Merge pull request #12900 from MathiasVP/ir-translate-constant-static-local-vars-2

This commit is contained in:
Mathias Vorreiter Pedersen
2023-04-28 08:46:25 +01:00
committed by GitHub
19 changed files with 359 additions and 52 deletions

View File

@@ -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

View File

@@ -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()
}

View File

@@ -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 =

View File

@@ -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() }
}

View File

@@ -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() }
}

View File

@@ -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
}
}

View File

@@ -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) {

View File

@@ -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

View File

@@ -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 }

View File

@@ -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() }

View File

@@ -47,7 +47,7 @@ class Variable = Cpp::Variable;
class AutomaticVariable = Cpp::StackVariable;
class StaticVariable = Cpp::Variable;
class StaticVariable = Cpp::StaticStorageDurationVariable;
class GlobalVariable = Cpp::GlobalOrNamespaceVariable;

View File

@@ -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)
}

View File

@@ -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>:

View File

@@ -18,5 +18,7 @@ predicate shouldDumpFunction(Declaration decl) {
decl instanceof Function
or
decl.(GlobalOrNamespaceVariable).hasInitializer()
or
decl.(StaticLocalVariable).hasInitializer()
)
}

View File

@@ -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

View File

@@ -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 |

View File

@@ -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 :

View File

@@ -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};
}