mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Merge pull request #12900 from MathiasVP/ir-translate-constant-static-local-vars-2
This commit is contained in:
@@ -6,7 +6,7 @@ private import IRFunctionBaseInternal
|
||||
|
||||
private newtype TIRFunction =
|
||||
TFunctionIRFunction(Language::Function func) { IRConstruction::Raw::functionHasIR(func) } or
|
||||
TVarInitIRFunction(Language::GlobalVariable var) { IRConstruction::Raw::varHasIRFunc(var) }
|
||||
TVarInitIRFunction(Language::Variable var) { IRConstruction::Raw::varHasIRFunc(var) }
|
||||
|
||||
/**
|
||||
* The IR for a function. This base class contains only the predicates that are the same between all
|
||||
|
||||
@@ -37,7 +37,13 @@ module Raw {
|
||||
predicate functionHasIR(Function func) { exists(getTranslatedFunction(func)) }
|
||||
|
||||
cached
|
||||
predicate varHasIRFunc(GlobalOrNamespaceVariable var) {
|
||||
predicate varHasIRFunc(Variable var) {
|
||||
(
|
||||
var instanceof GlobalOrNamespaceVariable
|
||||
or
|
||||
not var.isFromUninstantiatedTemplate(_) and
|
||||
var instanceof StaticInitializedStaticLocalVariable
|
||||
) and
|
||||
var.hasInitializer() and
|
||||
(
|
||||
not var.getType().isDeeplyConst()
|
||||
@@ -75,9 +81,10 @@ module Raw {
|
||||
}
|
||||
|
||||
cached
|
||||
predicate hasDynamicInitializationFlag(Function func, StaticLocalVariable var, CppType type) {
|
||||
predicate hasDynamicInitializationFlag(
|
||||
Function func, RuntimeInitializedStaticLocalVariable var, CppType type
|
||||
) {
|
||||
var.getFunction() = func and
|
||||
var.hasDynamicInitialization() and
|
||||
type = getBoolType()
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ abstract class TranslatedSideEffects extends TranslatedElement {
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = getAst() }
|
||||
|
||||
final override Declaration getFunction() { result = getExpr().getEnclosingDeclaration() }
|
||||
final override Declaration getFunction() { result = getEnclosingDeclaration(getExpr()) }
|
||||
|
||||
final override TranslatedElement getChild(int i) {
|
||||
result =
|
||||
|
||||
@@ -28,7 +28,11 @@ abstract class TranslatedCondition extends TranslatedElement {
|
||||
|
||||
final Expr getExpr() { result = expr }
|
||||
|
||||
final override Function getFunction() { result = expr.getEnclosingFunction() }
|
||||
final override Declaration getFunction() {
|
||||
result = getEnclosingFunction(expr) or
|
||||
result = getEnclosingVariable(expr).(GlobalOrNamespaceVariable) or
|
||||
result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable)
|
||||
}
|
||||
|
||||
final Type getResultType() { result = expr.getUnspecifiedType() }
|
||||
}
|
||||
|
||||
@@ -28,9 +28,14 @@ abstract class TranslatedDeclarationEntry extends TranslatedElement, TTranslated
|
||||
|
||||
TranslatedDeclarationEntry() { this = TTranslatedDeclarationEntry(entry) }
|
||||
|
||||
final override Function getFunction() {
|
||||
exists(DeclStmt stmt |
|
||||
stmt = entry.getStmt() and
|
||||
final override Declaration getFunction() {
|
||||
exists(DeclStmt stmt | stmt = entry.getStmt() |
|
||||
result = entry.getDeclaration().(StaticInitializedStaticLocalVariable)
|
||||
or
|
||||
result = entry.getDeclaration().(GlobalOrNamespaceVariable)
|
||||
or
|
||||
not entry.getDeclaration() instanceof StaticInitializedStaticLocalVariable and
|
||||
not entry.getDeclaration() instanceof GlobalOrNamespaceVariable and
|
||||
result = stmt.getEnclosingFunction()
|
||||
)
|
||||
}
|
||||
@@ -237,7 +242,7 @@ class TranslatedStaticLocalVariableInitialization extends TranslatedElement,
|
||||
|
||||
final override LocalVariable getVariable() { result = var }
|
||||
|
||||
final override Function getFunction() { result = var.getFunction() }
|
||||
final override Declaration getFunction() { result = var.getFunction() }
|
||||
}
|
||||
|
||||
TranslatedConditionDecl getTranslatedConditionDecl(ConditionDeclExpr expr) {
|
||||
@@ -264,7 +269,7 @@ class TranslatedConditionDecl extends TranslatedLocalVariableDeclaration, TTrans
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = getAst() }
|
||||
|
||||
override Function getFunction() { result = conditionDeclExpr.getEnclosingFunction() }
|
||||
override Declaration getFunction() { result = getEnclosingFunction(conditionDeclExpr) }
|
||||
|
||||
override LocalVariable getVariable() { result = conditionDeclExpr.getVariable() }
|
||||
}
|
||||
|
||||
@@ -62,15 +62,6 @@ private predicate ignoreExprAndDescendants(Expr expr) {
|
||||
// constant value.
|
||||
isIRConstant(getRealParent(expr))
|
||||
or
|
||||
// Only translate the initializer of a static local if it uses run-time data.
|
||||
// Otherwise the initializer does not run in function scope.
|
||||
exists(Initializer init, StaticStorageDurationVariable var |
|
||||
init = var.getInitializer() and
|
||||
not var.hasDynamicInitialization() and
|
||||
expr = init.getExpr().getFullyConverted() and
|
||||
not var instanceof GlobalOrNamespaceVariable
|
||||
)
|
||||
or
|
||||
// Ignore descendants of `__assume` expressions, since we translated these to `NoOp`.
|
||||
getRealParent(expr) instanceof AssumeExpr
|
||||
or
|
||||
@@ -118,8 +109,8 @@ private predicate ignoreExprOnly(Expr expr) {
|
||||
// should not be translated.
|
||||
exists(NewOrNewArrayExpr new | expr = new.getAllocatorCall().getArgument(0))
|
||||
or
|
||||
not translateFunction(expr.getEnclosingFunction()) and
|
||||
not Raw::varHasIRFunc(expr.getEnclosingVariable())
|
||||
not translateFunction(getEnclosingFunction(expr)) and
|
||||
not Raw::varHasIRFunc(getEnclosingVariable(expr))
|
||||
or
|
||||
// We do not yet translate destructors properly, so for now we ignore the
|
||||
// destructor call. We do, however, translate the expression being
|
||||
@@ -438,6 +429,17 @@ predicate hasTranslatedSyntheticTemporaryObject(Expr expr) {
|
||||
not expr.hasLValueToRValueConversion()
|
||||
}
|
||||
|
||||
class StaticInitializedStaticLocalVariable extends StaticLocalVariable {
|
||||
StaticInitializedStaticLocalVariable() {
|
||||
this.hasInitializer() and
|
||||
not this.hasDynamicInitialization()
|
||||
}
|
||||
}
|
||||
|
||||
class RuntimeInitializedStaticLocalVariable extends StaticLocalVariable {
|
||||
RuntimeInitializedStaticLocalVariable() { this.hasDynamicInitialization() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the specified `DeclarationEntry` needs an IR translation. An IR translation is only
|
||||
* necessary for automatic local variables, or for static local variables with dynamic
|
||||
@@ -453,7 +455,7 @@ private predicate translateDeclarationEntry(IRDeclarationEntry entry) {
|
||||
not var.isStatic()
|
||||
or
|
||||
// Ignore static variables unless they have a dynamic initializer.
|
||||
var.(StaticLocalVariable).hasDynamicInitialization()
|
||||
var instanceof RuntimeInitializedStaticLocalVariable
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -755,7 +757,7 @@ newtype TTranslatedElement =
|
||||
} or
|
||||
// The side effect that initializes newly-allocated memory.
|
||||
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) } or
|
||||
TTranslatedGlobalOrNamespaceVarInit(GlobalOrNamespaceVariable var) { Raw::varHasIRFunc(var) }
|
||||
TTranslatedStaticStorageDurationVarInit(Variable var) { Raw::varHasIRFunc(var) }
|
||||
|
||||
/**
|
||||
* Gets the index of the first explicitly initialized element in `initList`
|
||||
@@ -1043,6 +1045,6 @@ abstract class TranslatedRootElement extends TranslatedElement {
|
||||
TranslatedRootElement() {
|
||||
this instanceof TTranslatedFunction
|
||||
or
|
||||
this instanceof TTranslatedGlobalOrNamespaceVarInit
|
||||
this instanceof TTranslatedStaticStorageDurationVarInit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ abstract class TranslatedExpr extends TranslatedElement {
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final override Declaration getFunction() { result = expr.getEnclosingDeclaration() }
|
||||
final override Declaration getFunction() { result = getEnclosingDeclaration(expr) }
|
||||
|
||||
/**
|
||||
* Gets the expression from which this `TranslatedExpr` is generated.
|
||||
@@ -90,12 +90,57 @@ abstract class TranslatedExpr extends TranslatedElement {
|
||||
* Gets the `TranslatedFunction` containing this expression.
|
||||
*/
|
||||
final TranslatedRootElement getEnclosingFunction() {
|
||||
result = getTranslatedFunction(expr.getEnclosingFunction())
|
||||
result = getTranslatedFunction(getEnclosingFunction(expr))
|
||||
or
|
||||
result = getTranslatedVarInit(expr.getEnclosingVariable())
|
||||
result = getTranslatedVarInit(getEnclosingVariable(expr))
|
||||
}
|
||||
}
|
||||
|
||||
Function getEnclosingFunction(Expr e) {
|
||||
not exists(getEnclosingVariable(e)) and
|
||||
result = e.getEnclosingFunction()
|
||||
}
|
||||
|
||||
Declaration getEnclosingDeclaration0(Expr e) {
|
||||
result = getEnclosingDeclaration0(e.getParentWithConversions())
|
||||
or
|
||||
exists(Initializer i, Variable v |
|
||||
i.getExpr().getFullyConverted() = e and
|
||||
v = i.getDeclaration()
|
||||
|
|
||||
if v instanceof StaticInitializedStaticLocalVariable or v instanceof GlobalOrNamespaceVariable
|
||||
then result = v
|
||||
else result = e.getEnclosingDeclaration()
|
||||
)
|
||||
}
|
||||
|
||||
Declaration getEnclosingDeclaration(Expr e) {
|
||||
result = getEnclosingDeclaration0(e)
|
||||
or
|
||||
not exists(getEnclosingDeclaration0(e)) and
|
||||
result = e.getEnclosingDeclaration()
|
||||
}
|
||||
|
||||
Variable getEnclosingVariable0(Expr e) {
|
||||
result = getEnclosingVariable0(e.getParentWithConversions())
|
||||
or
|
||||
exists(Initializer i, Variable v |
|
||||
i.getExpr().getFullyConverted() = e and
|
||||
v = i.getDeclaration()
|
||||
|
|
||||
if v instanceof StaticInitializedStaticLocalVariable or v instanceof GlobalOrNamespaceVariable
|
||||
then result = v
|
||||
else result = e.getEnclosingVariable()
|
||||
)
|
||||
}
|
||||
|
||||
Variable getEnclosingVariable(Expr e) {
|
||||
result = getEnclosingVariable0(e)
|
||||
or
|
||||
not exists(getEnclosingVariable0(e)) and
|
||||
result = e.getEnclosingVariable()
|
||||
}
|
||||
|
||||
/**
|
||||
* The IR translation of the "core" part of an expression. This is the part of
|
||||
* the expression that produces the result value of the expression, before any
|
||||
@@ -843,10 +888,21 @@ class TranslatedNonFieldVariableAccess extends TranslatedVariableAccess {
|
||||
|
||||
override IRVariable getInstructionVariable(InstructionTag tag) {
|
||||
tag = OnlyInstructionTag() and
|
||||
result = getIRUserVariable(expr.getEnclosingDeclaration(), expr.getTarget())
|
||||
exists(Declaration d, Variable v |
|
||||
accessHasEnclosingDeclarationAndVariable(d, v, expr) and
|
||||
result = getIRUserVariable(d, v)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate accessHasEnclosingDeclarationAndVariable(
|
||||
Declaration d, Variable v, VariableAccess va
|
||||
) {
|
||||
d = getEnclosingDeclaration(va) and
|
||||
v = va.getTarget()
|
||||
}
|
||||
|
||||
class TranslatedFieldAccess extends TranslatedVariableAccess {
|
||||
override FieldAccess expr;
|
||||
|
||||
@@ -2000,7 +2056,7 @@ class TranslatedDestructorFieldDestruction extends TranslatedNonConstantExpr, St
|
||||
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
tag = OnlyInstructionTag() and
|
||||
operandTag instanceof UnaryOperandTag and
|
||||
result = getTranslatedFunction(expr.getEnclosingFunction()).getInitializeThisInstruction()
|
||||
result = getTranslatedFunction(getEnclosingFunction(expr)).getInitializeThisInstruction()
|
||||
}
|
||||
|
||||
final override Field getInstructionField(InstructionTag tag) {
|
||||
|
||||
@@ -322,11 +322,13 @@ class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
|
||||
(
|
||||
var instanceof GlobalOrNamespaceVariable
|
||||
or
|
||||
var instanceof StaticLocalVariable
|
||||
or
|
||||
var instanceof MemberVariable and not var instanceof Field
|
||||
) and
|
||||
exists(VariableAccess access |
|
||||
access.getTarget() = var and
|
||||
access.getEnclosingFunction() = func
|
||||
getEnclosingFunction(access) = func
|
||||
)
|
||||
or
|
||||
var.(LocalScopeVariable).getFunction() = func
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import semmle.code.cpp.ir.implementation.raw.internal.TranslatedElement
|
||||
private import TranslatedExpr
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.implementation.IRType
|
||||
private import semmle.code.cpp.ir.implementation.Opcode
|
||||
@@ -8,16 +9,16 @@ private import TranslatedInitialization
|
||||
private import InstructionTag
|
||||
private import semmle.code.cpp.ir.internal.IRUtilities
|
||||
|
||||
class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
|
||||
TTranslatedGlobalOrNamespaceVarInit, InitializationContext
|
||||
class TranslatedStaticStorageDurationVarInit extends TranslatedRootElement,
|
||||
TTranslatedStaticStorageDurationVarInit, InitializationContext
|
||||
{
|
||||
GlobalOrNamespaceVariable var;
|
||||
Variable var;
|
||||
|
||||
TranslatedGlobalOrNamespaceVarInit() { this = TTranslatedGlobalOrNamespaceVarInit(var) }
|
||||
TranslatedStaticStorageDurationVarInit() { this = TTranslatedStaticStorageDurationVarInit(var) }
|
||||
|
||||
override string toString() { result = var.toString() }
|
||||
|
||||
final override GlobalOrNamespaceVariable getAst() { result = var }
|
||||
final override Variable getAst() { result = var }
|
||||
|
||||
final override Declaration getFunction() { result = var }
|
||||
|
||||
@@ -111,11 +112,13 @@ class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
|
||||
(
|
||||
varUsed instanceof GlobalOrNamespaceVariable
|
||||
or
|
||||
varUsed instanceof StaticLocalVariable
|
||||
or
|
||||
varUsed instanceof MemberVariable and not varUsed instanceof Field
|
||||
) and
|
||||
exists(VariableAccess access |
|
||||
access.getTarget() = varUsed and
|
||||
access.getEnclosingVariable() = var
|
||||
getEnclosingVariable(access) = var
|
||||
)
|
||||
or
|
||||
var = varUsed
|
||||
@@ -128,6 +131,4 @@ class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
|
||||
}
|
||||
}
|
||||
|
||||
TranslatedGlobalOrNamespaceVarInit getTranslatedVarInit(GlobalOrNamespaceVariable var) {
|
||||
result.getAst() = var
|
||||
}
|
||||
TranslatedStaticStorageDurationVarInit getTranslatedVarInit(Variable var) { result.getAst() = var }
|
||||
|
||||
@@ -138,8 +138,9 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
|
||||
final override string toString() { result = "init: " + expr.toString() }
|
||||
|
||||
final override Declaration getFunction() {
|
||||
result = expr.getEnclosingFunction() or
|
||||
result = expr.getEnclosingVariable().(GlobalOrNamespaceVariable)
|
||||
result = getEnclosingFunction(expr) or
|
||||
result = getEnclosingVariable(expr).(GlobalOrNamespaceVariable) or
|
||||
result = getEnclosingVariable(expr).(StaticInitializedStaticLocalVariable)
|
||||
}
|
||||
|
||||
final override Locatable getAst() { result = expr }
|
||||
@@ -159,7 +160,7 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
|
||||
final InitializationContext getContext() { result = getParent() }
|
||||
|
||||
final TranslatedFunction getEnclosingFunction() {
|
||||
result = getTranslatedFunction(expr.getEnclosingFunction())
|
||||
result = getTranslatedFunction(this.getFunction())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -493,8 +494,9 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
|
||||
deprecated override Locatable getAST() { result = getAst() }
|
||||
|
||||
final override Declaration getFunction() {
|
||||
result = ast.getEnclosingFunction() or
|
||||
result = ast.getEnclosingVariable().(GlobalOrNamespaceVariable)
|
||||
result = getEnclosingFunction(ast) or
|
||||
result = getEnclosingVariable(ast).(GlobalOrNamespaceVariable) or
|
||||
result = getEnclosingVariable(ast).(StaticInitializedStaticLocalVariable)
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction() { result = getInstruction(getFieldAddressTag()) }
|
||||
@@ -651,9 +653,11 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
|
||||
deprecated override Locatable getAST() { result = getAst() }
|
||||
|
||||
final override Declaration getFunction() {
|
||||
result = initList.getEnclosingFunction()
|
||||
result = getEnclosingFunction(initList)
|
||||
or
|
||||
result = initList.getEnclosingVariable().(GlobalOrNamespaceVariable)
|
||||
result = getEnclosingVariable(initList).(GlobalOrNamespaceVariable)
|
||||
or
|
||||
result = getEnclosingVariable(initList).(StaticInitializedStaticLocalVariable)
|
||||
}
|
||||
|
||||
final override Instruction getFirstInstruction() { result = getInstruction(getElementIndexTag()) }
|
||||
@@ -852,7 +856,7 @@ abstract class TranslatedStructorCallFromStructor extends TranslatedElement, Str
|
||||
result = getStructorCall()
|
||||
}
|
||||
|
||||
final override Function getFunction() { result = call.getEnclosingFunction() }
|
||||
final override Function getFunction() { result = getEnclosingFunction(call) }
|
||||
|
||||
final override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = getStructorCall() and
|
||||
@@ -989,7 +993,7 @@ class TranslatedConstructorBareInit extends TranslatedElement, TTranslatedConstr
|
||||
|
||||
override TranslatedElement getChild(int id) { none() }
|
||||
|
||||
override Function getFunction() { result = getParent().getFunction() }
|
||||
override Declaration getFunction() { result = this.getParent().getFunction() }
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() }
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class Variable = Cpp::Variable;
|
||||
|
||||
class AutomaticVariable = Cpp::StackVariable;
|
||||
|
||||
class StaticVariable = Cpp::Variable;
|
||||
class StaticVariable = Cpp::StaticStorageDurationVariable;
|
||||
|
||||
class GlobalVariable = Cpp::GlobalOrNamespaceVariable;
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
private import cpp
|
||||
private import semmle.code.cpp.Print as Print
|
||||
|
||||
predicate getIdentityString = Print::getIdentityString/1;
|
||||
string getIdentityString(Declaration decl) {
|
||||
if decl instanceof StaticLocalVariable
|
||||
then
|
||||
exists(StaticLocalVariable v | v = decl | result = v.getType().toString() + " " + v.getName())
|
||||
else result = Print::getIdentityString(decl)
|
||||
}
|
||||
|
||||
@@ -14377,6 +14377,37 @@ ir.cpp:
|
||||
# 1885| Type = [ClassTemplateInstantiation,Struct] Bar2<int>
|
||||
# 1885| ValueCategory = lvalue
|
||||
# 1886| getStmt(2): [ReturnStmt] return ...
|
||||
# 1891| [TopLevelFunction] int test_global_template_int()
|
||||
# 1891| <params>:
|
||||
# 1891| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 1892| getStmt(0): [DeclStmt] declaration
|
||||
# 1892| getDeclarationEntry(0): [VariableDeclarationEntry] definition of local_int
|
||||
# 1892| Type = [IntType] int
|
||||
# 1892| getVariable().getInitializer(): [Initializer] initializer for local_int
|
||||
# 1892| getExpr(): [VariableAccess] global_template
|
||||
# 1892| Type = [IntType] int
|
||||
# 1892| ValueCategory = prvalue(load)
|
||||
# 1893| getStmt(1): [DeclStmt] declaration
|
||||
# 1893| getDeclarationEntry(0): [VariableDeclarationEntry] definition of local_char
|
||||
# 1893| Type = [PlainCharType] char
|
||||
# 1893| getVariable().getInitializer(): [Initializer] initializer for local_char
|
||||
# 1893| getExpr(): [VariableAccess] global_template
|
||||
# 1893| Type = [PlainCharType] char
|
||||
# 1893| ValueCategory = prvalue(load)
|
||||
# 1894| getStmt(2): [ReturnStmt] return ...
|
||||
# 1894| getExpr(): [AddExpr] ... + ...
|
||||
# 1894| Type = [IntType] int
|
||||
# 1894| ValueCategory = prvalue
|
||||
# 1894| getLeftOperand(): [VariableAccess] local_int
|
||||
# 1894| Type = [IntType] int
|
||||
# 1894| ValueCategory = prvalue(load)
|
||||
# 1894| getRightOperand(): [VariableAccess] local_char
|
||||
# 1894| Type = [PlainCharType] char
|
||||
# 1894| ValueCategory = prvalue(load)
|
||||
# 1894| getRightOperand().getFullyConverted(): [CStyleCast] (int)...
|
||||
# 1894| Conversion = [IntegralConversion] integral conversion
|
||||
# 1894| Type = [IntType] int
|
||||
# 1894| ValueCategory = prvalue
|
||||
perf-regression.cpp:
|
||||
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
|
||||
# 4| <params>:
|
||||
|
||||
@@ -18,5 +18,7 @@ predicate shouldDumpFunction(Declaration decl) {
|
||||
decl instanceof Function
|
||||
or
|
||||
decl.(GlobalOrNamespaceVariable).hasInitializer()
|
||||
or
|
||||
decl.(StaticLocalVariable).hasInitializer()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1886,4 +1886,12 @@ namespace missing_declaration_entries {
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> T global_template = 42;
|
||||
|
||||
int test_global_template_int() {
|
||||
int local_int = global_template<int>;
|
||||
char local_char = global_template<char>;
|
||||
return local_int + (int)local_char;
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++17 --clang
|
||||
|
||||
@@ -5754,6 +5754,16 @@
|
||||
| ir.cpp:1231:5:1231:19 | Load | m1237_15 |
|
||||
| ir.cpp:1231:5:1231:19 | SideEffect | ~m1237_2 |
|
||||
| ir.cpp:1231:25:1231:25 | Address | &:r1231_5 |
|
||||
| ir.cpp:1232:16:1232:16 | Address | &:r1232_3 |
|
||||
| ir.cpp:1232:16:1232:16 | SideEffect | ~m1232_6 |
|
||||
| ir.cpp:1232:20:1232:20 | ChiPartial | partial:m1232_5 |
|
||||
| ir.cpp:1232:20:1232:20 | ChiTotal | total:m1232_2 |
|
||||
| ir.cpp:1232:20:1232:20 | StoreValue | r1232_4 |
|
||||
| ir.cpp:1233:16:1233:16 | Address | &:r1233_3 |
|
||||
| ir.cpp:1233:16:1233:16 | SideEffect | ~m1233_6 |
|
||||
| ir.cpp:1233:20:1233:28 | ChiPartial | partial:m1233_5 |
|
||||
| ir.cpp:1233:20:1233:28 | ChiTotal | total:m1233_2 |
|
||||
| ir.cpp:1233:20:1233:28 | StoreValue | r1233_4 |
|
||||
| ir.cpp:1234:16:1234:16 | Address | &:r1234_1 |
|
||||
| ir.cpp:1234:16:1234:16 | Address | &:r1234_1 |
|
||||
| ir.cpp:1234:16:1234:16 | Address | &:r1234_4 |
|
||||
@@ -8741,6 +8751,38 @@
|
||||
| ir.cpp:1885:11:1885:50 | ChiPartial | partial:m1885_4 |
|
||||
| ir.cpp:1885:11:1885:50 | ChiTotal | total:m1883_4 |
|
||||
| ir.cpp:1885:11:1885:50 | SideEffect | ~m1883_4 |
|
||||
| ir.cpp:1889:24:1889:24 | Address | &:r1889_3 |
|
||||
| ir.cpp:1889:24:1889:24 | Address | &:r1889_3 |
|
||||
| ir.cpp:1889:24:1889:24 | SideEffect | ~m1889_6 |
|
||||
| ir.cpp:1889:24:1889:24 | SideEffect | ~m1889_6 |
|
||||
| ir.cpp:1889:42:1889:43 | ChiPartial | partial:m1889_5 |
|
||||
| ir.cpp:1889:42:1889:43 | ChiPartial | partial:m1889_5 |
|
||||
| ir.cpp:1889:42:1889:43 | ChiTotal | total:m1889_2 |
|
||||
| ir.cpp:1889:42:1889:43 | ChiTotal | total:m1889_2 |
|
||||
| ir.cpp:1889:42:1889:43 | StoreValue | r1889_4 |
|
||||
| ir.cpp:1889:42:1889:43 | StoreValue | r1889_4 |
|
||||
| ir.cpp:1891:5:1891:28 | Address | &:r1891_5 |
|
||||
| ir.cpp:1891:5:1891:28 | ChiPartial | partial:m1891_3 |
|
||||
| ir.cpp:1891:5:1891:28 | ChiTotal | total:m1891_2 |
|
||||
| ir.cpp:1891:5:1891:28 | Load | m1894_8 |
|
||||
| ir.cpp:1891:5:1891:28 | SideEffect | m1891_3 |
|
||||
| ir.cpp:1892:9:1892:17 | Address | &:r1892_1 |
|
||||
| ir.cpp:1892:21:1892:40 | Address | &:r1892_2 |
|
||||
| ir.cpp:1892:21:1892:40 | Load | ~m1891_3 |
|
||||
| ir.cpp:1892:21:1892:40 | StoreValue | r1892_3 |
|
||||
| ir.cpp:1893:10:1893:19 | Address | &:r1893_1 |
|
||||
| ir.cpp:1893:23:1893:43 | Address | &:r1893_2 |
|
||||
| ir.cpp:1893:23:1893:43 | Load | ~m1891_3 |
|
||||
| ir.cpp:1893:23:1893:43 | StoreValue | r1893_3 |
|
||||
| ir.cpp:1894:5:1894:39 | Address | &:r1894_1 |
|
||||
| ir.cpp:1894:12:1894:20 | Address | &:r1894_2 |
|
||||
| ir.cpp:1894:12:1894:20 | Left | r1894_3 |
|
||||
| ir.cpp:1894:12:1894:20 | Load | m1892_4 |
|
||||
| ir.cpp:1894:12:1894:38 | StoreValue | r1894_7 |
|
||||
| ir.cpp:1894:24:1894:38 | Right | r1894_6 |
|
||||
| ir.cpp:1894:29:1894:38 | Address | &:r1894_4 |
|
||||
| ir.cpp:1894:29:1894:38 | Load | m1893_4 |
|
||||
| ir.cpp:1894:29:1894:38 | Unary | r1894_5 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_7 |
|
||||
@@ -9030,6 +9072,34 @@
|
||||
| struct_init.cpp:20:6:20:25 | ChiPartial | partial:m20_3 |
|
||||
| struct_init.cpp:20:6:20:25 | ChiTotal | total:m20_2 |
|
||||
| struct_init.cpp:20:6:20:25 | SideEffect | ~m25_9 |
|
||||
| struct_init.cpp:21:17:21:28 | Left | r21_3 |
|
||||
| struct_init.cpp:21:17:21:28 | Left | r21_3 |
|
||||
| struct_init.cpp:21:17:21:28 | SideEffect | ~m23_10 |
|
||||
| struct_init.cpp:21:34:24:5 | Right | r21_4 |
|
||||
| struct_init.cpp:21:34:24:5 | Right | r21_6 |
|
||||
| struct_init.cpp:21:34:24:5 | Unary | r21_5 |
|
||||
| struct_init.cpp:21:34:24:5 | Unary | r21_5 |
|
||||
| struct_init.cpp:21:34:24:5 | Unary | r21_7 |
|
||||
| struct_init.cpp:21:34:24:5 | Unary | r21_7 |
|
||||
| struct_init.cpp:22:9:22:25 | Address | &:r22_1 |
|
||||
| struct_init.cpp:22:9:22:25 | Address | &:r22_6 |
|
||||
| struct_init.cpp:22:11:22:13 | ChiPartial | partial:m22_4 |
|
||||
| struct_init.cpp:22:11:22:13 | ChiTotal | total:m21_2 |
|
||||
| struct_init.cpp:22:11:22:13 | StoreValue | r22_3 |
|
||||
| struct_init.cpp:22:11:22:13 | Unary | r22_2 |
|
||||
| struct_init.cpp:22:16:22:23 | ChiPartial | partial:m22_8 |
|
||||
| struct_init.cpp:22:16:22:23 | ChiTotal | total:m22_5 |
|
||||
| struct_init.cpp:22:16:22:23 | StoreValue | r22_7 |
|
||||
| struct_init.cpp:23:9:23:26 | Address | &:r23_1 |
|
||||
| struct_init.cpp:23:9:23:26 | Address | &:r23_6 |
|
||||
| struct_init.cpp:23:11:23:13 | ChiPartial | partial:m23_4 |
|
||||
| struct_init.cpp:23:11:23:13 | ChiTotal | total:m22_9 |
|
||||
| struct_init.cpp:23:11:23:13 | StoreValue | r23_3 |
|
||||
| struct_init.cpp:23:11:23:13 | Unary | r23_2 |
|
||||
| struct_init.cpp:23:16:23:24 | ChiPartial | partial:m23_9 |
|
||||
| struct_init.cpp:23:16:23:24 | ChiTotal | total:m23_5 |
|
||||
| struct_init.cpp:23:16:23:24 | StoreValue | r23_8 |
|
||||
| struct_init.cpp:23:17:23:24 | Unary | r23_7 |
|
||||
| struct_init.cpp:25:5:25:19 | CallTarget | func:r25_1 |
|
||||
| struct_init.cpp:25:5:25:19 | ChiPartial | partial:m25_5 |
|
||||
| struct_init.cpp:25:5:25:19 | ChiTotal | total:m20_4 |
|
||||
|
||||
@@ -6841,6 +6841,28 @@ ir.cpp:
|
||||
# 1231| v1231_8(void) = AliasedUse : ~m?
|
||||
# 1231| v1231_9(void) = ExitFunction :
|
||||
|
||||
# 1232| int a
|
||||
# 1232| Block 0
|
||||
# 1232| v1232_1(void) = EnterFunction :
|
||||
# 1232| mu1232_2(unknown) = AliasedDefinition :
|
||||
# 1232| r1232_3(glval<int>) = VariableAddress[a] :
|
||||
# 1232| r1232_4(int) = Constant[0] :
|
||||
# 1232| mu1232_5(int) = Store[a] : &:r1232_3, r1232_4
|
||||
# 1232| v1232_6(void) = ReturnVoid :
|
||||
# 1232| v1232_7(void) = AliasedUse : ~m?
|
||||
# 1232| v1232_8(void) = ExitFunction :
|
||||
|
||||
# 1233| int b
|
||||
# 1233| Block 0
|
||||
# 1233| v1233_1(void) = EnterFunction :
|
||||
# 1233| mu1233_2(unknown) = AliasedDefinition :
|
||||
# 1233| r1233_3(glval<int>) = VariableAddress[b] :
|
||||
# 1233| r1233_4(int) = Constant[4] :
|
||||
# 1233| mu1233_5(int) = Store[b] : &:r1233_3, r1233_4
|
||||
# 1233| v1233_6(void) = ReturnVoid :
|
||||
# 1233| v1233_7(void) = AliasedUse : ~m?
|
||||
# 1233| v1233_8(void) = ExitFunction :
|
||||
|
||||
# 1240| void staticLocalWithConstructor(char const*)
|
||||
# 1240| Block 0
|
||||
# 1240| v1240_1(void) = EnterFunction :
|
||||
@@ -10035,6 +10057,54 @@ ir.cpp:
|
||||
# 1883| v1883_5(void) = AliasedUse : ~m?
|
||||
# 1883| v1883_6(void) = ExitFunction :
|
||||
|
||||
# 1889| char global_template<char>
|
||||
# 1889| Block 0
|
||||
# 1889| v1889_1(void) = EnterFunction :
|
||||
# 1889| mu1889_2(unknown) = AliasedDefinition :
|
||||
# 1889| r1889_3(glval<char>) = VariableAddress[global_template] :
|
||||
# 1889| r1889_4(char) = Constant[42] :
|
||||
# 1889| mu1889_5(char) = Store[global_template] : &:r1889_3, r1889_4
|
||||
# 1889| v1889_6(void) = ReturnVoid :
|
||||
# 1889| v1889_7(void) = AliasedUse : ~m?
|
||||
# 1889| v1889_8(void) = ExitFunction :
|
||||
|
||||
# 1889| int global_template<int>
|
||||
# 1889| Block 0
|
||||
# 1889| v1889_1(void) = EnterFunction :
|
||||
# 1889| mu1889_2(unknown) = AliasedDefinition :
|
||||
# 1889| r1889_3(glval<int>) = VariableAddress[global_template] :
|
||||
# 1889| r1889_4(int) = Constant[42] :
|
||||
# 1889| mu1889_5(int) = Store[global_template] : &:r1889_3, r1889_4
|
||||
# 1889| v1889_6(void) = ReturnVoid :
|
||||
# 1889| v1889_7(void) = AliasedUse : ~m?
|
||||
# 1889| v1889_8(void) = ExitFunction :
|
||||
|
||||
# 1891| int test_global_template_int()
|
||||
# 1891| Block 0
|
||||
# 1891| v1891_1(void) = EnterFunction :
|
||||
# 1891| mu1891_2(unknown) = AliasedDefinition :
|
||||
# 1891| mu1891_3(unknown) = InitializeNonLocal :
|
||||
# 1892| r1892_1(glval<int>) = VariableAddress[local_int] :
|
||||
# 1892| r1892_2(glval<int>) = VariableAddress[global_template] :
|
||||
# 1892| r1892_3(int) = Load[global_template] : &:r1892_2, ~m?
|
||||
# 1892| mu1892_4(int) = Store[local_int] : &:r1892_1, r1892_3
|
||||
# 1893| r1893_1(glval<char>) = VariableAddress[local_char] :
|
||||
# 1893| r1893_2(glval<char>) = VariableAddress[global_template] :
|
||||
# 1893| r1893_3(char) = Load[global_template] : &:r1893_2, ~m?
|
||||
# 1893| mu1893_4(char) = Store[local_char] : &:r1893_1, r1893_3
|
||||
# 1894| r1894_1(glval<int>) = VariableAddress[#return] :
|
||||
# 1894| r1894_2(glval<int>) = VariableAddress[local_int] :
|
||||
# 1894| r1894_3(int) = Load[local_int] : &:r1894_2, ~m?
|
||||
# 1894| r1894_4(glval<char>) = VariableAddress[local_char] :
|
||||
# 1894| r1894_5(char) = Load[local_char] : &:r1894_4, ~m?
|
||||
# 1894| r1894_6(int) = Convert : r1894_5
|
||||
# 1894| r1894_7(int) = Add : r1894_3, r1894_6
|
||||
# 1894| mu1894_8(int) = Store[#return] : &:r1894_1, r1894_7
|
||||
# 1891| r1891_4(glval<int>) = VariableAddress[#return] :
|
||||
# 1891| v1891_5(void) = ReturnValue : &:r1891_4, ~m?
|
||||
# 1891| v1891_6(void) = AliasedUse : ~m?
|
||||
# 1891| v1891_7(void) = ExitFunction :
|
||||
|
||||
perf-regression.cpp:
|
||||
# 6| void Big::Big()
|
||||
# 6| Block 0
|
||||
@@ -10320,6 +10390,34 @@ struct_init.cpp:
|
||||
# 20| v20_5(void) = AliasedUse : ~m?
|
||||
# 20| v20_6(void) = ExitFunction :
|
||||
|
||||
# 21| Info[] static_infos
|
||||
# 21| Block 0
|
||||
# 21| v21_1(void) = EnterFunction :
|
||||
# 21| mu21_2(unknown) = AliasedDefinition :
|
||||
# 21| r21_3(glval<Info[]>) = VariableAddress[static_infos] :
|
||||
# 21| r21_4(int) = Constant[0] :
|
||||
# 21| r21_5(glval<Info>) = PointerAdd[16] : r21_3, r21_4
|
||||
# 22| r22_1(glval<char *>) = FieldAddress[name] : r21_5
|
||||
# 22| r22_2(glval<char[2]>) = StringConstant["1"] :
|
||||
# 22| r22_3(char *) = Convert : r22_2
|
||||
# 22| mu22_4(char *) = Store[?] : &:r22_1, r22_3
|
||||
# 22| r22_5(glval<..(*)(..)>) = FieldAddress[handler] : r21_5
|
||||
# 22| r22_6(..(*)(..)) = FunctionAddress[handler1] :
|
||||
# 22| mu22_7(..(*)(..)) = Store[?] : &:r22_5, r22_6
|
||||
# 21| r21_6(int) = Constant[1] :
|
||||
# 21| r21_7(glval<Info>) = PointerAdd[16] : r21_3, r21_6
|
||||
# 23| r23_1(glval<char *>) = FieldAddress[name] : r21_7
|
||||
# 23| r23_2(glval<char[2]>) = StringConstant["2"] :
|
||||
# 23| r23_3(char *) = Convert : r23_2
|
||||
# 23| mu23_4(char *) = Store[?] : &:r23_1, r23_3
|
||||
# 23| r23_5(glval<..(*)(..)>) = FieldAddress[handler] : r21_7
|
||||
# 23| r23_6(glval<..()(..)>) = FunctionAddress[handler2] :
|
||||
# 23| r23_7(..(*)(..)) = CopyValue : r23_6
|
||||
# 23| mu23_8(..(*)(..)) = Store[?] : &:r23_5, r23_7
|
||||
# 21| v21_8(void) = ReturnVoid :
|
||||
# 21| v21_9(void) = AliasedUse : ~m?
|
||||
# 21| v21_10(void) = ExitFunction :
|
||||
|
||||
# 28| void declare_local_infos()
|
||||
# 28| Block 0
|
||||
# 28| v28_1(void) = EnterFunction :
|
||||
|
||||
@@ -233,3 +233,14 @@ void f_if_ternary_1(int b, int x, int y) {
|
||||
if (b ? x : y) {
|
||||
}
|
||||
}
|
||||
|
||||
struct _A
|
||||
{
|
||||
unsigned int x;
|
||||
const char *y;
|
||||
} as[];
|
||||
|
||||
void regression_test(void)
|
||||
{
|
||||
static const void *a[] = {0 ? 0 : as};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user