diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll index 088cb7fa4cd5..22f104e12c83 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedCall.qll @@ -324,6 +324,16 @@ class TranslatedFunctionCall extends TranslatedCallExpr, TranslatedDirectCall { override predicate hasWriteSideEffect() { not expr.getTarget().(SideEffectFunction).hasOnlySpecificWriteSideEffects() } + + override Instruction getQualifierResult() { + hasQualifier() and + result = getQualifier().getResult() + } + + override predicate hasQualifier() { + exists(getQualifier()) and + not exists(MemberFunction func | expr.getTarget() = func and func.isStatic()) + } } /** diff --git a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index c3788f4c8da0..2f143bf02ca4 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -463,7 +463,9 @@ newtype TTranslatedElement = expr = call.getArgument(n).getFullyConverted() or expr = call.getQualifier().getFullyConverted() and - n = -1 + n = -1 and + // Exclude calls to static member functions. They don't modify the qualifier + not exists(MemberFunction func | func = call.getTarget() and func.isStatic()) ) and ( call.getTarget().(SideEffectFunction).hasSpecificReadSideEffect(n, _) and diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index f6d9fdc8a35b..e218b6daf47a 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -4048,6 +4048,27 @@ ir.cpp: #-----| Type = [RValueReferenceType] C && # 628| [Destructor] void C::~C() # 628| params: +#-----| body: [Block] { ... } +#-----| 0: [ReturnStmt] return ... +# 628| destructions: +# 628| 0: [DestructorFieldDestruction] destructor field destruction of m_f +# 628| Type = [Struct] String +# 628| ValueCategory = prvalue +# 628| 0: [DestructorCall] call to ~String +# 628| Type = [VoidType] void +# 628| ValueCategory = prvalue +# 628| -1: [ImplicitThisFieldAccess] m_f +# 628| Type = [Struct] String +# 628| ValueCategory = lvalue +# 628| 1: [DestructorFieldDestruction] destructor field destruction of m_b +# 628| Type = [Struct] String +# 628| ValueCategory = prvalue +# 628| 0: [DestructorCall] call to ~String +# 628| Type = [VoidType] void +# 628| ValueCategory = prvalue +# 628| -1: [ImplicitThisFieldAccess] m_b +# 628| Type = [Struct] String +# 628| ValueCategory = lvalue # 630| [MemberFunction] int C::StaticMemberFunction(int) # 630| params: # 630| 0: [Parameter] x @@ -8545,6 +8566,190 @@ ir.cpp: # 1255| Type = [CharPointerType] char * # 1255| ValueCategory = prvalue(load) # 1256| 3: [ReturnStmt] return ... +# 1258| [CopyAssignmentOperator] A& A::operator=(A const&) +# 1258| params: +#-----| 0: [Parameter] p#0 +#-----| Type = [LValueReferenceType] const A & +# 1258| [MoveAssignmentOperator] A& A::operator=(A&&) +# 1258| params: +#-----| 0: [Parameter] p#0 +#-----| Type = [RValueReferenceType] A && +# 1261| [MemberFunction] void A::static_member(A*, int) +# 1261| params: +# 1261| 0: [Parameter] a +# 1261| Type = [PointerType] A * +# 1261| 1: [Parameter] x +# 1261| Type = [IntType] int +# 1261| body: [Block] { ... } +# 1262| 0: [ExprStmt] ExprStmt +# 1262| 0: [AssignExpr] ... = ... +# 1262| Type = [IntType] int +# 1262| ValueCategory = lvalue +# 1262| 0: [PointerFieldAccess] member +# 1262| Type = [IntType] int +# 1262| ValueCategory = lvalue +# 1262| -1: [VariableAccess] a +# 1262| Type = [PointerType] A * +# 1262| ValueCategory = prvalue(load) +# 1262| 1: [VariableAccess] x +# 1262| Type = [IntType] int +# 1262| ValueCategory = prvalue(load) +# 1263| 1: [ReturnStmt] return ... +# 1265| [MemberFunction] void A::static_member_without_def() +# 1265| params: +# 1268| [TopLevelFunction] A* getAnInstanceOfA() +# 1268| params: +# 1270| [TopLevelFunction] void test_static_member_functions(int, A*) +# 1270| params: +# 1270| 0: [Parameter] int_arg +# 1270| Type = [IntType] int +# 1270| 1: [Parameter] a_arg +# 1270| Type = [PointerType] A * +# 1270| body: [Block] { ... } +# 1271| 0: [DeclStmt] declaration +# 1271| 0: [VariableDeclarationEntry] definition of c +# 1271| Type = [Class] C +# 1271| init: [Initializer] initializer for c +# 1271| expr: [ConstructorCall] call to C +# 1271| Type = [VoidType] void +# 1271| ValueCategory = prvalue +# 1272| 1: [ExprStmt] ExprStmt +# 1272| 0: [FunctionCall] call to StaticMemberFunction +# 1272| Type = [IntType] int +# 1272| ValueCategory = prvalue +# 1272| -1: [VariableAccess] c +# 1272| Type = [Class] C +# 1272| ValueCategory = lvalue +# 1272| 0: [Literal] 10 +# 1272| Type = [IntType] int +# 1272| Value = [Literal] 10 +# 1272| ValueCategory = prvalue +# 1273| 2: [ExprStmt] ExprStmt +# 1273| 0: [FunctionCall] call to StaticMemberFunction +# 1273| Type = [IntType] int +# 1273| ValueCategory = prvalue +# 1273| 0: [Literal] 10 +# 1273| Type = [IntType] int +# 1273| Value = [Literal] 10 +# 1273| ValueCategory = prvalue +# 1275| 3: [DeclStmt] declaration +# 1275| 0: [VariableDeclarationEntry] definition of a +# 1275| Type = [Struct] A +# 1276| 4: [ExprStmt] ExprStmt +# 1276| 0: [FunctionCall] call to static_member +# 1276| Type = [VoidType] void +# 1276| ValueCategory = prvalue +# 1276| -1: [VariableAccess] a +# 1276| Type = [Struct] A +# 1276| ValueCategory = lvalue +# 1276| 0: [AddressOfExpr] & ... +# 1276| Type = [PointerType] A * +# 1276| ValueCategory = prvalue +# 1276| 0: [VariableAccess] a +# 1276| Type = [Struct] A +# 1276| ValueCategory = lvalue +# 1276| 1: [VariableAccess] int_arg +# 1276| Type = [IntType] int +# 1276| ValueCategory = prvalue(load) +# 1277| 5: [ExprStmt] ExprStmt +# 1277| 0: [FunctionCall] call to static_member +# 1277| Type = [VoidType] void +# 1277| ValueCategory = prvalue +# 1277| 0: [AddressOfExpr] & ... +# 1277| Type = [PointerType] A * +# 1277| ValueCategory = prvalue +# 1277| 0: [VariableAccess] a +# 1277| Type = [Struct] A +# 1277| ValueCategory = lvalue +# 1277| 1: [VariableAccess] int_arg +# 1277| Type = [IntType] int +# 1277| ValueCategory = prvalue(load) +# 1279| 6: [ExprStmt] ExprStmt +# 1279| 0: [FunctionCall] call to static_member +# 1279| Type = [VoidType] void +# 1279| ValueCategory = prvalue +# 1279| -1: [ParenthesisExpr] (...) +# 1279| Type = [PointerType] A * +# 1279| ValueCategory = prvalue +# 1279| expr: [AddressOfExpr] & ... +# 1279| Type = [PointerType] A * +# 1279| ValueCategory = prvalue +# 1279| 0: [VariableAccess] a +# 1279| Type = [Struct] A +# 1279| ValueCategory = lvalue +# 1279| 0: [VariableAccess] a_arg +# 1279| Type = [PointerType] A * +# 1279| ValueCategory = prvalue(load) +# 1279| 1: [AddExpr] ... + ... +# 1279| Type = [IntType] int +# 1279| ValueCategory = prvalue +# 1279| 0: [VariableAccess] int_arg +# 1279| Type = [IntType] int +# 1279| ValueCategory = prvalue(load) +# 1279| 1: [Literal] 2 +# 1279| Type = [IntType] int +# 1279| Value = [Literal] 2 +# 1279| ValueCategory = prvalue +# 1280| 7: [ExprStmt] ExprStmt +# 1280| 0: [FunctionCall] call to static_member +# 1280| Type = [VoidType] void +# 1280| ValueCategory = prvalue +# 1280| -1: [ParenthesisExpr] (...) +# 1280| Type = [Struct] A +# 1280| ValueCategory = lvalue +# 1280| expr: [PointerDereferenceExpr] * ... +# 1280| Type = [Struct] A +# 1280| ValueCategory = lvalue +# 1280| 0: [VariableAccess] a_arg +# 1280| Type = [PointerType] A * +# 1280| ValueCategory = prvalue(load) +# 1280| 0: [AddressOfExpr] & ... +# 1280| Type = [PointerType] A * +# 1280| ValueCategory = prvalue +# 1280| 0: [VariableAccess] a +# 1280| Type = [Struct] A +# 1280| ValueCategory = lvalue +# 1280| 1: [Literal] 99 +# 1280| Type = [IntType] int +# 1280| Value = [Literal] 99 +# 1280| ValueCategory = prvalue +# 1281| 8: [ExprStmt] ExprStmt +# 1281| 0: [FunctionCall] call to static_member +# 1281| Type = [VoidType] void +# 1281| ValueCategory = prvalue +# 1281| -1: [VariableAccess] a_arg +# 1281| Type = [PointerType] A * +# 1281| ValueCategory = prvalue(load) +# 1281| 0: [VariableAccess] a_arg +# 1281| Type = [PointerType] A * +# 1281| ValueCategory = prvalue(load) +# 1281| 1: [UnaryMinusExpr] - ... +# 1281| Type = [IntType] int +# 1281| Value = [UnaryMinusExpr] -1 +# 1281| ValueCategory = prvalue +# 1281| 0: [Literal] 1 +# 1281| Type = [IntType] int +# 1281| Value = [Literal] 1 +# 1281| ValueCategory = prvalue +# 1283| 9: [ExprStmt] ExprStmt +# 1283| 0: [FunctionCall] call to static_member_without_def +# 1283| Type = [VoidType] void +# 1283| ValueCategory = prvalue +# 1283| -1: [VariableAccess] a +# 1283| Type = [Struct] A +# 1283| ValueCategory = lvalue +# 1284| 10: [ExprStmt] ExprStmt +# 1284| 0: [FunctionCall] call to static_member_without_def +# 1284| Type = [VoidType] void +# 1284| ValueCategory = prvalue +# 1286| 11: [ExprStmt] ExprStmt +# 1286| 0: [FunctionCall] call to static_member_without_def +# 1286| Type = [VoidType] void +# 1286| ValueCategory = prvalue +# 1286| -1: [FunctionCall] call to getAnInstanceOfA +# 1286| Type = [PointerType] A * +# 1286| ValueCategory = prvalue +# 1287| 12: [ReturnStmt] return ... perf-regression.cpp: # 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&) # 4| params: diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index 6f6ab081347e..ec40d9447894 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -1255,4 +1255,35 @@ void test_strings(char *s1, char *s2) { strcat(buffer, s2); } +struct A { + int member; + + static void static_member(A* a, int x) { + a->member = x; + } + + static void static_member_without_def(); +}; + +A* getAnInstanceOfA(); + +void test_static_member_functions(int int_arg, A* a_arg) { + C c; + c.StaticMemberFunction(10); + C::StaticMemberFunction(10); + + A a; + a.static_member(&a, int_arg); + A::static_member(&a, int_arg); + + (&a)->static_member(a_arg, int_arg + 2); + (*a_arg).static_member(&a, 99); + a_arg->static_member(a_arg, -1); + + a.static_member_without_def(); + A::static_member_without_def(); + + getAnInstanceOfA()->static_member_without_def(); +} + // semmle-extractor-options: -std=c++17 --clang diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index 28e6de0e1f13..d74ce2920b0d 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -2991,6 +2991,27 @@ ir.cpp: # 622| v622_19(void) = AliasedUse : ~mu622_4 # 622| v622_20(void) = ExitFunction : +# 628| void C::~C() +# 628| Block 0 +# 628| v628_1(void) = EnterFunction : +# 628| mu628_2(unknown) = AliasedDefinition : +# 628| mu628_3(unknown) = InitializeNonLocal : +# 628| mu628_4(unknown) = UnmodeledDefinition : +# 628| r628_5(glval) = InitializeThis : +#-----| v0_1(void) = NoOp : +# 628| r628_6(glval) = FieldAddress[m_f] : r628_5 +# 628| r628_7(glval) = FunctionAddress[~String] : +# 628| v628_8(void) = Call : func:r628_7, this:r628_6 +# 628| mu628_9(unknown) = ^CallSideEffect : ~mu628_4 +# 628| r628_10(glval) = FieldAddress[m_b] : r628_5 +# 628| r628_11(glval) = FunctionAddress[~String] : +# 628| v628_12(void) = Call : func:r628_11, this:r628_10 +# 628| mu628_13(unknown) = ^CallSideEffect : ~mu628_4 +# 628| v628_14(void) = ReturnVoid : +# 628| v628_15(void) = UnmodeledUse : mu* +# 628| v628_16(void) = AliasedUse : ~mu628_4 +# 628| v628_17(void) = ExitFunction : + # 630| int C::StaticMemberFunction(int) # 630| Block 0 # 630| v630_1(void) = EnterFunction : @@ -6483,6 +6504,133 @@ ir.cpp: # 1251| v1251_17(void) = AliasedUse : ~mu1251_4 # 1251| v1251_18(void) = ExitFunction : +# 1261| void A::static_member(A*, int) +# 1261| Block 0 +# 1261| v1261_1(void) = EnterFunction : +# 1261| mu1261_2(unknown) = AliasedDefinition : +# 1261| mu1261_3(unknown) = InitializeNonLocal : +# 1261| mu1261_4(unknown) = UnmodeledDefinition : +# 1261| r1261_5(glval) = VariableAddress[a] : +# 1261| mu1261_6(A *) = InitializeParameter[a] : &:r1261_5 +# 1261| r1261_7(A *) = Load : &:r1261_5, ~mu1261_6 +# 1261| mu1261_8(unknown) = InitializeIndirection[a] : &:r1261_7 +# 1261| r1261_9(glval) = VariableAddress[x] : +# 1261| mu1261_10(int) = InitializeParameter[x] : &:r1261_9 +# 1262| r1262_1(glval) = VariableAddress[x] : +# 1262| r1262_2(int) = Load : &:r1262_1, ~mu1261_4 +# 1262| r1262_3(glval) = VariableAddress[a] : +# 1262| r1262_4(A *) = Load : &:r1262_3, ~mu1261_4 +# 1262| r1262_5(glval) = FieldAddress[member] : r1262_4 +# 1262| mu1262_6(int) = Store : &:r1262_5, r1262_2 +# 1263| v1263_1(void) = NoOp : +# 1261| v1261_11(void) = ReturnIndirection : &:r1261_7, ~mu1261_4 +# 1261| v1261_12(void) = ReturnVoid : +# 1261| v1261_13(void) = UnmodeledUse : mu* +# 1261| v1261_14(void) = AliasedUse : ~mu1261_4 +# 1261| v1261_15(void) = ExitFunction : + +# 1270| void test_static_member_functions(int, A*) +# 1270| Block 0 +# 1270| v1270_1(void) = EnterFunction : +# 1270| mu1270_2(unknown) = AliasedDefinition : +# 1270| mu1270_3(unknown) = InitializeNonLocal : +# 1270| mu1270_4(unknown) = UnmodeledDefinition : +# 1270| r1270_5(glval) = VariableAddress[int_arg] : +# 1270| mu1270_6(int) = InitializeParameter[int_arg] : &:r1270_5 +# 1270| r1270_7(glval) = VariableAddress[a_arg] : +# 1270| mu1270_8(A *) = InitializeParameter[a_arg] : &:r1270_7 +# 1270| r1270_9(A *) = Load : &:r1270_7, ~mu1270_8 +# 1270| mu1270_10(unknown) = InitializeIndirection[a_arg] : &:r1270_9 +# 1271| r1271_1(glval) = VariableAddress[c] : +# 1271| mu1271_2(C) = Uninitialized[c] : &:r1271_1 +# 1271| r1271_3(glval) = FunctionAddress[C] : +# 1271| v1271_4(void) = Call : func:r1271_3, this:r1271_1 +# 1271| mu1271_5(unknown) = ^CallSideEffect : ~mu1270_4 +# 1271| mu1271_6(C) = ^IndirectMayWriteSideEffect[-1] : &:r1271_1 +# 1272| r1272_1(glval) = VariableAddress[c] : +# 1272| r1272_2(glval) = FunctionAddress[StaticMemberFunction] : +# 1272| r1272_3(int) = Constant[10] : +# 1272| r1272_4(int) = Call : func:r1272_2, 0:r1272_3 +# 1272| mu1272_5(unknown) = ^CallSideEffect : ~mu1270_4 +# 1273| r1273_1(glval) = FunctionAddress[StaticMemberFunction] : +# 1273| r1273_2(int) = Constant[10] : +# 1273| r1273_3(int) = Call : func:r1273_1, 0:r1273_2 +# 1273| mu1273_4(unknown) = ^CallSideEffect : ~mu1270_4 +# 1275| r1275_1(glval) = VariableAddress[a] : +# 1275| mu1275_2(A) = Uninitialized[a] : &:r1275_1 +# 1276| r1276_1(glval) = VariableAddress[a] : +# 1276| r1276_2(glval) = FunctionAddress[static_member] : +# 1276| r1276_3(glval) = VariableAddress[a] : +# 1276| r1276_4(A *) = CopyValue : r1276_3 +# 1276| r1276_5(glval) = VariableAddress[int_arg] : +# 1276| r1276_6(int) = Load : &:r1276_5, ~mu1270_4 +# 1276| v1276_7(void) = Call : func:r1276_2, 0:r1276_4, 1:r1276_6 +# 1276| mu1276_8(unknown) = ^CallSideEffect : ~mu1270_4 +# 1276| v1276_9(void) = ^BufferReadSideEffect[0] : &:r1276_4, ~mu1270_4 +# 1276| mu1276_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r1276_4 +# 1277| r1277_1(glval) = FunctionAddress[static_member] : +# 1277| r1277_2(glval) = VariableAddress[a] : +# 1277| r1277_3(A *) = CopyValue : r1277_2 +# 1277| r1277_4(glval) = VariableAddress[int_arg] : +# 1277| r1277_5(int) = Load : &:r1277_4, ~mu1270_4 +# 1277| v1277_6(void) = Call : func:r1277_1, 0:r1277_3, 1:r1277_5 +# 1277| mu1277_7(unknown) = ^CallSideEffect : ~mu1270_4 +# 1277| v1277_8(void) = ^BufferReadSideEffect[0] : &:r1277_3, ~mu1270_4 +# 1277| mu1277_9(unknown) = ^BufferMayWriteSideEffect[0] : &:r1277_3 +# 1279| r1279_1(glval) = VariableAddress[a] : +# 1279| r1279_2(A *) = CopyValue : r1279_1 +# 1279| r1279_3(glval) = FunctionAddress[static_member] : +# 1279| r1279_4(glval) = VariableAddress[a_arg] : +# 1279| r1279_5(A *) = Load : &:r1279_4, ~mu1270_4 +# 1279| r1279_6(glval) = VariableAddress[int_arg] : +# 1279| r1279_7(int) = Load : &:r1279_6, ~mu1270_4 +# 1279| r1279_8(int) = Constant[2] : +# 1279| r1279_9(int) = Add : r1279_7, r1279_8 +# 1279| v1279_10(void) = Call : func:r1279_3, 0:r1279_5, 1:r1279_9 +# 1279| mu1279_11(unknown) = ^CallSideEffect : ~mu1270_4 +# 1279| v1279_12(void) = ^BufferReadSideEffect[0] : &:r1279_5, ~mu1270_4 +# 1279| mu1279_13(unknown) = ^BufferMayWriteSideEffect[0] : &:r1279_5 +# 1280| r1280_1(glval) = VariableAddress[a_arg] : +# 1280| r1280_2(A *) = Load : &:r1280_1, ~mu1270_4 +# 1280| r1280_3(glval) = CopyValue : r1280_2 +# 1280| r1280_4(glval) = FunctionAddress[static_member] : +# 1280| r1280_5(glval) = VariableAddress[a] : +# 1280| r1280_6(A *) = CopyValue : r1280_5 +# 1280| r1280_7(int) = Constant[99] : +# 1280| v1280_8(void) = Call : func:r1280_4, 0:r1280_6, 1:r1280_7 +# 1280| mu1280_9(unknown) = ^CallSideEffect : ~mu1270_4 +# 1280| v1280_10(void) = ^BufferReadSideEffect[0] : &:r1280_6, ~mu1270_4 +# 1280| mu1280_11(unknown) = ^BufferMayWriteSideEffect[0] : &:r1280_6 +# 1281| r1281_1(glval) = VariableAddress[a_arg] : +# 1281| r1281_2(A *) = Load : &:r1281_1, ~mu1270_4 +# 1281| r1281_3(glval) = FunctionAddress[static_member] : +# 1281| r1281_4(glval) = VariableAddress[a_arg] : +# 1281| r1281_5(A *) = Load : &:r1281_4, ~mu1270_4 +# 1281| r1281_6(int) = Constant[-1] : +# 1281| v1281_7(void) = Call : func:r1281_3, 0:r1281_5, 1:r1281_6 +# 1281| mu1281_8(unknown) = ^CallSideEffect : ~mu1270_4 +# 1281| v1281_9(void) = ^BufferReadSideEffect[0] : &:r1281_5, ~mu1270_4 +# 1281| mu1281_10(unknown) = ^BufferMayWriteSideEffect[0] : &:r1281_5 +# 1283| r1283_1(glval) = VariableAddress[a] : +# 1283| r1283_2(glval) = FunctionAddress[static_member_without_def] : +# 1283| v1283_3(void) = Call : func:r1283_2 +# 1283| mu1283_4(unknown) = ^CallSideEffect : ~mu1270_4 +# 1284| r1284_1(glval) = FunctionAddress[static_member_without_def] : +# 1284| v1284_2(void) = Call : func:r1284_1 +# 1284| mu1284_3(unknown) = ^CallSideEffect : ~mu1270_4 +# 1286| r1286_1(glval) = FunctionAddress[getAnInstanceOfA] : +# 1286| r1286_2(A *) = Call : func:r1286_1 +# 1286| mu1286_3(unknown) = ^CallSideEffect : ~mu1270_4 +# 1286| r1286_4(glval) = FunctionAddress[static_member_without_def] : +# 1286| v1286_5(void) = Call : func:r1286_4 +# 1286| mu1286_6(unknown) = ^CallSideEffect : ~mu1270_4 +# 1287| v1287_1(void) = NoOp : +# 1270| v1270_11(void) = ReturnIndirection : &:r1270_9, ~mu1270_4 +# 1270| v1270_12(void) = ReturnVoid : +# 1270| v1270_13(void) = UnmodeledUse : mu* +# 1270| v1270_14(void) = AliasedUse : ~mu1270_4 +# 1270| v1270_15(void) = ExitFunction : + perf-regression.cpp: # 6| void Big::Big() # 6| Block 0