diff --git a/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll b/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll index 566e4675a9f..413cca13b3b 100644 --- a/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll +++ b/cpp/ql/lib/semmle/code/cpp/exprs/Literal.qll @@ -187,13 +187,44 @@ class ClassAggregateLiteral extends AggregateLiteral { override string getAPrimaryQlClass() { result = "ClassAggregateLiteral" } /** + * Gets an expression within the aggregate literal that is used to initialize + * field `field`, if present. + * + * This predicate may have multiple results since a field can be initialized + * multiple times in the same initializer. + */ + Expr getAFieldExpr(Field field) { result = this.getFieldExpr(field, _) } + + /** + * DEPRECATED: Use `getAFieldExpr` instead. + * * Gets the expression within the aggregate literal that is used to initialize * field `field`, if present. + * + * This predicate may have multiple results since a field can be initialized + * multiple times in the same initializer. */ - Expr getFieldExpr(Field field) { + Expr getFieldExpr(Field field) { result = this.getFieldExpr(field, _) } + + /** + * Gets the expression within the aggregate literal that is used to initialize + * field `field`, if present. The expression is the `position`'th entry in the + * aggregate literal. + * + * For example, if `aggr` represents the initialization literal `{.x = 123, .y = 456 .x = 789}` in + * ```cpp + * struct Foo { int x; int y; }; + * struct Foo foo = {.x = 123, .y = 456 .x = 789}; + * ``` + * then: + * - `aggr.getFieldExpr(x, 0)` gives `123`. + * - `aggr.getFieldExpr(y, 1)` gives `456`. + * - `aggr.getFieldExpr(x, 2)` gives `789`. + */ + Expr getFieldExpr(Field field, int position) { field = classType.getAField() and aggregate_field_init(underlyingElement(this), unresolveElement(result), unresolveElement(field), - _) + position) } /** @@ -261,11 +292,41 @@ class ArrayOrVectorAggregateLiteral extends AggregateLiteral { Type getElementType() { none() } /** + * Gets an expression within the aggregate literal that is used to initialize + * element `elementIndex`, if present. + * + * This predicate may have multiple results since an element can be initialized + * multiple times in the same initializer. + */ + Expr getAnElementExpr(int elementIndex) { result = this.getElementExpr(elementIndex, _) } + + /** + * DEPRECATED: Use `getAnElementExpr` instead. + * * Gets the expression within the aggregate literal that is used to initialize * element `elementIndex`, if present. + * + * This predicate may have multiple results since an element can be initialized + * multiple times in the same initializer. */ - Expr getElementExpr(int elementIndex) { - aggregate_array_init(underlyingElement(this), unresolveElement(result), elementIndex, _) + Expr getElementExpr(int elementIndex) { result = this.getElementExpr(elementIndex, _) } + + /** + * Gets the expression within the aggregate literal that is used to initialize + * element `elementIndex`, if present. The expression is the `position`'th entry + * in the aggregate literal. + * + * For example, if `a` represents the initialization literal `{[0] = 123, [1] = 456, [0] = 789 }` in + * ```cpp + * int x[2] = {[0] = 123, [1] = 456, [0] = 789 }; + * ``` + * then: + * - `a.getElementExpr(0, 0)` gives `123`. + * - `a.getElementExpr(1, 1)` gives `456`. + * - `a.getElementExpr(0, 2)` gives `789`. + */ + Expr getElementExpr(int elementIndex, int position) { + aggregate_array_init(underlyingElement(this), unresolveElement(result), elementIndex, position) } /** diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 81c04c736b4..c320c7aa49e 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -619,18 +619,19 @@ newtype TTranslatedElement = ) } or // The initialization of a field via a member of an initializer list. - TTranslatedExplicitFieldInitialization(Expr ast, Field field, Expr expr) { + TTranslatedExplicitFieldInitialization(Expr ast, Field field, Expr expr, int position) { exists(ClassAggregateLiteral initList | not ignoreExpr(initList) and ast = initList and - expr = initList.getFieldExpr(field).getFullyConverted() + expr = initList.getFieldExpr(field, position).getFullyConverted() ) or exists(ConstructorFieldInit init | not ignoreExpr(init) and ast = init and field = init.getTarget() and - expr = init.getExpr().getFullyConverted() + expr = init.getExpr().getFullyConverted() and + position = -1 ) } or // The value initialization of a field due to an omitted member of an @@ -643,9 +644,11 @@ newtype TTranslatedElement = ) } or // The initialization of an array element via a member of an initializer list. - TTranslatedExplicitElementInitialization(ArrayOrVectorAggregateLiteral initList, int elementIndex) { + TTranslatedExplicitElementInitialization( + ArrayOrVectorAggregateLiteral initList, int elementIndex, int position + ) { not ignoreExpr(initList) and - exists(initList.getElementExpr(elementIndex)) + exists(initList.getElementExpr(elementIndex, position)) } or // The value initialization of a range of array elements that were omitted // from an initializer list. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll index 4cd235a52bf..5e50c834d67 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedInitialization.qll @@ -201,11 +201,13 @@ class TranslatedClassListInitialization extends TranslatedListInitialization { override ClassAggregateLiteral expr; override TranslatedElement getChild(int id) { - exists(TranslatedFieldInitialization fieldInit | - result = fieldInit and - fieldInit = getTranslatedFieldInitialization(expr, _) and - fieldInit.getOrder() = id - ) + result = + rank[id + 1](TranslatedFieldInitialization fieldInit, int ord | + fieldInit = getTranslatedFieldInitialization(expr, _) and + fieldInit.getOrder() = ord + | + fieldInit order by ord, fieldInit.getPosition() + ) } } @@ -222,7 +224,7 @@ class TranslatedArrayListInitialization extends TranslatedListInitialization { rank[id + 1](TranslatedElementInitialization init | init.getInitList() = expr | - init order by init.getElementIndex() + init order by init.getElementIndex(), init.getPosition() ) } } @@ -522,6 +524,9 @@ abstract class TranslatedFieldInitialization extends TranslatedElement { final InstructionTag getFieldAddressTag() { result = InitializerFieldAddressTag() } final Field getField() { result = field } + + /** Gets the position in the initializer list, or `-1` if the initialization is implicit. */ + int getPosition() { result = -1 } } /** @@ -532,9 +537,10 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio InitializationContext, TTranslatedExplicitFieldInitialization { Expr expr; + int position; TranslatedExplicitFieldInitialization() { - this = TTranslatedExplicitFieldInitialization(ast, field, expr) + this = TTranslatedExplicitFieldInitialization(ast, field, expr, position) } override Instruction getTargetAddress() { result = getInstruction(getFieldAddressTag()) } @@ -556,6 +562,8 @@ class TranslatedExplicitFieldInitialization extends TranslatedFieldInitializatio private TranslatedInitialization getInitialization() { result = getTranslatedInitialization(expr) } + + override int getPosition() { result = position } } private string getZeroValue(Type type) { @@ -689,6 +697,8 @@ abstract class TranslatedElementInitialization extends TranslatedElement { abstract int getElementIndex(); + int getPosition() { result = -1 } + final InstructionTag getElementAddressTag() { result = InitializerElementAddressTag() } final InstructionTag getElementIndexTag() { result = InitializerElementIndexTag() } @@ -706,9 +716,10 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ TTranslatedExplicitElementInitialization, InitializationContext { int elementIndex; + int position; TranslatedExplicitElementInitialization() { - this = TTranslatedExplicitElementInitialization(initList, elementIndex) + this = TTranslatedExplicitElementInitialization(initList, elementIndex, position) } override Instruction getTargetAddress() { result = getInstruction(getElementAddressTag()) } @@ -731,8 +742,13 @@ class TranslatedExplicitElementInitialization extends TranslatedElementInitializ override int getElementIndex() { result = elementIndex } + override int getPosition() { result = position } + TranslatedInitialization getInitialization() { - result = getTranslatedInitialization(initList.getElementExpr(elementIndex).getFullyConverted()) + result = + getTranslatedInitialization(initList + .getElementExpr(elementIndex, position) + .getFullyConverted()) } } diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected index 7f76af075a7..8a77a94f011 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir.expected @@ -1,3 +1,165 @@ +ssa.c: +# 2| void named_designators() +# 2| Block 0 +# 2| v2_1(void) = EnterFunction : +# 2| m2_2(unknown) = AliasedDefinition : +# 2| m2_3(unknown) = InitializeNonLocal : +# 2| m2_4(unknown) = Chi : total:m2_2, partial:m2_3 +# 3| r3_1(glval) = VariableAddress[foo] : +# 3| m3_2(Foo) = Uninitialized[foo] : &:r3_1 +# 3| r3_3(glval) = FieldAddress[x] : r3_1 +# 3| r3_4(int) = Constant[0] : +# 3| r3_5(glval) = PointerAdd[4] : r3_3, r3_4 +# 3| r3_6(int) = Constant[1234] : +# 3| m3_7(int) = Store[?] : &:r3_5, r3_6 +# 3| m3_8(Foo) = Chi : total:m3_2, partial:m3_7 +# 3| r3_9(int) = Constant[1] : +# 3| r3_10(glval) = PointerAdd[4] : r3_3, r3_9 +# 3| r3_11(int) = Constant[0] : +# 3| m3_12(int) = Store[?] : &:r3_10, r3_11 +# 3| m3_13(Foo) = Chi : total:m3_8, partial:m3_12 +# 3| r3_14(glval) = FieldAddress[x] : r3_1 +# 3| r3_15(int) = Constant[0] : +# 3| r3_16(glval) = PointerAdd[4] : r3_14, r3_15 +# 3| r3_17(int) = Constant[0] : +# 3| m3_18(int) = Store[?] : &:r3_16, r3_17 +# 3| m3_19(Foo) = Chi : total:m3_13, partial:m3_18 +# 3| r3_20(int) = Constant[1] : +# 3| r3_21(glval) = PointerAdd[4] : r3_14, r3_20 +# 3| r3_22(int) = Constant[5678] : +# 3| m3_23(int) = Store[?] : &:r3_21, r3_22 +# 3| m3_24(Foo) = Chi : total:m3_19, partial:m3_23 +# 4| v4_1(void) = NoOp : +# 2| v2_5(void) = ReturnVoid : +# 2| v2_6(void) = AliasedUse : m2_3 +# 2| v2_7(void) = ExitFunction : + +# 6| void repeated_designators() +# 6| Block 0 +# 6| v6_1(void) = EnterFunction : +# 6| m6_2(unknown) = AliasedDefinition : +# 6| m6_3(unknown) = InitializeNonLocal : +# 6| m6_4(unknown) = Chi : total:m6_2, partial:m6_3 +# 7| r7_1(glval) = VariableAddress[x] : +# 7| m7_2(int[1]) = Uninitialized[x] : &:r7_1 +# 7| r7_3(int) = Constant[0] : +# 7| r7_4(glval) = PointerAdd[4] : r7_1, r7_3 +# 7| r7_5(int) = Constant[1234] : +# 7| m7_6(int) = Store[?] : &:r7_4, r7_5 +# 7| r7_7(int) = Constant[0] : +# 7| r7_8(glval) = PointerAdd[4] : r7_1, r7_7 +# 7| r7_9(int) = Constant[5678] : +# 7| m7_10(int) = Store[?] : &:r7_8, r7_9 +# 8| v8_1(void) = NoOp : +# 6| v6_5(void) = ReturnVoid : +# 6| v6_6(void) = AliasedUse : m6_3 +# 6| v6_7(void) = ExitFunction : + +# 11| void named_designators_2() +# 11| Block 0 +# 11| v11_1(void) = EnterFunction : +# 11| m11_2(unknown) = AliasedDefinition : +# 11| m11_3(unknown) = InitializeNonLocal : +# 11| m11_4(unknown) = Chi : total:m11_2, partial:m11_3 +# 12| r12_1(glval) = VariableAddress[foo] : +# 12| m12_2(Foo2) = Uninitialized[foo] : &:r12_1 +# 12| r12_3(glval) = FieldAddress[x] : r12_1 +# 12| r12_4(int) = Constant[1234] : +# 12| m12_5(int) = Store[?] : &:r12_3, r12_4 +# 12| m12_6(Foo2) = Chi : total:m12_2, partial:m12_5 +# 12| r12_7(glval) = FieldAddress[y] : r12_1 +# 12| r12_8(int) = Constant[5678] : +# 12| m12_9(int) = Store[?] : &:r12_7, r12_8 +# 12| m12_10(Foo2) = Chi : total:m12_6, partial:m12_9 +# 14| r14_1(glval) = VariableAddress[foo_swapped] : +# 14| m14_2(Foo2) = Uninitialized[foo_swapped] : &:r14_1 +# 14| r14_3(glval) = FieldAddress[x] : r14_1 +# 14| r14_4(int) = Constant[1234] : +# 14| m14_5(int) = Store[?] : &:r14_3, r14_4 +# 14| m14_6(Foo2) = Chi : total:m14_2, partial:m14_5 +# 14| r14_7(glval) = FieldAddress[y] : r14_1 +# 14| r14_8(int) = Constant[5678] : +# 14| m14_9(int) = Store[?] : &:r14_7, r14_8 +# 14| m14_10(Foo2) = Chi : total:m14_6, partial:m14_9 +# 15| v15_1(void) = NoOp : +# 11| v11_5(void) = ReturnVoid : +# 11| v11_6(void) = AliasedUse : m11_3 +# 11| v11_7(void) = ExitFunction : + +# 17| void non_repeated_designators() +# 17| Block 0 +# 17| v17_1(void) = EnterFunction : +# 17| m17_2(unknown) = AliasedDefinition : +# 17| m17_3(unknown) = InitializeNonLocal : +# 17| m17_4(unknown) = Chi : total:m17_2, partial:m17_3 +# 18| r18_1(glval) = VariableAddress[x] : +# 18| m18_2(int[2]) = Uninitialized[x] : &:r18_1 +# 18| r18_3(int) = Constant[0] : +# 18| r18_4(glval) = PointerAdd[4] : r18_1, r18_3 +# 18| r18_5(int) = Constant[1234] : +# 18| m18_6(int) = Store[?] : &:r18_4, r18_5 +# 18| m18_7(int[2]) = Chi : total:m18_2, partial:m18_6 +# 18| r18_8(int) = Constant[1] : +# 18| r18_9(glval) = PointerAdd[4] : r18_1, r18_8 +# 18| r18_10(int) = Constant[5678] : +# 18| m18_11(int) = Store[?] : &:r18_9, r18_10 +# 18| m18_12(int[2]) = Chi : total:m18_7, partial:m18_11 +# 20| r20_1(glval) = VariableAddress[y] : +# 20| m20_2(int[2]) = Uninitialized[y] : &:r20_1 +# 20| r20_3(int) = Constant[0] : +# 20| r20_4(glval) = PointerAdd[4] : r20_1, r20_3 +# 20| r20_5(int) = Constant[5678] : +# 20| m20_6(int) = Store[?] : &:r20_4, r20_5 +# 20| m20_7(int[2]) = Chi : total:m20_2, partial:m20_6 +# 20| r20_8(int) = Constant[1] : +# 20| r20_9(glval) = PointerAdd[4] : r20_1, r20_8 +# 20| r20_10(int) = Constant[1234] : +# 20| m20_11(int) = Store[?] : &:r20_9, r20_10 +# 20| m20_12(int[2]) = Chi : total:m20_7, partial:m20_11 +# 21| v21_1(void) = NoOp : +# 17| v17_5(void) = ReturnVoid : +# 17| v17_6(void) = AliasedUse : m17_3 +# 17| v17_7(void) = ExitFunction : + +# 28| void test_foo_array_and_int() +# 28| Block 0 +# 28| v28_1(void) = EnterFunction : +# 28| m28_2(unknown) = AliasedDefinition : +# 28| m28_3(unknown) = InitializeNonLocal : +# 28| m28_4(unknown) = Chi : total:m28_2, partial:m28_3 +# 29| r29_1(glval) = VariableAddress[f] : +# 29| m29_2(Foo_array_and_int) = Uninitialized[f] : &:r29_1 +# 29| r29_3(glval) = FieldAddress[x] : r29_1 +# 29| r29_4(int) = Constant[0] : +# 29| r29_5(glval) = PointerAdd[4] : r29_3, r29_4 +# 29| r29_6(int) = Constant[0] : +# 29| m29_7(int) = Store[?] : &:r29_5, r29_6 +# 29| m29_8(Foo_array_and_int) = Chi : total:m29_2, partial:m29_7 +# 29| r29_9(int) = Constant[1] : +# 29| r29_10(glval) = PointerAdd[4] : r29_3, r29_9 +# 29| r29_11(int) = Constant[1] : +# 29| m29_12(int) = Store[?] : &:r29_10, r29_11 +# 29| m29_13(Foo_array_and_int) = Chi : total:m29_8, partial:m29_12 +# 29| r29_14(glval) = FieldAddress[x] : r29_1 +# 29| r29_15(int) = Constant[0] : +# 29| r29_16(glval) = PointerAdd[4] : r29_14, r29_15 +# 29| r29_17(int) = Constant[42] : +# 29| m29_18(int) = Store[?] : &:r29_16, r29_17 +# 29| m29_19(Foo_array_and_int) = Chi : total:m29_13, partial:m29_18 +# 29| r29_20(int) = Constant[1] : +# 29| r29_21(glval) = PointerAdd[4] : r29_14, r29_20 +# 29| r29_22(int) = Constant[0] : +# 29| m29_23(int) = Store[?] : &:r29_21, r29_22 +# 29| m29_24(Foo_array_and_int) = Chi : total:m29_19, partial:m29_23 +# 29| r29_25(glval) = FieldAddress[y] : r29_1 +# 29| r29_26(int) = Constant[42] : +# 29| m29_27(int) = Store[?] : &:r29_25, r29_26 +# 29| m29_28(Foo_array_and_int) = Chi : total:m29_24, partial:m29_27 +# 30| v30_1(void) = NoOp : +# 28| v28_5(void) = ReturnVoid : +# 28| v28_6(void) = AliasedUse : m28_3 +# 28| v28_7(void) = ExitFunction : + ssa.cpp: # 13| int ChiPhiNode(Point*, bool, bool) # 13| Block 0 @@ -1892,3 +2054,40 @@ ssa.cpp: # 401| v401_13(void) = ReturnVoid : # 401| v401_14(void) = AliasedUse : ~m408_10 # 401| v401_15(void) = ExitFunction : + +# 417| void nested_array_designators() +# 417| Block 0 +# 417| v417_1(void) = EnterFunction : +# 417| m417_2(unknown) = AliasedDefinition : +# 417| m417_3(unknown) = InitializeNonLocal : +# 417| m417_4(unknown) = Chi : total:m417_2, partial:m417_3 +# 418| r418_1(glval) = VariableAddress[x] : +# 418| m418_2(int[1][2]) = Uninitialized[x] : &:r418_1 +# 418| r418_3(int) = Constant[0] : +# 418| r418_4(glval) = PointerAdd[8] : r418_1, r418_3 +# 418| r418_5(int) = Constant[0] : +# 418| r418_6(glval) = PointerAdd[4] : r418_4, r418_5 +# 418| r418_7(int) = Constant[1234] : +# 418| m418_8(int) = Store[?] : &:r418_6, r418_7 +# 418| m418_9(int[1][2]) = Chi : total:m418_2, partial:m418_8 +# 418| r418_10(int) = Constant[1] : +# 418| r418_11(glval) = PointerAdd[4] : r418_4, r418_10 +# 418| r418_12(int) = Constant[0] : +# 418| m418_13(int) = Store[?] : &:r418_11, r418_12 +# 418| m418_14(int[1][2]) = Chi : total:m418_9, partial:m418_13 +# 418| r418_15(int) = Constant[0] : +# 418| r418_16(glval) = PointerAdd[8] : r418_1, r418_15 +# 418| r418_17(int) = Constant[0] : +# 418| r418_18(glval) = PointerAdd[4] : r418_16, r418_17 +# 418| r418_19(int) = Constant[0] : +# 418| m418_20(int) = Store[?] : &:r418_18, r418_19 +# 418| m418_21(int[1][2]) = Chi : total:m418_14, partial:m418_20 +# 418| r418_22(int) = Constant[1] : +# 418| r418_23(glval) = PointerAdd[4] : r418_16, r418_22 +# 418| r418_24(int) = Constant[5678] : +# 418| m418_25(int) = Store[?] : &:r418_23, r418_24 +# 418| m418_26(int[1][2]) = Chi : total:m418_21, partial:m418_25 +# 419| v419_1(void) = NoOp : +# 417| v417_5(void) = ReturnVoid : +# 417| v417_6(void) = AliasedUse : m417_3 +# 417| v417_7(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected index 1ad86dc0da0..fb9cb8737b9 100644 --- a/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/aliased_ssa_ir_unsound.expected @@ -1,3 +1,165 @@ +ssa.c: +# 2| void named_designators() +# 2| Block 0 +# 2| v2_1(void) = EnterFunction : +# 2| m2_2(unknown) = AliasedDefinition : +# 2| m2_3(unknown) = InitializeNonLocal : +# 2| m2_4(unknown) = Chi : total:m2_2, partial:m2_3 +# 3| r3_1(glval) = VariableAddress[foo] : +# 3| m3_2(Foo) = Uninitialized[foo] : &:r3_1 +# 3| r3_3(glval) = FieldAddress[x] : r3_1 +# 3| r3_4(int) = Constant[0] : +# 3| r3_5(glval) = PointerAdd[4] : r3_3, r3_4 +# 3| r3_6(int) = Constant[1234] : +# 3| m3_7(int) = Store[?] : &:r3_5, r3_6 +# 3| m3_8(Foo) = Chi : total:m3_2, partial:m3_7 +# 3| r3_9(int) = Constant[1] : +# 3| r3_10(glval) = PointerAdd[4] : r3_3, r3_9 +# 3| r3_11(int) = Constant[0] : +# 3| m3_12(int) = Store[?] : &:r3_10, r3_11 +# 3| m3_13(Foo) = Chi : total:m3_8, partial:m3_12 +# 3| r3_14(glval) = FieldAddress[x] : r3_1 +# 3| r3_15(int) = Constant[0] : +# 3| r3_16(glval) = PointerAdd[4] : r3_14, r3_15 +# 3| r3_17(int) = Constant[0] : +# 3| m3_18(int) = Store[?] : &:r3_16, r3_17 +# 3| m3_19(Foo) = Chi : total:m3_13, partial:m3_18 +# 3| r3_20(int) = Constant[1] : +# 3| r3_21(glval) = PointerAdd[4] : r3_14, r3_20 +# 3| r3_22(int) = Constant[5678] : +# 3| m3_23(int) = Store[?] : &:r3_21, r3_22 +# 3| m3_24(Foo) = Chi : total:m3_19, partial:m3_23 +# 4| v4_1(void) = NoOp : +# 2| v2_5(void) = ReturnVoid : +# 2| v2_6(void) = AliasedUse : m2_3 +# 2| v2_7(void) = ExitFunction : + +# 6| void repeated_designators() +# 6| Block 0 +# 6| v6_1(void) = EnterFunction : +# 6| m6_2(unknown) = AliasedDefinition : +# 6| m6_3(unknown) = InitializeNonLocal : +# 6| m6_4(unknown) = Chi : total:m6_2, partial:m6_3 +# 7| r7_1(glval) = VariableAddress[x] : +# 7| m7_2(int[1]) = Uninitialized[x] : &:r7_1 +# 7| r7_3(int) = Constant[0] : +# 7| r7_4(glval) = PointerAdd[4] : r7_1, r7_3 +# 7| r7_5(int) = Constant[1234] : +# 7| m7_6(int) = Store[?] : &:r7_4, r7_5 +# 7| r7_7(int) = Constant[0] : +# 7| r7_8(glval) = PointerAdd[4] : r7_1, r7_7 +# 7| r7_9(int) = Constant[5678] : +# 7| m7_10(int) = Store[?] : &:r7_8, r7_9 +# 8| v8_1(void) = NoOp : +# 6| v6_5(void) = ReturnVoid : +# 6| v6_6(void) = AliasedUse : m6_3 +# 6| v6_7(void) = ExitFunction : + +# 11| void named_designators_2() +# 11| Block 0 +# 11| v11_1(void) = EnterFunction : +# 11| m11_2(unknown) = AliasedDefinition : +# 11| m11_3(unknown) = InitializeNonLocal : +# 11| m11_4(unknown) = Chi : total:m11_2, partial:m11_3 +# 12| r12_1(glval) = VariableAddress[foo] : +# 12| m12_2(Foo2) = Uninitialized[foo] : &:r12_1 +# 12| r12_3(glval) = FieldAddress[x] : r12_1 +# 12| r12_4(int) = Constant[1234] : +# 12| m12_5(int) = Store[?] : &:r12_3, r12_4 +# 12| m12_6(Foo2) = Chi : total:m12_2, partial:m12_5 +# 12| r12_7(glval) = FieldAddress[y] : r12_1 +# 12| r12_8(int) = Constant[5678] : +# 12| m12_9(int) = Store[?] : &:r12_7, r12_8 +# 12| m12_10(Foo2) = Chi : total:m12_6, partial:m12_9 +# 14| r14_1(glval) = VariableAddress[foo_swapped] : +# 14| m14_2(Foo2) = Uninitialized[foo_swapped] : &:r14_1 +# 14| r14_3(glval) = FieldAddress[x] : r14_1 +# 14| r14_4(int) = Constant[1234] : +# 14| m14_5(int) = Store[?] : &:r14_3, r14_4 +# 14| m14_6(Foo2) = Chi : total:m14_2, partial:m14_5 +# 14| r14_7(glval) = FieldAddress[y] : r14_1 +# 14| r14_8(int) = Constant[5678] : +# 14| m14_9(int) = Store[?] : &:r14_7, r14_8 +# 14| m14_10(Foo2) = Chi : total:m14_6, partial:m14_9 +# 15| v15_1(void) = NoOp : +# 11| v11_5(void) = ReturnVoid : +# 11| v11_6(void) = AliasedUse : m11_3 +# 11| v11_7(void) = ExitFunction : + +# 17| void non_repeated_designators() +# 17| Block 0 +# 17| v17_1(void) = EnterFunction : +# 17| m17_2(unknown) = AliasedDefinition : +# 17| m17_3(unknown) = InitializeNonLocal : +# 17| m17_4(unknown) = Chi : total:m17_2, partial:m17_3 +# 18| r18_1(glval) = VariableAddress[x] : +# 18| m18_2(int[2]) = Uninitialized[x] : &:r18_1 +# 18| r18_3(int) = Constant[0] : +# 18| r18_4(glval) = PointerAdd[4] : r18_1, r18_3 +# 18| r18_5(int) = Constant[1234] : +# 18| m18_6(int) = Store[?] : &:r18_4, r18_5 +# 18| m18_7(int[2]) = Chi : total:m18_2, partial:m18_6 +# 18| r18_8(int) = Constant[1] : +# 18| r18_9(glval) = PointerAdd[4] : r18_1, r18_8 +# 18| r18_10(int) = Constant[5678] : +# 18| m18_11(int) = Store[?] : &:r18_9, r18_10 +# 18| m18_12(int[2]) = Chi : total:m18_7, partial:m18_11 +# 20| r20_1(glval) = VariableAddress[y] : +# 20| m20_2(int[2]) = Uninitialized[y] : &:r20_1 +# 20| r20_3(int) = Constant[0] : +# 20| r20_4(glval) = PointerAdd[4] : r20_1, r20_3 +# 20| r20_5(int) = Constant[5678] : +# 20| m20_6(int) = Store[?] : &:r20_4, r20_5 +# 20| m20_7(int[2]) = Chi : total:m20_2, partial:m20_6 +# 20| r20_8(int) = Constant[1] : +# 20| r20_9(glval) = PointerAdd[4] : r20_1, r20_8 +# 20| r20_10(int) = Constant[1234] : +# 20| m20_11(int) = Store[?] : &:r20_9, r20_10 +# 20| m20_12(int[2]) = Chi : total:m20_7, partial:m20_11 +# 21| v21_1(void) = NoOp : +# 17| v17_5(void) = ReturnVoid : +# 17| v17_6(void) = AliasedUse : m17_3 +# 17| v17_7(void) = ExitFunction : + +# 28| void test_foo_array_and_int() +# 28| Block 0 +# 28| v28_1(void) = EnterFunction : +# 28| m28_2(unknown) = AliasedDefinition : +# 28| m28_3(unknown) = InitializeNonLocal : +# 28| m28_4(unknown) = Chi : total:m28_2, partial:m28_3 +# 29| r29_1(glval) = VariableAddress[f] : +# 29| m29_2(Foo_array_and_int) = Uninitialized[f] : &:r29_1 +# 29| r29_3(glval) = FieldAddress[x] : r29_1 +# 29| r29_4(int) = Constant[0] : +# 29| r29_5(glval) = PointerAdd[4] : r29_3, r29_4 +# 29| r29_6(int) = Constant[0] : +# 29| m29_7(int) = Store[?] : &:r29_5, r29_6 +# 29| m29_8(Foo_array_and_int) = Chi : total:m29_2, partial:m29_7 +# 29| r29_9(int) = Constant[1] : +# 29| r29_10(glval) = PointerAdd[4] : r29_3, r29_9 +# 29| r29_11(int) = Constant[1] : +# 29| m29_12(int) = Store[?] : &:r29_10, r29_11 +# 29| m29_13(Foo_array_and_int) = Chi : total:m29_8, partial:m29_12 +# 29| r29_14(glval) = FieldAddress[x] : r29_1 +# 29| r29_15(int) = Constant[0] : +# 29| r29_16(glval) = PointerAdd[4] : r29_14, r29_15 +# 29| r29_17(int) = Constant[42] : +# 29| m29_18(int) = Store[?] : &:r29_16, r29_17 +# 29| m29_19(Foo_array_and_int) = Chi : total:m29_13, partial:m29_18 +# 29| r29_20(int) = Constant[1] : +# 29| r29_21(glval) = PointerAdd[4] : r29_14, r29_20 +# 29| r29_22(int) = Constant[0] : +# 29| m29_23(int) = Store[?] : &:r29_21, r29_22 +# 29| m29_24(Foo_array_and_int) = Chi : total:m29_19, partial:m29_23 +# 29| r29_25(glval) = FieldAddress[y] : r29_1 +# 29| r29_26(int) = Constant[42] : +# 29| m29_27(int) = Store[?] : &:r29_25, r29_26 +# 29| m29_28(Foo_array_and_int) = Chi : total:m29_24, partial:m29_27 +# 30| v30_1(void) = NoOp : +# 28| v28_5(void) = ReturnVoid : +# 28| v28_6(void) = AliasedUse : m28_3 +# 28| v28_7(void) = ExitFunction : + ssa.cpp: # 13| int ChiPhiNode(Point*, bool, bool) # 13| Block 0 @@ -1881,3 +2043,40 @@ ssa.cpp: # 401| v401_13(void) = ReturnVoid : # 401| v401_14(void) = AliasedUse : ~m408_10 # 401| v401_15(void) = ExitFunction : + +# 417| void nested_array_designators() +# 417| Block 0 +# 417| v417_1(void) = EnterFunction : +# 417| m417_2(unknown) = AliasedDefinition : +# 417| m417_3(unknown) = InitializeNonLocal : +# 417| m417_4(unknown) = Chi : total:m417_2, partial:m417_3 +# 418| r418_1(glval) = VariableAddress[x] : +# 418| m418_2(int[1][2]) = Uninitialized[x] : &:r418_1 +# 418| r418_3(int) = Constant[0] : +# 418| r418_4(glval) = PointerAdd[8] : r418_1, r418_3 +# 418| r418_5(int) = Constant[0] : +# 418| r418_6(glval) = PointerAdd[4] : r418_4, r418_5 +# 418| r418_7(int) = Constant[1234] : +# 418| m418_8(int) = Store[?] : &:r418_6, r418_7 +# 418| m418_9(int[1][2]) = Chi : total:m418_2, partial:m418_8 +# 418| r418_10(int) = Constant[1] : +# 418| r418_11(glval) = PointerAdd[4] : r418_4, r418_10 +# 418| r418_12(int) = Constant[0] : +# 418| m418_13(int) = Store[?] : &:r418_11, r418_12 +# 418| m418_14(int[1][2]) = Chi : total:m418_9, partial:m418_13 +# 418| r418_15(int) = Constant[0] : +# 418| r418_16(glval) = PointerAdd[8] : r418_1, r418_15 +# 418| r418_17(int) = Constant[0] : +# 418| r418_18(glval) = PointerAdd[4] : r418_16, r418_17 +# 418| r418_19(int) = Constant[0] : +# 418| m418_20(int) = Store[?] : &:r418_18, r418_19 +# 418| m418_21(int[1][2]) = Chi : total:m418_14, partial:m418_20 +# 418| r418_22(int) = Constant[1] : +# 418| r418_23(glval) = PointerAdd[4] : r418_16, r418_22 +# 418| r418_24(int) = Constant[5678] : +# 418| m418_25(int) = Store[?] : &:r418_23, r418_24 +# 418| m418_26(int[1][2]) = Chi : total:m418_21, partial:m418_25 +# 419| v419_1(void) = NoOp : +# 417| v417_5(void) = ReturnVoid : +# 417| v417_6(void) = AliasedUse : m417_3 +# 417| v417_7(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/ssa.c b/cpp/ql/test/library-tests/ir/ssa/ssa.c new file mode 100644 index 00000000000..991c6f38625 --- /dev/null +++ b/cpp/ql/test/library-tests/ir/ssa/ssa.c @@ -0,0 +1,30 @@ +struct Foo { int x[2]; }; +void named_designators() { + struct Foo foo = {.x[0] = 1234, .x[1] = 5678}; +} + +void repeated_designators() { + int x[1] = {[0] = 1234, [0] = 5678}; +} + +struct Foo2 { int x; int y; }; +void named_designators_2() { + struct Foo2 foo = {.x = 1234, .y = 5678}; + + struct Foo2 foo_swapped = {.y = 5678, .x = 1234}; +} + +void non_repeated_designators() { + int x[2] = {[0] = 1234, [1] = 5678}; + + int y[2] = {[1] = 1234, [0] = 5678}; +} + +struct Foo_array_and_int { + int x[2]; + int y; +}; + +void test_foo_array_and_int() { + struct Foo_array_and_int f = { .x = {0, 1}, .x[0] = 42, .y = 42 }; +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/ir/ssa/ssa.cpp b/cpp/ql/test/library-tests/ir/ssa/ssa.cpp index 98c33c3eddf..d356f0dc1f7 100644 --- a/cpp/ql/test/library-tests/ir/ssa/ssa.cpp +++ b/cpp/ql/test/library-tests/ir/ssa/ssa.cpp @@ -412,4 +412,8 @@ void vla(int n1, int n2, int n3, bool b1) { } else { int b[n2]; } -} \ No newline at end of file +} + +void nested_array_designators() { + int x[1][2] = {[0][0] = 1234, [0][1] = 5678}; +} diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected index 03de47a1ab0..7efa7691d4d 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir.expected @@ -1,3 +1,143 @@ +ssa.c: +# 2| void named_designators() +# 2| Block 0 +# 2| v2_1(void) = EnterFunction : +# 2| mu2_2(unknown) = AliasedDefinition : +# 2| mu2_3(unknown) = InitializeNonLocal : +# 3| r3_1(glval) = VariableAddress[foo] : +# 3| mu3_2(Foo) = Uninitialized[foo] : &:r3_1 +# 3| r3_3(glval) = FieldAddress[x] : r3_1 +# 3| r3_4(int) = Constant[0] : +# 3| r3_5(glval) = PointerAdd[4] : r3_3, r3_4 +# 3| r3_6(int) = Constant[1234] : +# 3| mu3_7(int) = Store[?] : &:r3_5, r3_6 +# 3| r3_8(int) = Constant[1] : +# 3| r3_9(glval) = PointerAdd[4] : r3_3, r3_8 +# 3| r3_10(int) = Constant[0] : +# 3| mu3_11(int) = Store[?] : &:r3_9, r3_10 +# 3| r3_12(glval) = FieldAddress[x] : r3_1 +# 3| r3_13(int) = Constant[0] : +# 3| r3_14(glval) = PointerAdd[4] : r3_12, r3_13 +# 3| r3_15(int) = Constant[0] : +# 3| mu3_16(int) = Store[?] : &:r3_14, r3_15 +# 3| r3_17(int) = Constant[1] : +# 3| r3_18(glval) = PointerAdd[4] : r3_12, r3_17 +# 3| r3_19(int) = Constant[5678] : +# 3| mu3_20(int) = Store[?] : &:r3_18, r3_19 +# 4| v4_1(void) = NoOp : +# 2| v2_4(void) = ReturnVoid : +# 2| v2_5(void) = AliasedUse : ~m? +# 2| v2_6(void) = ExitFunction : + +# 6| void repeated_designators() +# 6| Block 0 +# 6| v6_1(void) = EnterFunction : +# 6| mu6_2(unknown) = AliasedDefinition : +# 6| mu6_3(unknown) = InitializeNonLocal : +# 7| r7_1(glval) = VariableAddress[x] : +# 7| mu7_2(int[1]) = Uninitialized[x] : &:r7_1 +# 7| r7_3(int) = Constant[0] : +# 7| r7_4(glval) = PointerAdd[4] : r7_1, r7_3 +# 7| r7_5(int) = Constant[1234] : +# 7| mu7_6(int) = Store[?] : &:r7_4, r7_5 +# 7| r7_7(int) = Constant[0] : +# 7| r7_8(glval) = PointerAdd[4] : r7_1, r7_7 +# 7| r7_9(int) = Constant[5678] : +# 7| mu7_10(int) = Store[?] : &:r7_8, r7_9 +# 8| v8_1(void) = NoOp : +# 6| v6_4(void) = ReturnVoid : +# 6| v6_5(void) = AliasedUse : ~m? +# 6| v6_6(void) = ExitFunction : + +# 11| void named_designators_2() +# 11| Block 0 +# 11| v11_1(void) = EnterFunction : +# 11| mu11_2(unknown) = AliasedDefinition : +# 11| mu11_3(unknown) = InitializeNonLocal : +# 12| r12_1(glval) = VariableAddress[foo] : +# 12| mu12_2(Foo2) = Uninitialized[foo] : &:r12_1 +# 12| r12_3(glval) = FieldAddress[x] : r12_1 +# 12| r12_4(int) = Constant[1234] : +# 12| mu12_5(int) = Store[?] : &:r12_3, r12_4 +# 12| r12_6(glval) = FieldAddress[y] : r12_1 +# 12| r12_7(int) = Constant[5678] : +# 12| mu12_8(int) = Store[?] : &:r12_6, r12_7 +# 14| r14_1(glval) = VariableAddress[foo_swapped] : +# 14| mu14_2(Foo2) = Uninitialized[foo_swapped] : &:r14_1 +# 14| r14_3(glval) = FieldAddress[x] : r14_1 +# 14| r14_4(int) = Constant[1234] : +# 14| mu14_5(int) = Store[?] : &:r14_3, r14_4 +# 14| r14_6(glval) = FieldAddress[y] : r14_1 +# 14| r14_7(int) = Constant[5678] : +# 14| mu14_8(int) = Store[?] : &:r14_6, r14_7 +# 15| v15_1(void) = NoOp : +# 11| v11_4(void) = ReturnVoid : +# 11| v11_5(void) = AliasedUse : ~m? +# 11| v11_6(void) = ExitFunction : + +# 17| void non_repeated_designators() +# 17| Block 0 +# 17| v17_1(void) = EnterFunction : +# 17| mu17_2(unknown) = AliasedDefinition : +# 17| mu17_3(unknown) = InitializeNonLocal : +# 18| r18_1(glval) = VariableAddress[x] : +# 18| mu18_2(int[2]) = Uninitialized[x] : &:r18_1 +# 18| r18_3(int) = Constant[0] : +# 18| r18_4(glval) = PointerAdd[4] : r18_1, r18_3 +# 18| r18_5(int) = Constant[1234] : +# 18| mu18_6(int) = Store[?] : &:r18_4, r18_5 +# 18| r18_7(int) = Constant[1] : +# 18| r18_8(glval) = PointerAdd[4] : r18_1, r18_7 +# 18| r18_9(int) = Constant[5678] : +# 18| mu18_10(int) = Store[?] : &:r18_8, r18_9 +# 20| r20_1(glval) = VariableAddress[y] : +# 20| mu20_2(int[2]) = Uninitialized[y] : &:r20_1 +# 20| r20_3(int) = Constant[0] : +# 20| r20_4(glval) = PointerAdd[4] : r20_1, r20_3 +# 20| r20_5(int) = Constant[5678] : +# 20| mu20_6(int) = Store[?] : &:r20_4, r20_5 +# 20| r20_7(int) = Constant[1] : +# 20| r20_8(glval) = PointerAdd[4] : r20_1, r20_7 +# 20| r20_9(int) = Constant[1234] : +# 20| mu20_10(int) = Store[?] : &:r20_8, r20_9 +# 21| v21_1(void) = NoOp : +# 17| v17_4(void) = ReturnVoid : +# 17| v17_5(void) = AliasedUse : ~m? +# 17| v17_6(void) = ExitFunction : + +# 28| void test_foo_array_and_int() +# 28| Block 0 +# 28| v28_1(void) = EnterFunction : +# 28| mu28_2(unknown) = AliasedDefinition : +# 28| mu28_3(unknown) = InitializeNonLocal : +# 29| r29_1(glval) = VariableAddress[f] : +# 29| mu29_2(Foo_array_and_int) = Uninitialized[f] : &:r29_1 +# 29| r29_3(glval) = FieldAddress[x] : r29_1 +# 29| r29_4(int) = Constant[0] : +# 29| r29_5(glval) = PointerAdd[4] : r29_3, r29_4 +# 29| r29_6(int) = Constant[0] : +# 29| mu29_7(int) = Store[?] : &:r29_5, r29_6 +# 29| r29_8(int) = Constant[1] : +# 29| r29_9(glval) = PointerAdd[4] : r29_3, r29_8 +# 29| r29_10(int) = Constant[1] : +# 29| mu29_11(int) = Store[?] : &:r29_9, r29_10 +# 29| r29_12(glval) = FieldAddress[x] : r29_1 +# 29| r29_13(int) = Constant[0] : +# 29| r29_14(glval) = PointerAdd[4] : r29_12, r29_13 +# 29| r29_15(int) = Constant[42] : +# 29| mu29_16(int) = Store[?] : &:r29_14, r29_15 +# 29| r29_17(int) = Constant[1] : +# 29| r29_18(glval) = PointerAdd[4] : r29_12, r29_17 +# 29| r29_19(int) = Constant[0] : +# 29| mu29_20(int) = Store[?] : &:r29_18, r29_19 +# 29| r29_21(glval) = FieldAddress[y] : r29_1 +# 29| r29_22(int) = Constant[42] : +# 29| mu29_23(int) = Store[?] : &:r29_21, r29_22 +# 30| v30_1(void) = NoOp : +# 28| v28_4(void) = ReturnVoid : +# 28| v28_5(void) = AliasedUse : ~m? +# 28| v28_6(void) = ExitFunction : + ssa.cpp: # 13| int ChiPhiNode(Point*, bool, bool) # 13| Block 0 @@ -1768,3 +1908,35 @@ ssa.cpp: # 401| v401_12(void) = ReturnVoid : # 401| v401_13(void) = AliasedUse : ~m? # 401| v401_14(void) = ExitFunction : + +# 417| void nested_array_designators() +# 417| Block 0 +# 417| v417_1(void) = EnterFunction : +# 417| mu417_2(unknown) = AliasedDefinition : +# 417| mu417_3(unknown) = InitializeNonLocal : +# 418| r418_1(glval) = VariableAddress[x] : +# 418| mu418_2(int[1][2]) = Uninitialized[x] : &:r418_1 +# 418| r418_3(int) = Constant[0] : +# 418| r418_4(glval) = PointerAdd[8] : r418_1, r418_3 +# 418| r418_5(int) = Constant[0] : +# 418| r418_6(glval) = PointerAdd[4] : r418_4, r418_5 +# 418| r418_7(int) = Constant[1234] : +# 418| mu418_8(int) = Store[?] : &:r418_6, r418_7 +# 418| r418_9(int) = Constant[1] : +# 418| r418_10(glval) = PointerAdd[4] : r418_4, r418_9 +# 418| r418_11(int) = Constant[0] : +# 418| mu418_12(int) = Store[?] : &:r418_10, r418_11 +# 418| r418_13(int) = Constant[0] : +# 418| r418_14(glval) = PointerAdd[8] : r418_1, r418_13 +# 418| r418_15(int) = Constant[0] : +# 418| r418_16(glval) = PointerAdd[4] : r418_14, r418_15 +# 418| r418_17(int) = Constant[0] : +# 418| mu418_18(int) = Store[?] : &:r418_16, r418_17 +# 418| r418_19(int) = Constant[1] : +# 418| r418_20(glval) = PointerAdd[4] : r418_14, r418_19 +# 418| r418_21(int) = Constant[5678] : +# 418| mu418_22(int) = Store[?] : &:r418_20, r418_21 +# 419| v419_1(void) = NoOp : +# 417| v417_4(void) = ReturnVoid : +# 417| v417_5(void) = AliasedUse : ~m? +# 417| v417_6(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected index 03de47a1ab0..7efa7691d4d 100644 --- a/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ssa/unaliased_ssa_ir_unsound.expected @@ -1,3 +1,143 @@ +ssa.c: +# 2| void named_designators() +# 2| Block 0 +# 2| v2_1(void) = EnterFunction : +# 2| mu2_2(unknown) = AliasedDefinition : +# 2| mu2_3(unknown) = InitializeNonLocal : +# 3| r3_1(glval) = VariableAddress[foo] : +# 3| mu3_2(Foo) = Uninitialized[foo] : &:r3_1 +# 3| r3_3(glval) = FieldAddress[x] : r3_1 +# 3| r3_4(int) = Constant[0] : +# 3| r3_5(glval) = PointerAdd[4] : r3_3, r3_4 +# 3| r3_6(int) = Constant[1234] : +# 3| mu3_7(int) = Store[?] : &:r3_5, r3_6 +# 3| r3_8(int) = Constant[1] : +# 3| r3_9(glval) = PointerAdd[4] : r3_3, r3_8 +# 3| r3_10(int) = Constant[0] : +# 3| mu3_11(int) = Store[?] : &:r3_9, r3_10 +# 3| r3_12(glval) = FieldAddress[x] : r3_1 +# 3| r3_13(int) = Constant[0] : +# 3| r3_14(glval) = PointerAdd[4] : r3_12, r3_13 +# 3| r3_15(int) = Constant[0] : +# 3| mu3_16(int) = Store[?] : &:r3_14, r3_15 +# 3| r3_17(int) = Constant[1] : +# 3| r3_18(glval) = PointerAdd[4] : r3_12, r3_17 +# 3| r3_19(int) = Constant[5678] : +# 3| mu3_20(int) = Store[?] : &:r3_18, r3_19 +# 4| v4_1(void) = NoOp : +# 2| v2_4(void) = ReturnVoid : +# 2| v2_5(void) = AliasedUse : ~m? +# 2| v2_6(void) = ExitFunction : + +# 6| void repeated_designators() +# 6| Block 0 +# 6| v6_1(void) = EnterFunction : +# 6| mu6_2(unknown) = AliasedDefinition : +# 6| mu6_3(unknown) = InitializeNonLocal : +# 7| r7_1(glval) = VariableAddress[x] : +# 7| mu7_2(int[1]) = Uninitialized[x] : &:r7_1 +# 7| r7_3(int) = Constant[0] : +# 7| r7_4(glval) = PointerAdd[4] : r7_1, r7_3 +# 7| r7_5(int) = Constant[1234] : +# 7| mu7_6(int) = Store[?] : &:r7_4, r7_5 +# 7| r7_7(int) = Constant[0] : +# 7| r7_8(glval) = PointerAdd[4] : r7_1, r7_7 +# 7| r7_9(int) = Constant[5678] : +# 7| mu7_10(int) = Store[?] : &:r7_8, r7_9 +# 8| v8_1(void) = NoOp : +# 6| v6_4(void) = ReturnVoid : +# 6| v6_5(void) = AliasedUse : ~m? +# 6| v6_6(void) = ExitFunction : + +# 11| void named_designators_2() +# 11| Block 0 +# 11| v11_1(void) = EnterFunction : +# 11| mu11_2(unknown) = AliasedDefinition : +# 11| mu11_3(unknown) = InitializeNonLocal : +# 12| r12_1(glval) = VariableAddress[foo] : +# 12| mu12_2(Foo2) = Uninitialized[foo] : &:r12_1 +# 12| r12_3(glval) = FieldAddress[x] : r12_1 +# 12| r12_4(int) = Constant[1234] : +# 12| mu12_5(int) = Store[?] : &:r12_3, r12_4 +# 12| r12_6(glval) = FieldAddress[y] : r12_1 +# 12| r12_7(int) = Constant[5678] : +# 12| mu12_8(int) = Store[?] : &:r12_6, r12_7 +# 14| r14_1(glval) = VariableAddress[foo_swapped] : +# 14| mu14_2(Foo2) = Uninitialized[foo_swapped] : &:r14_1 +# 14| r14_3(glval) = FieldAddress[x] : r14_1 +# 14| r14_4(int) = Constant[1234] : +# 14| mu14_5(int) = Store[?] : &:r14_3, r14_4 +# 14| r14_6(glval) = FieldAddress[y] : r14_1 +# 14| r14_7(int) = Constant[5678] : +# 14| mu14_8(int) = Store[?] : &:r14_6, r14_7 +# 15| v15_1(void) = NoOp : +# 11| v11_4(void) = ReturnVoid : +# 11| v11_5(void) = AliasedUse : ~m? +# 11| v11_6(void) = ExitFunction : + +# 17| void non_repeated_designators() +# 17| Block 0 +# 17| v17_1(void) = EnterFunction : +# 17| mu17_2(unknown) = AliasedDefinition : +# 17| mu17_3(unknown) = InitializeNonLocal : +# 18| r18_1(glval) = VariableAddress[x] : +# 18| mu18_2(int[2]) = Uninitialized[x] : &:r18_1 +# 18| r18_3(int) = Constant[0] : +# 18| r18_4(glval) = PointerAdd[4] : r18_1, r18_3 +# 18| r18_5(int) = Constant[1234] : +# 18| mu18_6(int) = Store[?] : &:r18_4, r18_5 +# 18| r18_7(int) = Constant[1] : +# 18| r18_8(glval) = PointerAdd[4] : r18_1, r18_7 +# 18| r18_9(int) = Constant[5678] : +# 18| mu18_10(int) = Store[?] : &:r18_8, r18_9 +# 20| r20_1(glval) = VariableAddress[y] : +# 20| mu20_2(int[2]) = Uninitialized[y] : &:r20_1 +# 20| r20_3(int) = Constant[0] : +# 20| r20_4(glval) = PointerAdd[4] : r20_1, r20_3 +# 20| r20_5(int) = Constant[5678] : +# 20| mu20_6(int) = Store[?] : &:r20_4, r20_5 +# 20| r20_7(int) = Constant[1] : +# 20| r20_8(glval) = PointerAdd[4] : r20_1, r20_7 +# 20| r20_9(int) = Constant[1234] : +# 20| mu20_10(int) = Store[?] : &:r20_8, r20_9 +# 21| v21_1(void) = NoOp : +# 17| v17_4(void) = ReturnVoid : +# 17| v17_5(void) = AliasedUse : ~m? +# 17| v17_6(void) = ExitFunction : + +# 28| void test_foo_array_and_int() +# 28| Block 0 +# 28| v28_1(void) = EnterFunction : +# 28| mu28_2(unknown) = AliasedDefinition : +# 28| mu28_3(unknown) = InitializeNonLocal : +# 29| r29_1(glval) = VariableAddress[f] : +# 29| mu29_2(Foo_array_and_int) = Uninitialized[f] : &:r29_1 +# 29| r29_3(glval) = FieldAddress[x] : r29_1 +# 29| r29_4(int) = Constant[0] : +# 29| r29_5(glval) = PointerAdd[4] : r29_3, r29_4 +# 29| r29_6(int) = Constant[0] : +# 29| mu29_7(int) = Store[?] : &:r29_5, r29_6 +# 29| r29_8(int) = Constant[1] : +# 29| r29_9(glval) = PointerAdd[4] : r29_3, r29_8 +# 29| r29_10(int) = Constant[1] : +# 29| mu29_11(int) = Store[?] : &:r29_9, r29_10 +# 29| r29_12(glval) = FieldAddress[x] : r29_1 +# 29| r29_13(int) = Constant[0] : +# 29| r29_14(glval) = PointerAdd[4] : r29_12, r29_13 +# 29| r29_15(int) = Constant[42] : +# 29| mu29_16(int) = Store[?] : &:r29_14, r29_15 +# 29| r29_17(int) = Constant[1] : +# 29| r29_18(glval) = PointerAdd[4] : r29_12, r29_17 +# 29| r29_19(int) = Constant[0] : +# 29| mu29_20(int) = Store[?] : &:r29_18, r29_19 +# 29| r29_21(glval) = FieldAddress[y] : r29_1 +# 29| r29_22(int) = Constant[42] : +# 29| mu29_23(int) = Store[?] : &:r29_21, r29_22 +# 30| v30_1(void) = NoOp : +# 28| v28_4(void) = ReturnVoid : +# 28| v28_5(void) = AliasedUse : ~m? +# 28| v28_6(void) = ExitFunction : + ssa.cpp: # 13| int ChiPhiNode(Point*, bool, bool) # 13| Block 0 @@ -1768,3 +1908,35 @@ ssa.cpp: # 401| v401_12(void) = ReturnVoid : # 401| v401_13(void) = AliasedUse : ~m? # 401| v401_14(void) = ExitFunction : + +# 417| void nested_array_designators() +# 417| Block 0 +# 417| v417_1(void) = EnterFunction : +# 417| mu417_2(unknown) = AliasedDefinition : +# 417| mu417_3(unknown) = InitializeNonLocal : +# 418| r418_1(glval) = VariableAddress[x] : +# 418| mu418_2(int[1][2]) = Uninitialized[x] : &:r418_1 +# 418| r418_3(int) = Constant[0] : +# 418| r418_4(glval) = PointerAdd[8] : r418_1, r418_3 +# 418| r418_5(int) = Constant[0] : +# 418| r418_6(glval) = PointerAdd[4] : r418_4, r418_5 +# 418| r418_7(int) = Constant[1234] : +# 418| mu418_8(int) = Store[?] : &:r418_6, r418_7 +# 418| r418_9(int) = Constant[1] : +# 418| r418_10(glval) = PointerAdd[4] : r418_4, r418_9 +# 418| r418_11(int) = Constant[0] : +# 418| mu418_12(int) = Store[?] : &:r418_10, r418_11 +# 418| r418_13(int) = Constant[0] : +# 418| r418_14(glval) = PointerAdd[8] : r418_1, r418_13 +# 418| r418_15(int) = Constant[0] : +# 418| r418_16(glval) = PointerAdd[4] : r418_14, r418_15 +# 418| r418_17(int) = Constant[0] : +# 418| mu418_18(int) = Store[?] : &:r418_16, r418_17 +# 418| r418_19(int) = Constant[1] : +# 418| r418_20(glval) = PointerAdd[4] : r418_14, r418_19 +# 418| r418_21(int) = Constant[5678] : +# 418| mu418_22(int) = Store[?] : &:r418_20, r418_21 +# 419| v419_1(void) = NoOp : +# 417| v417_4(void) = ReturnVoid : +# 417| v417_5(void) = AliasedUse : ~m? +# 417| v417_6(void) = ExitFunction :