Skip to content

Commit 5467649

Browse files
committed
C++: Fix typeid IR translation
1 parent 16f3fc6 commit 5467649

File tree

10 files changed

+111
-28
lines changed

10 files changed

+111
-28
lines changed

cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ private newtype TOpcode =
9292
TUninitializedGroup() or
9393
TInlineAsm() or
9494
TUnreached() or
95-
TNewObj()
95+
TNewObj() or
96+
TTypeidExpr() or
97+
TTypeidType()
9698

9799
/**
98100
* An opcode that specifies the operation performed by an `Instruction`.
@@ -1281,4 +1283,22 @@ module Opcode {
12811283
class NewObj extends Opcode, TNewObj {
12821284
final override string toString() { result = "NewObj" }
12831285
}
1286+
1287+
/**
1288+
* The `Opcode` for a `TypeidInstruction`.
1289+
*
1290+
* See the `TypeidExprInstruction` documentation for more details.
1291+
*/
1292+
class TypeidExpr extends UnaryOpcode, TTypeidExpr {
1293+
final override string toString() { result = "TypeidExpr" }
1294+
}
1295+
1296+
/**
1297+
* The `Opcode` for a `TypeidTypeInstruction`.
1298+
*
1299+
* See the `TypeidTypeInstruction` documentation for more details.
1300+
*/
1301+
class TypeidType extends Opcode, TTypeidType {
1302+
final override string toString() { result = "TypeidType" }
1303+
}
12841304
}

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2293,3 +2293,19 @@ class NextVarArgInstruction extends UnaryInstruction {
22932293
class NewObjInstruction extends Instruction {
22942294
NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj }
22952295
}
2296+
2297+
/**
2298+
* An instruction that returns the type info for its operand, where the
2299+
* operand occurs as an expression in the AST.
2300+
*/
2301+
class TypeidExprInstruction extends UnaryInstruction {
2302+
TypeidExprInstruction() { this.getOpcode() instanceof Opcode::TypeidExpr }
2303+
}
2304+
2305+
/**
2306+
* An instruction that returns the type info for its operand, where the
2307+
* operand occurs as a type in the AST.
2308+
*/
2309+
class TypeidTypeInstruction extends Instruction {
2310+
TypeidTypeInstruction() { this.getOpcode() instanceof Opcode::TypeidType }
2311+
}

cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4185,3 +4185,52 @@ class TranslatedAssumeExpr extends TranslatedSingleInstructionExpr {
41854185
none()
41864186
}
41874187
}
4188+
4189+
class TranslatedTypeidExpr extends TranslatedSingleInstructionExpr {
4190+
override TypeidOperator expr;
4191+
4192+
final override Opcode getOpcode() {
4193+
exists(this.getOperand()) and
4194+
result instanceof Opcode::TypeidExpr
4195+
or
4196+
not exists(this.getOperand()) and
4197+
result instanceof Opcode::TypeidType
4198+
}
4199+
4200+
final override Instruction getFirstInstruction(EdgeKind kind) {
4201+
result = this.getOperand().getFirstInstruction(kind)
4202+
or
4203+
not exists(this.getOperand()) and
4204+
result = this.getInstruction(OnlyInstructionTag()) and
4205+
kind instanceof GotoEdge
4206+
}
4207+
4208+
override Instruction getALastInstructionInternal() {
4209+
result = this.getInstruction(OnlyInstructionTag())
4210+
}
4211+
4212+
final override TranslatedElement getChildInternal(int id) {
4213+
id = 0 and result = this.getOperand()
4214+
}
4215+
4216+
final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) {
4217+
tag = OnlyInstructionTag() and
4218+
result = this.getParent().getChildSuccessor(this, kind)
4219+
}
4220+
4221+
final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) {
4222+
child = this.getOperand() and
4223+
result = this.getInstruction(OnlyInstructionTag()) and
4224+
kind instanceof GotoEdge
4225+
}
4226+
4227+
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
4228+
tag = OnlyInstructionTag() and
4229+
result = this.getOperand().getResult() and
4230+
operandTag instanceof UnaryOperandTag
4231+
}
4232+
4233+
private TranslatedExpr getOperand() {
4234+
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
4235+
}
4236+
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39983,4 +39983,17 @@ type_info_test.cpp:
3998339983
# 3| m3_4(unknown) = Chi : total:m3_2, partial:m3_3
3998439984
# 3| r3_5(glval<int>) = VariableAddress[x] :
3998539985
# 3| m3_6(int) = InitializeParameter[x] : &:r3_5
39986+
# 3| m3_7(unknown) = Chi : total:m3_4, partial:m3_6
3998639987
# 4| r4_1(glval<type_info &>) = VariableAddress[t1] :
39988+
# 4| r4_2(glval<int>) = VariableAddress[x] :
39989+
# 4| r4_3(glval<type_info>) = TypeidExpr : r4_2
39990+
# 4| r4_4(type_info &) = CopyValue : r4_3
39991+
# 4| m4_5(type_info &) = Store[t1] : &:r4_1, r4_4
39992+
# 5| r5_1(glval<type_info &>) = VariableAddress[t2] :
39993+
# 5| r5_2(glval<type_info>) = TypeidType :
39994+
# 5| r5_3(type_info &) = CopyValue : r5_2
39995+
# 5| m5_4(type_info &) = Store[t2] : &:r5_1, r5_3
39996+
# 6| v6_1(void) = NoOp :
39997+
# 3| v3_8(void) = ReturnVoid :
39998+
# 3| v3_9(void) = AliasedUse : m3_3
39999+
# 3| v3_10(void) = ExitFunction :

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ missingOperandType
66
duplicateChiOperand
77
sideEffectWithoutPrimary
88
instructionWithoutSuccessor
9-
| type_info_test.cpp:4:25:4:26 | VariableAddress: definition of t1 | Instruction 'VariableAddress: definition of t1' has no successors in function '$@'. | type_info_test.cpp:3:6:3:19 | void type_info_test(int) | void type_info_test(int) |
109
ambiguousSuccessors
1110
unexplainedLoop
1211
unnecessaryPhiInstruction

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ missingOperandType
66
duplicateChiOperand
77
sideEffectWithoutPrimary
88
instructionWithoutSuccessor
9-
| type_info_test.cpp:4:25:4:26 | VariableAddress: definition of t1 | Instruction 'VariableAddress: definition of t1' has no successors in function '$@'. | type_info_test.cpp:3:6:3:19 | void type_info_test(int) | void type_info_test(int) |
109
ambiguousSuccessors
1110
unexplainedLoop
1211
unnecessaryPhiInstruction

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

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
missingOperand
2-
| type_info_test.cpp:4:30:4:38 | CopyValue: (reference to) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | type_info_test.cpp:3:6:3:19 | void type_info_test(int) | void type_info_test(int) |
3-
| type_info_test.cpp:5:30:5:40 | CopyValue: (reference to) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | type_info_test.cpp:3:6:3:19 | void type_info_test(int) | void type_info_test(int) |
42
unexpectedOperand
53
duplicateOperand
64
missingPhiOperand
75
missingOperandType
86
duplicateChiOperand
97
sideEffectWithoutPrimary
108
instructionWithoutSuccessor
11-
| type_info_test.cpp:4:25:4:26 | VariableAddress: definition of t1 | Instruction 'VariableAddress: definition of t1' has no successors in function '$@'. | type_info_test.cpp:3:6:3:19 | void type_info_test(int) | void type_info_test(int) |
12-
| type_info_test.cpp:4:37:4:37 | VariableAddress: x | Instruction 'VariableAddress: x' has no successors in function '$@'. | type_info_test.cpp:3:6:3:19 | void type_info_test(int) | void type_info_test(int) |
13-
| type_info_test.cpp:5:25:5:26 | VariableAddress: definition of t2 | Instruction 'VariableAddress: definition of t2' has no successors in function '$@'. | type_info_test.cpp:3:6:3:19 | void type_info_test(int) | void type_info_test(int) |
149
ambiguousSuccessors
1510
unexplainedLoop
1611
unnecessaryPhiInstruction
@@ -26,8 +21,6 @@ lostReachability
2621
backEdgeCountMismatch
2722
useNotDominatedByDefinition
2823
| 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() |
29-
| type_info_test.cpp:4:25:4:26 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | type_info_test.cpp:3:6:3:19 | void type_info_test(int) | void type_info_test(int) |
30-
| type_info_test.cpp:5:25:5:26 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | type_info_test.cpp:3:6:3:19 | void type_info_test(int) | void type_info_test(int) |
3124
switchInstructionWithoutDefaultEdge
3225
notMarkedAsConflated
3326
wronglyMarkedAsConflated

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

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38112,19 +38112,15 @@ type_info_test.cpp:
3811238112
# 3| r3_4(glval<int>) = VariableAddress[x] :
3811338113
# 3| mu3_5(int) = InitializeParameter[x] : &:r3_4
3811438114
# 4| r4_1(glval<type_info &>) = VariableAddress[t1] :
38115-
38116-
# 4| Block 1
38117-
# 4| r4_2(glval<int>) = VariableAddress[x] :
38118-
38119-
# 4| Block 2
38120-
# 4| r4_3(type_info &) = CopyValue :
38121-
# 4| mu4_4(type_info &) = Store[t1] : &:r4_1, r4_3
38122-
# 5| r5_1(glval<type_info &>) = VariableAddress[t2] :
38123-
38124-
# 5| Block 3
38125-
# 5| r5_2(type_info &) = CopyValue :
38126-
# 5| mu5_3(type_info &) = Store[t2] : &:r5_1, r5_2
38127-
# 6| v6_1(void) = NoOp :
38128-
# 3| v3_6(void) = ReturnVoid :
38129-
# 3| v3_7(void) = AliasedUse : ~m?
38130-
# 3| v3_8(void) = ExitFunction :
38115+
# 4| r4_2(glval<int>) = VariableAddress[x] :
38116+
# 4| r4_3(glval<type_info>) = TypeidExpr : r4_2
38117+
# 4| r4_4(type_info &) = CopyValue : r4_3
38118+
# 4| mu4_5(type_info &) = Store[t1] : &:r4_1, r4_4
38119+
# 5| r5_1(glval<type_info &>) = VariableAddress[t2] :
38120+
# 5| r5_2(glval<type_info>) = TypeidType :
38121+
# 5| r5_3(type_info &) = CopyValue : r5_2
38122+
# 5| mu5_4(type_info &) = Store[t2] : &:r5_1, r5_3
38123+
# 6| v6_1(void) = NoOp :
38124+
# 3| v3_6(void) = ReturnVoid :
38125+
# 3| v3_7(void) = AliasedUse : ~m?
38126+
# 3| v3_8(void) = ExitFunction :

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ missingOperandType
66
duplicateChiOperand
77
sideEffectWithoutPrimary
88
instructionWithoutSuccessor
9-
| type_info_test.cpp:4:25:4:26 | VariableAddress: definition of t1 | Instruction 'VariableAddress: definition of t1' has no successors in function '$@'. | type_info_test.cpp:3:6:3:19 | void type_info_test(int) | void type_info_test(int) |
109
ambiguousSuccessors
1110
unexplainedLoop
1211
unnecessaryPhiInstruction

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ missingOperandType
66
duplicateChiOperand
77
sideEffectWithoutPrimary
88
instructionWithoutSuccessor
9-
| type_info_test.cpp:4:25:4:26 | VariableAddress: definition of t1 | Instruction 'VariableAddress: definition of t1' has no successors in function '$@'. | type_info_test.cpp:3:6:3:19 | void type_info_test(int) | void type_info_test(int) |
109
ambiguousSuccessors
1110
unexplainedLoop
1211
unnecessaryPhiInstruction

0 commit comments

Comments
 (0)