C++: Add IR tests demonstrating some inconsistencies that may occur

This commit is contained in:
Jeroen Ketema
2024-05-08 11:43:58 +02:00
parent 2dcb55cc42
commit 6575927630
9 changed files with 259 additions and 11 deletions

View File

@@ -22658,6 +22658,82 @@ ir.cpp:
# 2541| getQualifier(): [VariableAccess] x
# 2541| Type = [Class] ClassWithDestructor
# 2541| ValueCategory = lvalue
# 2543| [TopLevelFunction] ClassWithDestructor getClassWithDestructor()
# 2543| <params>:
# 2545| [TopLevelFunction] void this_inconsistency(bool)
# 2545| <params>:
# 2545| getParameter(0): [Parameter] b
# 2545| Type = [BoolType] bool
# 2545| getEntryPoint(): [BlockStmt] { ... }
# 2546| getStmt(0): [IfStmt] if (...) ...
# 2546| getCondition(): [ConditionDeclExpr] (condition decl)
# 2546| Type = [BoolType] bool
# 2546| ValueCategory = prvalue
# 2546| getChild(0): [FunctionCall] call to operator bool
# 2546| Type = [BoolType] bool
# 2546| ValueCategory = prvalue
# 2546| getQualifier(): [VariableAccess] a
# 2546| Type = [LValueReferenceType] const ClassWithDestructor &
# 2546| ValueCategory = prvalue(load)
# 2546| getQualifier().getFullyConverted(): [ReferenceDereferenceExpr] (reference dereference)
# 2546| Type = [SpecifiedType] const ClassWithDestructor
# 2546| ValueCategory = prvalue(load)
# 2546| getInitializingExpr(): [FunctionCall] call to getClassWithDestructor
# 2546| Type = [Class] ClassWithDestructor
# 2546| ValueCategory = prvalue
# 2546| getInitializingExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
# 2546| Type = [LValueReferenceType] const ClassWithDestructor &
# 2546| ValueCategory = prvalue
# 2546| getExpr(): [CStyleCast] (const ClassWithDestructor)...
# 2546| Conversion = [GlvalueConversion] glvalue conversion
# 2546| Type = [SpecifiedType] const ClassWithDestructor
# 2546| ValueCategory = lvalue
# 2546| getExpr(): [TemporaryObjectExpr] temporary object
# 2546| Type = [Class] ClassWithDestructor
# 2546| ValueCategory = lvalue
# 2547| getThen(): [EmptyStmt] ;
# 2547| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
# 2547| Type = [VoidType] void
# 2547| ValueCategory = prvalue
# 2547| getQualifier(): [ReuseExpr] reuse of temporary object
# 2547| Type = [Class] ClassWithDestructor
# 2547| ValueCategory = xvalue
# 2548| getStmt(1): [ReturnStmt] return ...
# 2550| [TopLevelFunction] void constexpr_inconsistency(bool)
# 2550| <params>:
# 2550| getParameter(0): [Parameter] b
# 2550| Type = [BoolType] bool
# 2550| getEntryPoint(): [BlockStmt] { ... }
# 2551| getStmt(0): [ConstexprIfStmt] if constexpr (...) ...
# 2551| getInitialization(): [DeclStmt] declaration
# 2551| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a
# 2551| Type = [LValueReferenceType] const ClassWithDestructor &
# 2551| getVariable().getInitializer(): [Initializer] initializer for a
# 2551| getExpr(): [FunctionCall] call to getClassWithDestructor
# 2551| Type = [Class] ClassWithDestructor
# 2551| ValueCategory = prvalue
# 2551| getExpr().getFullyConverted(): [ReferenceToExpr] (reference to)
# 2551| Type = [LValueReferenceType] const ClassWithDestructor &
# 2551| ValueCategory = prvalue
# 2551| getExpr(): [CStyleCast] (const ClassWithDestructor)...
# 2551| Conversion = [GlvalueConversion] glvalue conversion
# 2551| Type = [SpecifiedType] const ClassWithDestructor
# 2551| ValueCategory = lvalue
# 2551| getExpr(): [TemporaryObjectExpr] temporary object
# 2551| Type = [Class] ClassWithDestructor
# 2551| ValueCategory = lvalue
# 2551| getCondition(): [VariableAccess] initialization_with_destructor_bool
# 2551| Type = [BoolType] bool
# 2551| Value = [VariableAccess] 1
# 2551| ValueCategory = prvalue(load)
# 2552| getThen(): [EmptyStmt] ;
# 2552| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
# 2552| Type = [VoidType] void
# 2552| ValueCategory = prvalue
# 2552| getQualifier(): [ReuseExpr] reuse of temporary object
# 2552| Type = [Class] ClassWithDestructor
# 2552| ValueCategory = xvalue
# 2553| getStmt(1): [ReturnStmt] return ...
perf-regression.cpp:
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
# 4| <params>:

View File

@@ -18251,6 +18251,90 @@ ir.cpp:
# 2534| v2534_9(void) = ReturnVoid :
#-----| Goto -> Block 1
# 2545| void this_inconsistency(bool)
# 2545| Block 0
# 2545| v2545_1(void) = EnterFunction :
# 2545| m2545_2(unknown) = AliasedDefinition :
# 2545| m2545_3(unknown) = InitializeNonLocal :
# 2545| m2545_4(unknown) = Chi : total:m2545_2, partial:m2545_3
# 2545| r2545_5(glval<bool>) = VariableAddress[b] :
# 2545| m2545_6(bool) = InitializeParameter[b] : &:r2545_5
# 2546| r2546_1(glval<ClassWithDestructor &>) = VariableAddress[a] :
# 2546| r2546_2(glval<ClassWithDestructor>) = VariableAddress[#temp2546:38] :
# 2546| r2546_3(glval<unknown>) = FunctionAddress[getClassWithDestructor] :
# 2546| r2546_4(ClassWithDestructor) = Call[getClassWithDestructor] : func:r2546_3
# 2546| m2546_5(unknown) = ^CallSideEffect : ~m2545_4
# 2546| m2546_6(unknown) = Chi : total:m2545_4, partial:m2546_5
# 2546| m2546_7(ClassWithDestructor) = Store[#temp2546:38] : &:r2546_2, r2546_4
# 2546| m2546_8(unknown) = Chi : total:m2546_6, partial:m2546_7
# 2546| r2546_9(glval<ClassWithDestructor>) = Convert : r2546_2
# 2546| r2546_10(ClassWithDestructor &) = CopyValue : r2546_9
# 2546| m2546_11(ClassWithDestructor &) = Store[a] : &:r2546_1, r2546_10
# 2546| r2546_12(glval<ClassWithDestructor &>) = VariableAddress[a] :
# 2546| r2546_13(ClassWithDestructor &) = Load[a] : &:r2546_12, m2546_11
# 2546| r2546_14(ClassWithDestructor) = CopyValue : r2546_13
# 2546| r2546_15(glval<unknown>) = FunctionAddress[operator bool] :
# 2546| r2546_16(bool) = Call[operator bool] : func:r2546_15, this:r2546_14
# 2546| m2546_17(unknown) = ^CallSideEffect : ~m2546_8
# 2546| m2546_18(unknown) = Chi : total:m2546_8, partial:m2546_17
# 2546| v2546_19(void) = ^IndirectReadSideEffect[-1] : &:r2546_14, ~m2546_18
# 2546| r2546_20(bool) = CopyValue : r2546_16
# 2546| v2546_21(void) = ConditionalBranch : r2546_20
#-----| False -> Block 2
#-----| True -> Block 1
# 2547| Block 1
# 2547| v2547_1(void) = NoOp :
# 2547| r2547_2(glval<ClassWithDestructor>) = CopyValue : r2546_2
# 2547| r2547_3(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2547| v2547_4(void) = Call[~ClassWithDestructor] : func:r2547_3, this:r2547_2
# 2547| m2547_5(unknown) = ^CallSideEffect : ~m2546_18
# 2547| m2547_6(unknown) = Chi : total:m2546_18, partial:m2547_5
# 2547| v2547_7(void) = ^IndirectReadSideEffect[-1] : &:r2547_2, ~m2547_6
# 2547| m2547_8(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2547_2
# 2547| m2547_9(unknown) = Chi : total:m2547_6, partial:m2547_8
#-----| Goto -> Block 2
# 2548| Block 2
# 2548| m2548_1(unknown) = Phi : from 0:~m2546_18, from 1:~m2547_9
# 2548| v2548_2(void) = NoOp :
# 2545| v2545_7(void) = ReturnVoid :
# 2545| v2545_8(void) = AliasedUse : ~m2548_1
# 2545| v2545_9(void) = ExitFunction :
# 2550| void constexpr_inconsistency(bool)
# 2550| Block 0
# 2550| v2550_1(void) = EnterFunction :
# 2550| m2550_2(unknown) = AliasedDefinition :
# 2550| m2550_3(unknown) = InitializeNonLocal :
# 2550| m2550_4(unknown) = Chi : total:m2550_2, partial:m2550_3
# 2550| r2550_5(glval<bool>) = VariableAddress[b] :
# 2550| m2550_6(bool) = InitializeParameter[b] : &:r2550_5
# 2551| r2551_1(glval<ClassWithDestructor &>) = VariableAddress[a] :
# 2551| r2551_2(glval<ClassWithDestructor>) = VariableAddress[#temp2551:48] :
# 2551| r2551_3(glval<unknown>) = FunctionAddress[getClassWithDestructor] :
# 2551| r2551_4(ClassWithDestructor) = Call[getClassWithDestructor] : func:r2551_3
# 2551| m2551_5(unknown) = ^CallSideEffect : ~m2550_4
# 2551| m2551_6(unknown) = Chi : total:m2550_4, partial:m2551_5
# 2551| m2551_7(ClassWithDestructor) = Store[#temp2551:48] : &:r2551_2, r2551_4
# 2551| r2551_8(glval<ClassWithDestructor>) = Convert : r2551_2
# 2551| r2551_9(ClassWithDestructor &) = CopyValue : r2551_8
# 2551| m2551_10(ClassWithDestructor &) = Store[a] : &:r2551_1, r2551_9
# 2551| r2551_11(bool) = Constant[1] :
# 2551| v2551_12(void) = ConditionalBranch : r2551_11
#-----| False -> Block 2
#-----| True -> Block 1
# 2552| Block 1
# 2552| v2552_1(void) = NoOp :
# 2553| v2553_1(void) = NoOp :
# 2550| v2550_7(void) = ReturnVoid :
# 2550| v2550_8(void) = AliasedUse : ~m2551_6
# 2550| v2550_9(void) = ExitFunction :
# 2550| Block 2
# 2550| v2550_10(void) = Unreached :
perf-regression.cpp:
# 6| void Big::Big()
# 6| Block 0

View File

@@ -27,6 +27,7 @@ invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
thisArgumentIsNonPointer
| 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) |
nonUniqueIRVariable
| 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() |
| 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() |

View File

@@ -27,6 +27,7 @@ invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
thisArgumentIsNonPointer
| 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) |
nonUniqueIRVariable
| 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() |
| 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() |

View File

@@ -2540,18 +2540,16 @@ void destructor_possibly_not_handled() {
}
}
// ClassWithDestructor getClassWithDestructor();
ClassWithDestructor getClassWithDestructor();
// void this_inconsistency(bool b) {
// if (const ClassWithDestructor& a = getClassWithDestructor())
// ;
// }
void this_inconsistency(bool b) {
if (const ClassWithDestructor& a = getClassWithDestructor())
;
}
// constexpr bool initialization_with_destructor_bool = true;
// void constexpr_inconsistency(bool b) {
// if constexpr (const ClassWithDestructor& a = getClassWithDestructor(); initialization_with_destructor_bool)
// ;
// }
void constexpr_inconsistency(bool b) {
if constexpr (const ClassWithDestructor& a = getClassWithDestructor(); initialization_with_destructor_bool)
;
}
// semmle-extractor-options: -std=c++20 --clang

View File

@@ -21,6 +21,7 @@ lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
| 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() |
| 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) |
| 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() |
| 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() |
| 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
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
thisArgumentIsNonPointer
| 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) |
nonUniqueIRVariable
| 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() |
| 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() |

View File

@@ -16615,6 +16615,90 @@ ir.cpp:
# 2534| v2534_7(void) = ReturnVoid :
#-----| Goto -> Block 1
# 2545| void this_inconsistency(bool)
# 2545| Block 0
# 2545| v2545_1(void) = EnterFunction :
# 2545| mu2545_2(unknown) = AliasedDefinition :
# 2545| mu2545_3(unknown) = InitializeNonLocal :
# 2545| r2545_4(glval<bool>) = VariableAddress[b] :
# 2545| mu2545_5(bool) = InitializeParameter[b] : &:r2545_4
# 2546| r2546_1(glval<ClassWithDestructor &>) = VariableAddress[a] :
# 2546| r2546_2(glval<ClassWithDestructor>) = VariableAddress[#temp2546:38] :
# 2546| r2546_3(glval<unknown>) = FunctionAddress[getClassWithDestructor] :
# 2546| r2546_4(ClassWithDestructor) = Call[getClassWithDestructor] : func:r2546_3
# 2546| mu2546_5(unknown) = ^CallSideEffect : ~m?
# 2546| mu2546_6(ClassWithDestructor) = Store[#temp2546:38] : &:r2546_2, r2546_4
# 2546| r2546_7(glval<ClassWithDestructor>) = Convert : r2546_2
# 2546| r2546_8(ClassWithDestructor &) = CopyValue : r2546_7
# 2546| mu2546_9(ClassWithDestructor &) = Store[a] : &:r2546_1, r2546_8
# 2546| r2546_10(glval<ClassWithDestructor &>) = VariableAddress[a] :
# 2546| r2546_11(ClassWithDestructor &) = Load[a] : &:r2546_10, ~m?
# 2546| r2546_12(ClassWithDestructor) = CopyValue : r2546_11
# 2546| r2546_13(glval<unknown>) = FunctionAddress[operator bool] :
# 2546| r2546_14(bool) = Call[operator bool] : func:r2546_13, this:r2546_12
# 2546| mu2546_15(unknown) = ^CallSideEffect : ~m?
# 2546| v2546_16(void) = ^IndirectReadSideEffect[-1] : &:r2546_12, ~m?
# 2546| r2546_17(bool) = CopyValue : r2546_14
# 2546| v2546_18(void) = ConditionalBranch : r2546_17
#-----| False -> Block 2
#-----| True -> Block 1
# 2547| Block 1
# 2547| v2547_1(void) = NoOp :
# 2547| r2547_2(glval<ClassWithDestructor>) = CopyValue : r2546_2
# 2547| r2547_3(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2547| v2547_4(void) = Call[~ClassWithDestructor] : func:r2547_3, this:r2547_2
# 2547| mu2547_5(unknown) = ^CallSideEffect : ~m?
# 2547| v2547_6(void) = ^IndirectReadSideEffect[-1] : &:r2547_2, ~m?
# 2547| mu2547_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2547_2
#-----| Goto -> Block 2
# 2548| Block 2
# 2548| v2548_1(void) = NoOp :
# 2545| v2545_6(void) = ReturnVoid :
# 2545| v2545_7(void) = AliasedUse : ~m?
# 2545| v2545_8(void) = ExitFunction :
# 2550| void constexpr_inconsistency(bool)
# 2550| Block 0
# 2550| v2550_1(void) = EnterFunction :
# 2550| mu2550_2(unknown) = AliasedDefinition :
# 2550| mu2550_3(unknown) = InitializeNonLocal :
# 2550| r2550_4(glval<bool>) = VariableAddress[b] :
# 2550| mu2550_5(bool) = InitializeParameter[b] : &:r2550_4
# 2551| r2551_1(glval<ClassWithDestructor &>) = VariableAddress[a] :
# 2551| r2551_2(glval<ClassWithDestructor>) = VariableAddress[#temp2551:48] :
# 2551| r2551_3(glval<unknown>) = FunctionAddress[getClassWithDestructor] :
# 2551| r2551_4(ClassWithDestructor) = Call[getClassWithDestructor] : func:r2551_3
# 2551| mu2551_5(unknown) = ^CallSideEffect : ~m?
# 2551| mu2551_6(ClassWithDestructor) = Store[#temp2551:48] : &:r2551_2, r2551_4
# 2551| r2551_7(glval<ClassWithDestructor>) = Convert : r2551_2
# 2551| r2551_8(ClassWithDestructor &) = CopyValue : r2551_7
# 2551| mu2551_9(ClassWithDestructor &) = Store[a] : &:r2551_1, r2551_8
# 2551| r2551_10(bool) = Constant[1] :
# 2551| v2551_11(void) = ConditionalBranch : r2551_10
#-----| False -> Block 3
#-----| True -> Block 1
# 2552| Block 1
# 2552| v2552_1(void) = NoOp :
#-----| Goto -> Block 3
# 2552| Block 2
# 2552| r2552_2(glval<ClassWithDestructor>) = CopyValue : r2551_2
# 2552| r2552_3(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
# 2552| v2552_4(void) = Call[~ClassWithDestructor] : func:r2552_3, this:r2552_2
# 2552| mu2552_5(unknown) = ^CallSideEffect : ~m?
# 2552| v2552_6(void) = ^IndirectReadSideEffect[-1] : &:r2552_2, ~m?
# 2552| mu2552_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2552_2
#-----| Goto -> Block 3
# 2553| Block 3
# 2553| v2553_1(void) = NoOp :
# 2550| v2550_6(void) = ReturnVoid :
# 2550| v2550_7(void) = AliasedUse : ~m?
# 2550| v2550_8(void) = ExitFunction :
perf-regression.cpp:
# 6| void Big::Big()
# 6| Block 0

View File

@@ -27,6 +27,7 @@ invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
thisArgumentIsNonPointer
| 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) |
nonUniqueIRVariable
| 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() |
| 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() |

View File

@@ -27,6 +27,7 @@ invalidOverlap
nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
thisArgumentIsNonPointer
| 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) |
nonUniqueIRVariable
| 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() |
| 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() |