mirror of
https://github.com/github/codeql.git
synced 2026-04-27 01:35:13 +02:00
Merge pull request #16366 from MathiasVP/fix-ir-for-destructors-in-switch
C++: Fix IR destructor calls on `JumpStmt`s
This commit is contained in:
@@ -1276,6 +1276,11 @@ class TranslatedJumpStmt extends TranslatedStmt {
|
||||
override JumpStmt stmt;
|
||||
|
||||
override Instruction getFirstInstruction(EdgeKind kind) {
|
||||
// The first instruction is a destructor call, if any.
|
||||
result = this.getChildInternal(0).getFirstInstruction(kind)
|
||||
or
|
||||
// Otherwise, the first (and only) instruction is a `NoOp`
|
||||
not exists(this.getChildInternal(0)) and
|
||||
result = this.getInstruction(OnlyInstructionTag()) and
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
@@ -1284,7 +1289,20 @@ class TranslatedJumpStmt extends TranslatedStmt {
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
}
|
||||
|
||||
override TranslatedElement getChildInternal(int id) { none() }
|
||||
private TranslatedCall getTranslatedImplicitDestructorCall(int id) {
|
||||
result.getExpr() = stmt.getImplicitDestructorCall(id)
|
||||
}
|
||||
|
||||
override TranslatedElement getLastChild() {
|
||||
result =
|
||||
this.getTranslatedImplicitDestructorCall(max(int id |
|
||||
exists(stmt.getImplicitDestructorCall(id))
|
||||
))
|
||||
}
|
||||
|
||||
override TranslatedElement getChildInternal(int id) {
|
||||
result = this.getTranslatedImplicitDestructorCall(id)
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) {
|
||||
tag = OnlyInstructionTag() and
|
||||
@@ -1297,7 +1315,19 @@ class TranslatedJumpStmt extends TranslatedStmt {
|
||||
result = getTranslatedStmt(stmt.getTarget()).getFirstInstruction(kind)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { none() }
|
||||
final override predicate handlesDestructorsExplicitly() { any() }
|
||||
|
||||
override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
|
||||
exists(int id | child = this.getChildInternal(id) |
|
||||
// Transition to the next destructor call, if any.
|
||||
result = this.getChildInternal(id + 1).getFirstInstruction(kind)
|
||||
or
|
||||
// And otherwise, exit this element by flowing to the target of the jump.
|
||||
not exists(this.getChildInternal(id + 1)) and
|
||||
kind instanceof GotoEdge and
|
||||
result = this.getInstruction(OnlyInstructionTag())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private EdgeKind getCaseEdge(SwitchCase switchCase) {
|
||||
|
||||
@@ -22442,6 +22442,139 @@ ir.cpp:
|
||||
#-----| Type = [Class] ClassWithDestructor
|
||||
#-----| ValueCategory = lvalue
|
||||
# 2499| getStmt(4): [ReturnStmt] return ...
|
||||
# 2501| [TopLevelFunction] void destruction_in_switch_1(int)
|
||||
# 2501| <params>:
|
||||
# 2501| getParameter(0): [Parameter] c
|
||||
# 2501| Type = [IntType] int
|
||||
# 2501| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2502| getStmt(0): [SwitchStmt] switch (...) ...
|
||||
# 2502| getExpr(): [VariableAccess] c
|
||||
# 2502| Type = [IntType] int
|
||||
# 2502| ValueCategory = prvalue(load)
|
||||
# 2502| getStmt(): [BlockStmt] { ... }
|
||||
# 2503| getStmt(0): [SwitchCase] case ...:
|
||||
# 2503| getExpr(): [Literal] 0
|
||||
# 2503| Type = [IntType] int
|
||||
# 2503| Value = [Literal] 0
|
||||
# 2503| ValueCategory = prvalue
|
||||
# 2503| getStmt(1): [BlockStmt] { ... }
|
||||
# 2504| getStmt(0): [DeclStmt] declaration
|
||||
# 2504| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
|
||||
# 2504| Type = [Class] ClassWithDestructor
|
||||
# 2504| getVariable().getInitializer(): [Initializer] initializer for x
|
||||
# 2504| getExpr(): [ConstructorCall] call to ClassWithDestructor
|
||||
# 2504| Type = [VoidType] void
|
||||
# 2504| ValueCategory = prvalue
|
||||
# 2505| getStmt(1): [BreakStmt] break;
|
||||
# 2506| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
|
||||
# 2506| Type = [VoidType] void
|
||||
# 2506| ValueCategory = prvalue
|
||||
# 2506| getQualifier(): [VariableAccess] x
|
||||
# 2506| Type = [Class] ClassWithDestructor
|
||||
# 2506| ValueCategory = lvalue
|
||||
# 2506| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
|
||||
# 2506| Type = [VoidType] void
|
||||
# 2506| ValueCategory = prvalue
|
||||
# 2506| getQualifier(): [VariableAccess] x
|
||||
# 2506| Type = [Class] ClassWithDestructor
|
||||
# 2506| ValueCategory = lvalue
|
||||
# 2507| getStmt(1): [LabelStmt] label ...:
|
||||
# 2508| getStmt(2): [ReturnStmt] return ...
|
||||
# 2510| [TopLevelFunction] void destruction_in_switch_2(int)
|
||||
# 2510| <params>:
|
||||
# 2510| getParameter(0): [Parameter] c
|
||||
# 2510| Type = [IntType] int
|
||||
# 2510| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2511| getStmt(0): [SwitchStmt] switch (...) ...
|
||||
# 2511| getInitialization(): [DeclStmt] declaration
|
||||
# 2511| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
|
||||
# 2511| Type = [Class] ClassWithDestructor
|
||||
# 2511| getVariable().getInitializer(): [Initializer] initializer for y
|
||||
# 2511| getExpr(): [ConstructorCall] call to ClassWithDestructor
|
||||
# 2511| Type = [VoidType] void
|
||||
# 2511| ValueCategory = prvalue
|
||||
# 2511| getExpr(): [VariableAccess] c
|
||||
# 2511| Type = [IntType] int
|
||||
# 2511| ValueCategory = prvalue(load)
|
||||
# 2511| getStmt(): [BlockStmt] { ... }
|
||||
# 2512| getStmt(0): [SwitchCase] case ...:
|
||||
# 2512| getExpr(): [Literal] 0
|
||||
# 2512| Type = [IntType] int
|
||||
# 2512| Value = [Literal] 0
|
||||
# 2512| ValueCategory = prvalue
|
||||
# 2512| getStmt(1): [BlockStmt] { ... }
|
||||
# 2513| getStmt(0): [BreakStmt] break;
|
||||
# 2515| getStmt(2): [SwitchCase] default:
|
||||
# 2515| getStmt(3): [BlockStmt] { ... }
|
||||
# 2516| getStmt(0): [BreakStmt] break;
|
||||
# 2518| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
|
||||
# 2518| Type = [VoidType] void
|
||||
# 2518| ValueCategory = prvalue
|
||||
# 2518| getQualifier(): [VariableAccess] y
|
||||
# 2518| Type = [Class] ClassWithDestructor
|
||||
# 2518| ValueCategory = lvalue
|
||||
# 2518| getStmt(1): [LabelStmt] label ...:
|
||||
# 2519| getStmt(2): [ReturnStmt] return ...
|
||||
# 2521| [TopLevelFunction] void destruction_in_switch_3(int)
|
||||
# 2521| <params>:
|
||||
# 2521| getParameter(0): [Parameter] c
|
||||
# 2521| Type = [IntType] int
|
||||
# 2521| getEntryPoint(): [BlockStmt] { ... }
|
||||
# 2522| getStmt(0): [SwitchStmt] switch (...) ...
|
||||
# 2522| getInitialization(): [DeclStmt] declaration
|
||||
# 2522| getDeclarationEntry(0): [VariableDeclarationEntry] definition of y
|
||||
# 2522| Type = [Class] ClassWithDestructor
|
||||
# 2522| getVariable().getInitializer(): [Initializer] initializer for y
|
||||
# 2522| getExpr(): [ConstructorCall] call to ClassWithDestructor
|
||||
# 2522| Type = [VoidType] void
|
||||
# 2522| ValueCategory = prvalue
|
||||
# 2522| getExpr(): [VariableAccess] c
|
||||
# 2522| Type = [IntType] int
|
||||
# 2522| ValueCategory = prvalue(load)
|
||||
# 2522| getStmt(): [BlockStmt] { ... }
|
||||
# 2523| getStmt(0): [SwitchCase] case ...:
|
||||
# 2523| getExpr(): [Literal] 0
|
||||
# 2523| Type = [IntType] int
|
||||
# 2523| Value = [Literal] 0
|
||||
# 2523| ValueCategory = prvalue
|
||||
# 2523| getStmt(1): [BlockStmt] { ... }
|
||||
# 2524| getStmt(0): [DeclStmt] declaration
|
||||
# 2524| getDeclarationEntry(0): [VariableDeclarationEntry] definition of x
|
||||
# 2524| Type = [Class] ClassWithDestructor
|
||||
# 2524| getVariable().getInitializer(): [Initializer] initializer for x
|
||||
# 2524| getExpr(): [ConstructorCall] call to ClassWithDestructor
|
||||
# 2524| Type = [VoidType] void
|
||||
# 2524| ValueCategory = prvalue
|
||||
# 2525| getStmt(1): [BreakStmt] break;
|
||||
# 2526| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
|
||||
# 2526| Type = [VoidType] void
|
||||
# 2526| ValueCategory = prvalue
|
||||
# 2526| getQualifier(): [VariableAccess] x
|
||||
# 2526| Type = [Class] ClassWithDestructor
|
||||
# 2526| ValueCategory = lvalue
|
||||
# 2530| getImplicitDestructorCall(1): [DestructorCall] call to ~ClassWithDestructor
|
||||
# 2530| Type = [VoidType] void
|
||||
# 2530| ValueCategory = prvalue
|
||||
# 2530| getQualifier(): [VariableAccess] y
|
||||
# 2530| Type = [Class] ClassWithDestructor
|
||||
# 2530| ValueCategory = lvalue
|
||||
# 2526| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
|
||||
# 2526| Type = [VoidType] void
|
||||
# 2526| ValueCategory = prvalue
|
||||
# 2526| getQualifier(): [VariableAccess] x
|
||||
# 2526| Type = [Class] ClassWithDestructor
|
||||
# 2526| ValueCategory = lvalue
|
||||
# 2527| getStmt(2): [SwitchCase] default:
|
||||
# 2527| getStmt(3): [BlockStmt] { ... }
|
||||
# 2528| getStmt(0): [BreakStmt] break;
|
||||
# 2530| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
|
||||
# 2530| Type = [VoidType] void
|
||||
# 2530| ValueCategory = prvalue
|
||||
# 2530| getQualifier(): [VariableAccess] y
|
||||
# 2530| Type = [Class] ClassWithDestructor
|
||||
# 2530| ValueCategory = lvalue
|
||||
# 2530| getStmt(1): [LabelStmt] label ...:
|
||||
# 2531| getStmt(2): [ReturnStmt] return ...
|
||||
perf-regression.cpp:
|
||||
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
|
||||
# 4| <params>:
|
||||
|
||||
@@ -17958,6 +17958,152 @@ ir.cpp:
|
||||
# 2484| v2484_8(void) = AliasedUse : ~m2497_4
|
||||
# 2484| v2484_9(void) = ExitFunction :
|
||||
|
||||
# 2501| void destruction_in_switch_1(int)
|
||||
# 2501| Block 0
|
||||
# 2501| v2501_1(void) = EnterFunction :
|
||||
# 2501| m2501_2(unknown) = AliasedDefinition :
|
||||
# 2501| m2501_3(unknown) = InitializeNonLocal :
|
||||
# 2501| m2501_4(unknown) = Chi : total:m2501_2, partial:m2501_3
|
||||
# 2501| r2501_5(glval<int>) = VariableAddress[c] :
|
||||
# 2501| m2501_6(int) = InitializeParameter[c] : &:r2501_5
|
||||
# 2502| r2502_1(glval<int>) = VariableAddress[c] :
|
||||
# 2502| r2502_2(int) = Load[c] : &:r2502_1, m2501_6
|
||||
# 2502| v2502_3(void) = Switch : r2502_2
|
||||
#-----| Case[0] -> Block 1
|
||||
#-----| Default -> Block 2
|
||||
|
||||
# 2503| Block 1
|
||||
# 2503| v2503_1(void) = NoOp :
|
||||
# 2504| r2504_1(glval<ClassWithDestructor>) = VariableAddress[x] :
|
||||
# 2504| m2504_2(ClassWithDestructor) = Uninitialized[x] : &:r2504_1
|
||||
# 2504| r2504_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
|
||||
# 2504| v2504_4(void) = Call[ClassWithDestructor] : func:r2504_3, this:r2504_1
|
||||
# 2504| m2504_5(unknown) = ^CallSideEffect : ~m2501_4
|
||||
# 2504| m2504_6(unknown) = Chi : total:m2501_4, partial:m2504_5
|
||||
# 2504| m2504_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2504_1
|
||||
# 2504| m2504_8(ClassWithDestructor) = Chi : total:m2504_2, partial:m2504_7
|
||||
# 2506| r2506_1(glval<ClassWithDestructor>) = VariableAddress[x] :
|
||||
# 2506| r2506_2(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
|
||||
# 2506| v2506_3(void) = Call[~ClassWithDestructor] : func:r2506_2, this:r2506_1
|
||||
# 2506| m2506_4(unknown) = ^CallSideEffect : ~m2504_6
|
||||
# 2506| m2506_5(unknown) = Chi : total:m2504_6, partial:m2506_4
|
||||
# 2506| v2506_6(void) = ^IndirectReadSideEffect[-1] : &:r2506_1, m2504_8
|
||||
# 2506| m2506_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_1
|
||||
# 2506| m2506_8(ClassWithDestructor) = Chi : total:m2504_8, partial:m2506_7
|
||||
# 2505| v2505_1(void) = NoOp :
|
||||
#-----| Goto -> Block 2
|
||||
|
||||
# 2507| Block 2
|
||||
# 2507| m2507_1(unknown) = Phi : from 0:~m2501_4, from 1:~m2506_5
|
||||
# 2507| v2507_2(void) = NoOp :
|
||||
# 2508| v2508_1(void) = NoOp :
|
||||
# 2501| v2501_7(void) = ReturnVoid :
|
||||
# 2501| v2501_8(void) = AliasedUse : ~m2507_1
|
||||
# 2501| v2501_9(void) = ExitFunction :
|
||||
|
||||
# 2510| void destruction_in_switch_2(int)
|
||||
# 2510| Block 0
|
||||
# 2510| v2510_1(void) = EnterFunction :
|
||||
# 2510| m2510_2(unknown) = AliasedDefinition :
|
||||
# 2510| m2510_3(unknown) = InitializeNonLocal :
|
||||
# 2510| m2510_4(unknown) = Chi : total:m2510_2, partial:m2510_3
|
||||
# 2510| r2510_5(glval<int>) = VariableAddress[c] :
|
||||
# 2510| m2510_6(int) = InitializeParameter[c] : &:r2510_5
|
||||
# 2511| r2511_1(glval<ClassWithDestructor>) = VariableAddress[y] :
|
||||
# 2511| m2511_2(ClassWithDestructor) = Uninitialized[y] : &:r2511_1
|
||||
# 2511| r2511_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
|
||||
# 2511| v2511_4(void) = Call[ClassWithDestructor] : func:r2511_3, this:r2511_1
|
||||
# 2511| m2511_5(unknown) = ^CallSideEffect : ~m2510_4
|
||||
# 2511| m2511_6(unknown) = Chi : total:m2510_4, partial:m2511_5
|
||||
# 2511| m2511_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2511_1
|
||||
# 2511| m2511_8(ClassWithDestructor) = Chi : total:m2511_2, partial:m2511_7
|
||||
# 2511| r2511_9(glval<int>) = VariableAddress[c] :
|
||||
# 2511| r2511_10(int) = Load[c] : &:r2511_9, m2510_6
|
||||
# 2511| v2511_11(void) = Switch : r2511_10
|
||||
#-----| Case[0] -> Block 1
|
||||
#-----| Default -> Block 2
|
||||
|
||||
# 2512| Block 1
|
||||
# 2512| v2512_1(void) = NoOp :
|
||||
# 2513| v2513_1(void) = NoOp :
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2515| Block 2
|
||||
# 2515| v2515_1(void) = NoOp :
|
||||
# 2516| v2516_1(void) = NoOp :
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2518| Block 3
|
||||
# 2518| v2518_1(void) = NoOp :
|
||||
# 2519| v2519_1(void) = NoOp :
|
||||
# 2510| v2510_7(void) = ReturnVoid :
|
||||
# 2510| v2510_8(void) = AliasedUse : ~m2511_6
|
||||
# 2510| v2510_9(void) = ExitFunction :
|
||||
|
||||
# 2521| void destruction_in_switch_3(int)
|
||||
# 2521| Block 0
|
||||
# 2521| v2521_1(void) = EnterFunction :
|
||||
# 2521| m2521_2(unknown) = AliasedDefinition :
|
||||
# 2521| m2521_3(unknown) = InitializeNonLocal :
|
||||
# 2521| m2521_4(unknown) = Chi : total:m2521_2, partial:m2521_3
|
||||
# 2521| r2521_5(glval<int>) = VariableAddress[c] :
|
||||
# 2521| m2521_6(int) = InitializeParameter[c] : &:r2521_5
|
||||
# 2522| r2522_1(glval<ClassWithDestructor>) = VariableAddress[y] :
|
||||
# 2522| m2522_2(ClassWithDestructor) = Uninitialized[y] : &:r2522_1
|
||||
# 2522| r2522_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
|
||||
# 2522| v2522_4(void) = Call[ClassWithDestructor] : func:r2522_3, this:r2522_1
|
||||
# 2522| m2522_5(unknown) = ^CallSideEffect : ~m2521_4
|
||||
# 2522| m2522_6(unknown) = Chi : total:m2521_4, partial:m2522_5
|
||||
# 2522| m2522_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2522_1
|
||||
# 2522| m2522_8(ClassWithDestructor) = Chi : total:m2522_2, partial:m2522_7
|
||||
# 2522| r2522_9(glval<int>) = VariableAddress[c] :
|
||||
# 2522| r2522_10(int) = Load[c] : &:r2522_9, m2521_6
|
||||
# 2522| v2522_11(void) = Switch : r2522_10
|
||||
#-----| Case[0] -> Block 1
|
||||
#-----| Default -> Block 2
|
||||
|
||||
# 2523| Block 1
|
||||
# 2523| v2523_1(void) = NoOp :
|
||||
# 2524| r2524_1(glval<ClassWithDestructor>) = VariableAddress[x] :
|
||||
# 2524| m2524_2(ClassWithDestructor) = Uninitialized[x] : &:r2524_1
|
||||
# 2524| r2524_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
|
||||
# 2524| v2524_4(void) = Call[ClassWithDestructor] : func:r2524_3, this:r2524_1
|
||||
# 2524| m2524_5(unknown) = ^CallSideEffect : ~m2522_6
|
||||
# 2524| m2524_6(unknown) = Chi : total:m2522_6, partial:m2524_5
|
||||
# 2524| m2524_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2524_1
|
||||
# 2524| m2524_8(ClassWithDestructor) = Chi : total:m2524_2, partial:m2524_7
|
||||
# 2526| r2526_1(glval<ClassWithDestructor>) = VariableAddress[x] :
|
||||
# 2526| r2526_2(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
|
||||
# 2526| v2526_3(void) = Call[~ClassWithDestructor] : func:r2526_2, this:r2526_1
|
||||
# 2526| m2526_4(unknown) = ^CallSideEffect : ~m2524_6
|
||||
# 2526| m2526_5(unknown) = Chi : total:m2524_6, partial:m2526_4
|
||||
# 2526| v2526_6(void) = ^IndirectReadSideEffect[-1] : &:r2526_1, m2524_8
|
||||
# 2526| m2526_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2526_1
|
||||
# 2526| m2526_8(ClassWithDestructor) = Chi : total:m2524_8, partial:m2526_7
|
||||
# 2530| r2530_1(glval<ClassWithDestructor>) = VariableAddress[y] :
|
||||
# 2530| r2530_2(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
|
||||
# 2530| v2530_3(void) = Call[~ClassWithDestructor] : func:r2530_2, this:r2530_1
|
||||
# 2530| m2530_4(unknown) = ^CallSideEffect : ~m2526_5
|
||||
# 2530| m2530_5(unknown) = Chi : total:m2526_5, partial:m2530_4
|
||||
# 2530| v2530_6(void) = ^IndirectReadSideEffect[-1] : &:r2530_1, m2522_8
|
||||
# 2530| m2530_7(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_1
|
||||
# 2530| m2530_8(ClassWithDestructor) = Chi : total:m2522_8, partial:m2530_7
|
||||
# 2525| v2525_1(void) = NoOp :
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2527| Block 2
|
||||
# 2527| v2527_1(void) = NoOp :
|
||||
# 2528| v2528_1(void) = NoOp :
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2530| Block 3
|
||||
# 2530| m2530_9(unknown) = Phi : from 1:~m2530_5, from 2:~m2522_6
|
||||
# 2530| v2530_10(void) = NoOp :
|
||||
# 2531| v2531_1(void) = NoOp :
|
||||
# 2521| v2521_7(void) = ReturnVoid :
|
||||
# 2521| v2521_8(void) = AliasedUse : ~m2530_9
|
||||
# 2521| v2521_9(void) = ExitFunction :
|
||||
|
||||
perf-regression.cpp:
|
||||
# 6| void Big::Big()
|
||||
# 6| Block 0
|
||||
|
||||
@@ -2498,4 +2498,36 @@ void destructor_without_block(bool b)
|
||||
ClassWithDestructor g;
|
||||
}
|
||||
|
||||
void destruction_in_switch_1(int c) {
|
||||
switch (c) {
|
||||
case 0: {
|
||||
ClassWithDestructor x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void destruction_in_switch_2(int c) {
|
||||
switch (ClassWithDestructor y; c) {
|
||||
case 0: {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void destruction_in_switch_3(int c) {
|
||||
switch (ClassWithDestructor y; c) {
|
||||
case 0: {
|
||||
ClassWithDestructor x;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// semmle-extractor-options: -std=c++20 --clang
|
||||
|
||||
@@ -16372,6 +16372,169 @@ ir.cpp:
|
||||
# 2484| v2484_7(void) = AliasedUse : ~m?
|
||||
# 2484| v2484_8(void) = ExitFunction :
|
||||
|
||||
# 2501| void destruction_in_switch_1(int)
|
||||
# 2501| Block 0
|
||||
# 2501| v2501_1(void) = EnterFunction :
|
||||
# 2501| mu2501_2(unknown) = AliasedDefinition :
|
||||
# 2501| mu2501_3(unknown) = InitializeNonLocal :
|
||||
# 2501| r2501_4(glval<int>) = VariableAddress[c] :
|
||||
# 2501| mu2501_5(int) = InitializeParameter[c] : &:r2501_4
|
||||
# 2502| r2502_1(glval<int>) = VariableAddress[c] :
|
||||
# 2502| r2502_2(int) = Load[c] : &:r2502_1, ~m?
|
||||
# 2502| v2502_3(void) = Switch : r2502_2
|
||||
#-----| Case[0] -> Block 1
|
||||
#-----| Default -> Block 3
|
||||
|
||||
# 2503| Block 1
|
||||
# 2503| v2503_1(void) = NoOp :
|
||||
# 2504| r2504_1(glval<ClassWithDestructor>) = VariableAddress[x] :
|
||||
# 2504| mu2504_2(ClassWithDestructor) = Uninitialized[x] : &:r2504_1
|
||||
# 2504| r2504_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
|
||||
# 2504| v2504_4(void) = Call[ClassWithDestructor] : func:r2504_3, this:r2504_1
|
||||
# 2504| mu2504_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2504| mu2504_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2504_1
|
||||
# 2506| r2506_1(glval<ClassWithDestructor>) = VariableAddress[x] :
|
||||
# 2506| r2506_2(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
|
||||
# 2506| v2506_3(void) = Call[~ClassWithDestructor] : func:r2506_2, this:r2506_1
|
||||
# 2506| mu2506_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 2506| v2506_5(void) = ^IndirectReadSideEffect[-1] : &:r2506_1, ~m?
|
||||
# 2506| mu2506_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_1
|
||||
# 2505| v2505_1(void) = NoOp :
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2506| Block 2
|
||||
# 2506| r2506_7(glval<ClassWithDestructor>) = VariableAddress[x] :
|
||||
# 2506| r2506_8(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
|
||||
# 2506| v2506_9(void) = Call[~ClassWithDestructor] : func:r2506_8, this:r2506_7
|
||||
# 2506| mu2506_10(unknown) = ^CallSideEffect : ~m?
|
||||
# 2506| v2506_11(void) = ^IndirectReadSideEffect[-1] : &:r2506_7, ~m?
|
||||
# 2506| mu2506_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2506_7
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2507| Block 3
|
||||
# 2507| v2507_1(void) = NoOp :
|
||||
# 2508| v2508_1(void) = NoOp :
|
||||
# 2501| v2501_6(void) = ReturnVoid :
|
||||
# 2501| v2501_7(void) = AliasedUse : ~m?
|
||||
# 2501| v2501_8(void) = ExitFunction :
|
||||
|
||||
# 2510| void destruction_in_switch_2(int)
|
||||
# 2510| Block 0
|
||||
# 2510| v2510_1(void) = EnterFunction :
|
||||
# 2510| mu2510_2(unknown) = AliasedDefinition :
|
||||
# 2510| mu2510_3(unknown) = InitializeNonLocal :
|
||||
# 2510| r2510_4(glval<int>) = VariableAddress[c] :
|
||||
# 2510| mu2510_5(int) = InitializeParameter[c] : &:r2510_4
|
||||
# 2511| r2511_1(glval<ClassWithDestructor>) = VariableAddress[y] :
|
||||
# 2511| mu2511_2(ClassWithDestructor) = Uninitialized[y] : &:r2511_1
|
||||
# 2511| r2511_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
|
||||
# 2511| v2511_4(void) = Call[ClassWithDestructor] : func:r2511_3, this:r2511_1
|
||||
# 2511| mu2511_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2511| mu2511_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2511_1
|
||||
# 2511| r2511_7(glval<int>) = VariableAddress[c] :
|
||||
# 2511| r2511_8(int) = Load[c] : &:r2511_7, ~m?
|
||||
# 2511| v2511_9(void) = Switch : r2511_8
|
||||
#-----| Case[0] -> Block 1
|
||||
#-----| Default -> Block 2
|
||||
|
||||
# 2512| Block 1
|
||||
# 2512| v2512_1(void) = NoOp :
|
||||
# 2513| v2513_1(void) = NoOp :
|
||||
#-----| Goto -> Block 4
|
||||
|
||||
# 2515| Block 2
|
||||
# 2515| v2515_1(void) = NoOp :
|
||||
# 2516| v2516_1(void) = NoOp :
|
||||
#-----| Goto -> Block 4
|
||||
|
||||
# 2518| Block 3
|
||||
# 2518| r2518_1(glval<ClassWithDestructor>) = VariableAddress[y] :
|
||||
# 2518| r2518_2(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
|
||||
# 2518| v2518_3(void) = Call[~ClassWithDestructor] : func:r2518_2, this:r2518_1
|
||||
# 2518| mu2518_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 2518| v2518_5(void) = ^IndirectReadSideEffect[-1] : &:r2518_1, ~m?
|
||||
# 2518| mu2518_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2518_1
|
||||
#-----| Goto -> Block 4
|
||||
|
||||
# 2518| Block 4
|
||||
# 2518| v2518_7(void) = NoOp :
|
||||
# 2519| v2519_1(void) = NoOp :
|
||||
# 2510| v2510_6(void) = ReturnVoid :
|
||||
# 2510| v2510_7(void) = AliasedUse : ~m?
|
||||
# 2510| v2510_8(void) = ExitFunction :
|
||||
|
||||
# 2521| void destruction_in_switch_3(int)
|
||||
# 2521| Block 0
|
||||
# 2521| v2521_1(void) = EnterFunction :
|
||||
# 2521| mu2521_2(unknown) = AliasedDefinition :
|
||||
# 2521| mu2521_3(unknown) = InitializeNonLocal :
|
||||
# 2521| r2521_4(glval<int>) = VariableAddress[c] :
|
||||
# 2521| mu2521_5(int) = InitializeParameter[c] : &:r2521_4
|
||||
# 2522| r2522_1(glval<ClassWithDestructor>) = VariableAddress[y] :
|
||||
# 2522| mu2522_2(ClassWithDestructor) = Uninitialized[y] : &:r2522_1
|
||||
# 2522| r2522_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
|
||||
# 2522| v2522_4(void) = Call[ClassWithDestructor] : func:r2522_3, this:r2522_1
|
||||
# 2522| mu2522_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2522| mu2522_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2522_1
|
||||
# 2522| r2522_7(glval<int>) = VariableAddress[c] :
|
||||
# 2522| r2522_8(int) = Load[c] : &:r2522_7, ~m?
|
||||
# 2522| v2522_9(void) = Switch : r2522_8
|
||||
#-----| Case[0] -> Block 1
|
||||
#-----| Default -> Block 3
|
||||
|
||||
# 2523| Block 1
|
||||
# 2523| v2523_1(void) = NoOp :
|
||||
# 2524| r2524_1(glval<ClassWithDestructor>) = VariableAddress[x] :
|
||||
# 2524| mu2524_2(ClassWithDestructor) = Uninitialized[x] : &:r2524_1
|
||||
# 2524| r2524_3(glval<unknown>) = FunctionAddress[ClassWithDestructor] :
|
||||
# 2524| v2524_4(void) = Call[ClassWithDestructor] : func:r2524_3, this:r2524_1
|
||||
# 2524| mu2524_5(unknown) = ^CallSideEffect : ~m?
|
||||
# 2524| mu2524_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2524_1
|
||||
# 2526| r2526_1(glval<ClassWithDestructor>) = VariableAddress[x] :
|
||||
# 2526| r2526_2(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
|
||||
# 2526| v2526_3(void) = Call[~ClassWithDestructor] : func:r2526_2, this:r2526_1
|
||||
# 2526| mu2526_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 2526| v2526_5(void) = ^IndirectReadSideEffect[-1] : &:r2526_1, ~m?
|
||||
# 2526| mu2526_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2526_1
|
||||
# 2530| r2530_1(glval<ClassWithDestructor>) = VariableAddress[y] :
|
||||
# 2530| r2530_2(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
|
||||
# 2530| v2530_3(void) = Call[~ClassWithDestructor] : func:r2530_2, this:r2530_1
|
||||
# 2530| mu2530_4(unknown) = ^CallSideEffect : ~m?
|
||||
# 2530| v2530_5(void) = ^IndirectReadSideEffect[-1] : &:r2530_1, ~m?
|
||||
# 2530| mu2530_6(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_1
|
||||
# 2525| v2525_1(void) = NoOp :
|
||||
#-----| Goto -> Block 5
|
||||
|
||||
# 2526| Block 2
|
||||
# 2526| r2526_7(glval<ClassWithDestructor>) = VariableAddress[x] :
|
||||
# 2526| r2526_8(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
|
||||
# 2526| v2526_9(void) = Call[~ClassWithDestructor] : func:r2526_8, this:r2526_7
|
||||
# 2526| mu2526_10(unknown) = ^CallSideEffect : ~m?
|
||||
# 2526| v2526_11(void) = ^IndirectReadSideEffect[-1] : &:r2526_7, ~m?
|
||||
# 2526| mu2526_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2526_7
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 2527| Block 3
|
||||
# 2527| v2527_1(void) = NoOp :
|
||||
# 2528| v2528_1(void) = NoOp :
|
||||
#-----| Goto -> Block 5
|
||||
|
||||
# 2530| Block 4
|
||||
# 2530| r2530_7(glval<ClassWithDestructor>) = VariableAddress[y] :
|
||||
# 2530| r2530_8(glval<unknown>) = FunctionAddress[~ClassWithDestructor] :
|
||||
# 2530| v2530_9(void) = Call[~ClassWithDestructor] : func:r2530_8, this:r2530_7
|
||||
# 2530| mu2530_10(unknown) = ^CallSideEffect : ~m?
|
||||
# 2530| v2530_11(void) = ^IndirectReadSideEffect[-1] : &:r2530_7, ~m?
|
||||
# 2530| mu2530_12(ClassWithDestructor) = ^IndirectMayWriteSideEffect[-1] : &:r2530_7
|
||||
#-----| Goto -> Block 5
|
||||
|
||||
# 2530| Block 5
|
||||
# 2530| v2530_13(void) = NoOp :
|
||||
# 2531| v2531_1(void) = NoOp :
|
||||
# 2521| v2521_6(void) = ReturnVoid :
|
||||
# 2521| v2521_7(void) = AliasedUse : ~m?
|
||||
# 2521| v2521_8(void) = ExitFunction :
|
||||
|
||||
perf-regression.cpp:
|
||||
# 6| void Big::Big()
|
||||
# 6| Block 0
|
||||
|
||||
Reference in New Issue
Block a user