Skip to content

Commit 6575927

Browse files
committed
C++: Add IR tests demonstrating some inconsistencies that may occur
1 parent 2dcb55c commit 6575927

9 files changed

+259
-11
lines changed

cpp/ql/test/library-tests/ir/ir/PrintAST.expected

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22658,6 +22658,82 @@ ir.cpp:
2265822658
# 2541| getQualifier(): [VariableAccess] x
2265922659
# 2541| Type = [Class] ClassWithDestructor
2266022660
# 2541| ValueCategory = lvalue
22661+
# 2543| [TopLevelFunction] ClassWithDestructor getClassWithDestructor()
22662+
# 2543| <params>:
22663+
# 2545| [TopLevelFunction] void this_inconsistency(bool)
22664+
# 2545| <params>:
22665+
# 2545| getParameter(0): [Parameter] b
22666+
# 2545| Type = [BoolType] bool
22667+
# 2545| getEntryPoint(): [BlockStmt] { ... }
22668+
# 2546| getStmt(0): [IfStmt] if (...) ...
22669+
# 2546| getCondition(): [ConditionDeclExpr] (condition decl)
22670+
# 2546| Type = [BoolType] bool
22671+
# 2546| ValueCategory = prvalue
22672+
# 2546| getChild(0): [FunctionCall] call to operator bool
22673+
# 2546| Type = [BoolType] bool
22674+
# 2546| ValueCategory = prvalue
22675+
# 2546| getQualifier(): [VariableAccess] a
22676+
# 2546| Type = [LValueReferenceType] const ClassWithDestructor &
22677+
# 2546| ValueCategory = prvalue(load)
22678+
# 2546| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
22679+
# 2546| Type = [SpecifiedType] const ClassWithDestructor
22680+
# 2546| ValueCategory = prvalue(load)
22681+
# 2546| getInitializingExpr(): [FunctionCall] call to getClassWithDestructor
22682+
# 2546| Type = [Class] ClassWithDestructor
22683+
# 2546| ValueCategory = prvalue
22684+
# 2546| getInitializingExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
22685+
# 2546| Type = [LValueReferenceType] const ClassWithDestructor &
22686+
# 2546| ValueCategory = prvalue
22687+
# 2546| getExpr(): [CStyleCast] (const ClassWithDestructor)...
22688+
# 2546| Conversion = [GlvalueConversion] glvalue conversion
22689+
# 2546| Type = [SpecifiedType] const ClassWithDestructor
22690+
# 2546| ValueCategory = lvalue
22691+
# 2546| getExpr(): [TemporaryObjectExpr] temporary object
22692+
# 2546| Type = [Class] ClassWithDestructor
22693+
# 2546| ValueCategory = lvalue
22694+
# 2547| getThen(): [EmptyStmt] ;
22695+
# 2547| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
22696+
# 2547| Type = [VoidType] void
22697+
# 2547| ValueCategory = prvalue
22698+
# 2547| getQualifier(): [ReuseExpr] reuse of temporary object
22699+
# 2547| Type = [Class] ClassWithDestructor
22700+
# 2547| ValueCategory = xvalue
22701+
# 2548| getStmt(1): [ReturnStmt] return ...
22702+
# 2550| [TopLevelFunction] void constexpr_inconsistency(bool)
22703+
# 2550| <params>:
22704+
# 2550| getParameter(0): [Parameter] b
22705+
# 2550| Type = [BoolType] bool
22706+
# 2550| getEntryPoint(): [BlockStmt] { ... }
22707+
# 2551| getStmt(0): [ConstexprIfStmt] if constexpr (...) ...
22708+
# 2551| getInitialization(): [DeclStmt] declaration
22709+
# 2551| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a
22710+
# 2551| Type = [LValueReferenceType] const ClassWithDestructor &
22711+
# 2551| getVariable().getInitializer(): [Initializer] initializer for a
22712+
# 2551| getExpr(): [FunctionCall] call to getClassWithDestructor
22713+
# 2551| Type = [Class] ClassWithDestructor
22714+
# 2551| ValueCategory = prvalue
22715+
# 2551| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
22716+
# 2551| Type = [LValueReferenceType] const ClassWithDestructor &
22717+
# 2551| ValueCategory = prvalue
22718+
# 2551| getExpr(): [CStyleCast] (const ClassWithDestructor)...
22719+
# 2551| Conversion = [GlvalueConversion] glvalue conversion
22720+
# 2551| Type = [SpecifiedType] const ClassWithDestructor
22721+
# 2551| ValueCategory = lvalue
22722+
# 2551| getExpr(): [TemporaryObjectExpr] temporary object
22723+
# 2551| Type = [Class] ClassWithDestructor
22724+
# 2551| ValueCategory = lvalue
22725+
# 2551| getCondition(): [VariableAccess] initialization_with_destructor_bool
22726+
# 2551| Type = [BoolType] bool
22727+
# 2551| Value = [VariableAccess] 1
22728+
# 2551| ValueCategory = prvalue(load)
22729+
# 2552| getThen(): [EmptyStmt] ;
22730+
# 2552| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
22731+
# 2552| Type = [VoidType] void
22732+
# 2552| ValueCategory = prvalue
22733+
# 2552| getQualifier(): [ReuseExpr] reuse of temporary object
22734+
# 2552| Type = [Class] ClassWithDestructor
22735+
# 2552| ValueCategory = xvalue
22736+
# 2553| getStmt(1): [ReturnStmt] return ...
2266122737
perf-regression.cpp:
2266222738
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
2266322739
# 4| <params>:

cpp/ql/test/library-tests/ir/ir/aliased_ir.expected

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18251,6 +18251,90 @@ ir.cpp:
1825118251
# 2534| v2534_9(void) = ReturnVoid :
1825218252
#-----| Goto -> Block 1
1825318253

18254+
# 2545| void this_inconsistency(bool)
18255+
# 2545| Block 0
18256+
# 2545| v2545_1(void) = EnterFunction :
18257+
# 2545| m2545_2(unknown) = AliasedDefinition :
18258+
# 2545| m2545_3(unknown) = InitializeNonLocal :
18259+
# 2545| m2545_4(unknown) = Chi : total:m2545_2, partial:m2545_3
18260+
# 2545| r2545_5(glval<bool>) = VariableAddress[b] :
18261+
# 2545| m2545_6(bool) = InitializeParameter[b] : &:r2545_5
18262+
# 2546| r2546_1(glval<ClassWithDestructor &>) = VariableAddress[a] :
18263+
# 2546| r2546_2(glval<ClassWithDestructor>) = VariableAddress[#temp2546:38] :
18264+
# 2546| r2546_3(glval<unknown>) = FunctionAddress[getClassWithDestructor] :
18265+
# 2546| r2546_4(ClassWithDestructor) = Call[getClassWithDestructor] : func:r2546_3
18266+
# 2546| m2546_5(unknown) = ^CallSideEffect : ~m2545_4
18267+
# 2546| m2546_6(unknown) = Chi : total:m2545_4, partial:m2546_5
18268+
# 2546| m2546_7(ClassWithDestructor) = Store[#temp2546:38] : &:r2546_2, r2546_4
18269+
# 2546| m2546_8(unknown) = Chi : total:m2546_6, partial:m2546_7
18270+
# 2546| r2546_9(glval<ClassWithDestructor>) = Convert : r2546_2
18271+
# 2546| r2546_10(ClassWithDestructor &) = CopyValue : r2546_9
18272+
# 2546| m2546_11(ClassWithDestructor &) = Store[a] : &:r2546_1, r2546_10
18273+
# 2546| r2546_12(glval<ClassWithDestructor &>) = VariableAddress[a] :
18274+
# 2546| r2546_13(ClassWithDestructor &) = Load[a] : &:r2546_12, m2546_11
18275+
# 2546| r2546_14(ClassWithDestructor) = CopyValue : r2546_13
18276+
# 2546| r2546_15(glval<unknown>) = FunctionAddress[operator bool] :
18277+
# 2546| r2546_16(bool) = Call[operator bool] : func:r2546_15, this:r2546_14
18278+
# 2546| m2546_17(unknown) = ^CallSideEffect : ~m2546_8
18279+
# 2546| m2546_18(unknown) = Chi : total:m2546_8, partial:m2546_17
18280+
# 2546| v2546_19(void) = ^IndirectReadSideEffect[-1] : &:r2546_14, ~m2546_18
18281+
# 2546| r2546_20(bool) = CopyValue : r2546_16
18282+
# 2546| v2546_21(void) = ConditionalBranch : r2546_20
18283+
#-----| False -> Block 2
18284+
#-----| True -> Block 1
18285+
18286+
# 2547| Block 1
18287+
# 2547| v2547_1(void) = NoOp :
18288+
# 2547| r2547_2(glval<ClassWithDestructor>) = CopyValue : r2546_2
18289+
# 2547| r2547_3(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
18290+
# 2547| v2547_4(void) = Call[~ClassWithDestructor] : func:r2547_3, this:r2547_2
18291+
# 2547| m2547_5(unknown) = ^CallSideEffect : ~m2546_18
18292+
# 2547| m2547_6(unknown) = Chi : total:m2546_18, partial:m2547_5
18293+
# 2547| v2547_7(void) = ^IndirectReadSideEffect[-1] : &:r2547_2, ~m2547_6
18294+
# 2547| m2547_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2547_2
18295+
# 2547| m2547_9(unknown) = Chi : total:m2547_6, partial:m2547_8
18296+
#-----| Goto -> Block 2
18297+
18298+
# 2548| Block 2
18299+
# 2548| m2548_1(unknown) = Phi : from 0:~m2546_18, from 1:~m2547_9
18300+
# 2548| v2548_2(void) = NoOp :
18301+
# 2545| v2545_7(void) = ReturnVoid :
18302+
# 2545| v2545_8(void) = AliasedUse : ~m2548_1
18303+
# 2545| v2545_9(void) = ExitFunction :
18304+
18305+
# 2550| void constexpr_inconsistency(bool)
18306+
# 2550| Block 0
18307+
# 2550| v2550_1(void) = EnterFunction :
18308+
# 2550| m2550_2(unknown) = AliasedDefinition :
18309+
# 2550| m2550_3(unknown) = InitializeNonLocal :
18310+
# 2550| m2550_4(unknown) = Chi : total:m2550_2, partial:m2550_3
18311+
# 2550| r2550_5(glval<bool>) = VariableAddress[b] :
18312+
# 2550| m2550_6(bool) = InitializeParameter[b] : &:r2550_5
18313+
# 2551| r2551_1(glval<ClassWithDestructor &>) = VariableAddress[a] :
18314+
# 2551| r2551_2(glval<ClassWithDestructor>) = VariableAddress[#temp2551:48] :
18315+
# 2551| r2551_3(glval<unknown>) = FunctionAddress[getClassWithDestructor] :
18316+
# 2551| r2551_4(ClassWithDestructor) = Call[getClassWithDestructor] : func:r2551_3
18317+
# 2551| m2551_5(unknown) = ^CallSideEffect : ~m2550_4
18318+
# 2551| m2551_6(unknown) = Chi : total:m2550_4, partial:m2551_5
18319+
# 2551| m2551_7(ClassWithDestructor) = Store[#temp2551:48] : &:r2551_2, r2551_4
18320+
# 2551| r2551_8(glval<ClassWithDestructor>) = Convert : r2551_2
18321+
# 2551| r2551_9(ClassWithDestructor &) = CopyValue : r2551_8
18322+
# 2551| m2551_10(ClassWithDestructor &) = Store[a] : &:r2551_1, r2551_9
18323+
# 2551| r2551_11(bool) = Constant[1] :
18324+
# 2551| v2551_12(void) = ConditionalBranch : r2551_11
18325+
#-----| False -> Block 2
18326+
#-----| True -> Block 1
18327+
18328+
# 2552| Block 1
18329+
# 2552| v2552_1(void) = NoOp :
18330+
# 2553| v2553_1(void) = NoOp :
18331+
# 2550| v2550_7(void) = ReturnVoid :
18332+
# 2550| v2550_8(void) = AliasedUse : ~m2551_6
18333+
# 2550| v2550_9(void) = ExitFunction :
18334+
18335+
# 2550| Block 2
18336+
# 2550| v2550_10(void) = Unreached :
18337+
1825418338
perf-regression.cpp:
1825518339
# 6| void Big::Big()
1825618340
# 6| Block 0

cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ invalidOverlap
2727
nonUniqueEnclosingIRFunction
2828
fieldAddressOnNonPointer
2929
thisArgumentIsNonPointer
30+
| ir.cpp:2546:34:2546:34 | Call: call to operator bool | Call instruction 'Call: call to operator bool' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:2545:6:2545:23 | void this_inconsistency(bool) | void this_inconsistency(bool) |
3031
nonUniqueIRVariable
3132
| coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
3233
| coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |

cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ invalidOverlap
2727
nonUniqueEnclosingIRFunction
2828
fieldAddressOnNonPointer
2929
thisArgumentIsNonPointer
30+
| ir.cpp:2546:34:2546:34 | Call: call to operator bool | Call instruction 'Call: call to operator bool' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:2545:6:2545:23 | void this_inconsistency(bool) | void this_inconsistency(bool) |
3031
nonUniqueIRVariable
3132
| coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
3233
| coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |

cpp/ql/test/library-tests/ir/ir/ir.cpp

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2540,18 +2540,16 @@ void destructor_possibly_not_handled() {
25402540
}
25412541
}
25422542

2543-
// ClassWithDestructor getClassWithDestructor();
2543+
ClassWithDestructor getClassWithDestructor();
25442544

2545-
// void this_inconsistency(bool b) {
2546-
// if (const ClassWithDestructor& a = getClassWithDestructor())
2547-
// ;
2548-
// }
2549-
2550-
// constexpr bool initialization_with_destructor_bool = true;
2545+
void this_inconsistency(bool b) {
2546+
if (const ClassWithDestructor& a = getClassWithDestructor())
2547+
;
2548+
}
25512549

2552-
// void constexpr_inconsistency(bool b) {
2553-
// if constexpr (const ClassWithDestructor& a = getClassWithDestructor(); initialization_with_destructor_bool)
2554-
// ;
2555-
// }
2550+
void constexpr_inconsistency(bool b) {
2551+
if constexpr (const ClassWithDestructor& a = getClassWithDestructor(); initialization_with_destructor_bool)
2552+
;
2553+
}
25562554

25572555
// semmle-extractor-options: -std=c++20 --clang

cpp/ql/test/library-tests/ir/ir/raw_consistency.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ lostReachability
2121
backEdgeCountMismatch
2222
useNotDominatedByDefinition
2323
| ir.cpp:1535:8:1535:8 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | ir.cpp:1535:8:1535:8 | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() |
24+
| ir.cpp:2551:48:2551:71 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | ir.cpp:2550:6:2550:28 | void constexpr_inconsistency(bool) | void constexpr_inconsistency(bool) |
2425
| try_except.c:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:6:6:6:6 | void f() | void f() |
2526
| try_except.c:13:13:13:13 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:6:6:6:6 | void f() | void f() |
2627
| try_except.c:39:15:39:15 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | try_except.c:32:6:32:6 | void h(int) | void h(int) |
@@ -36,6 +37,7 @@ invalidOverlap
3637
nonUniqueEnclosingIRFunction
3738
fieldAddressOnNonPointer
3839
thisArgumentIsNonPointer
40+
| ir.cpp:2546:34:2546:34 | Call: call to operator bool | Call instruction 'Call: call to operator bool' has a `this` argument operand that is not an address, in function '$@'. | ir.cpp:2545:6:2545:23 | void this_inconsistency(bool) | void this_inconsistency(bool) |
3941
nonUniqueIRVariable
4042
| coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |
4143
| coroutines.cpp:87:20:87:20 | VariableAddress: (unnamed local variable) | Variable address instruction 'VariableAddress: (unnamed local variable)' has no associated variable, in function '$@'. | coroutines.cpp:87:20:87:33 | co_returnable_void co_return_void() | co_returnable_void co_return_void() |

0 commit comments

Comments
 (0)