From 70bff4e726926afbbd587027cfd7d0293f139583 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 15 Jul 2025 20:19:22 +0200 Subject: [PATCH 1/4] C++: Fix typeid IR translation --- .../code/cpp/ir/implementation/Opcode.qll | 22 ++++++++- .../aliased_ssa/Instruction.qll | 16 ++++++ .../cpp/ir/implementation/raw/Instruction.qll | 16 ++++++ .../raw/internal/TranslatedExpr.qll | 49 +++++++++++++++++++ .../unaliased_ssa/Instruction.qll | 16 ++++++ .../library-tests/ir/ir/aliased_ir.expected | 13 +++++ .../ir/ir/aliased_ssa_consistency.expected | 1 - .../aliased_ssa_consistency_unsound.expected | 1 - .../ir/ir/raw_consistency.expected | 7 --- .../test/library-tests/ir/ir/raw_ir.expected | 28 +++++------ .../ir/ir/unaliased_ssa_consistency.expected | 1 - ...unaliased_ssa_consistency_unsound.expected | 1 - 12 files changed, 143 insertions(+), 28 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll index bd1ffcd5ce15..5012f7787cf5 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll @@ -92,7 +92,9 @@ private newtype TOpcode = TUninitializedGroup() or TInlineAsm() or TUnreached() or - TNewObj() + TNewObj() or + TTypeidExpr() or + TTypeidType() /** * An opcode that specifies the operation performed by an `Instruction`. @@ -1281,4 +1283,22 @@ module Opcode { class NewObj extends Opcode, TNewObj { final override string toString() { result = "NewObj" } } + + /** + * The `Opcode` for a `TypeidInstruction`. + * + * See the `TypeidExprInstruction` documentation for more details. + */ + class TypeidExpr extends UnaryOpcode, TTypeidExpr { + final override string toString() { result = "TypeidExpr" } + } + + /** + * The `Opcode` for a `TypeidTypeInstruction`. + * + * See the `TypeidTypeInstruction` documentation for more details. + */ + class TypeidType extends Opcode, TTypeidType { + final override string toString() { result = "TypeidType" } + } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index 96c18a04ff7b..8ca2ace4cdca 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -2293,3 +2293,19 @@ class NextVarArgInstruction extends UnaryInstruction { class NewObjInstruction extends Instruction { NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj } } + +/** + * An instruction that returns the type info for its operand, where the + * operand occurs as an expression in the AST. + */ +class TypeidExprInstruction extends UnaryInstruction { + TypeidExprInstruction() { this.getOpcode() instanceof Opcode::TypeidExpr } +} + +/** + * An instruction that returns the type info for its operand, where the + * operand occurs as a type in the AST. + */ +class TypeidTypeInstruction extends Instruction { + TypeidTypeInstruction() { this.getOpcode() instanceof Opcode::TypeidType } +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll index 96c18a04ff7b..8ca2ace4cdca 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -2293,3 +2293,19 @@ class NextVarArgInstruction extends UnaryInstruction { class NewObjInstruction extends Instruction { NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj } } + +/** + * An instruction that returns the type info for its operand, where the + * operand occurs as an expression in the AST. + */ +class TypeidExprInstruction extends UnaryInstruction { + TypeidExprInstruction() { this.getOpcode() instanceof Opcode::TypeidExpr } +} + +/** + * An instruction that returns the type info for its operand, where the + * operand occurs as a type in the AST. + */ +class TypeidTypeInstruction extends Instruction { + TypeidTypeInstruction() { this.getOpcode() instanceof Opcode::TypeidType } +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index dea86499e7ca..2aa5eeebb6b7 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -4185,3 +4185,52 @@ class TranslatedAssumeExpr extends TranslatedSingleInstructionExpr { none() } } + +class TranslatedTypeidExpr extends TranslatedSingleInstructionExpr { + override TypeidOperator expr; + + final override Opcode getOpcode() { + exists(this.getOperand()) and + result instanceof Opcode::TypeidExpr + or + not exists(this.getOperand()) and + result instanceof Opcode::TypeidType + } + + final override Instruction getFirstInstruction(EdgeKind kind) { + result = this.getOperand().getFirstInstruction(kind) + or + not exists(this.getOperand()) and + result = this.getInstruction(OnlyInstructionTag()) and + kind instanceof GotoEdge + } + + override Instruction getALastInstructionInternal() { + result = this.getInstruction(OnlyInstructionTag()) + } + + final override TranslatedElement getChildInternal(int id) { + id = 0 and result = this.getOperand() + } + + final override Instruction getInstructionSuccessorInternal(InstructionTag tag, EdgeKind kind) { + tag = OnlyInstructionTag() and + result = this.getParent().getChildSuccessor(this, kind) + } + + final override Instruction getChildSuccessorInternal(TranslatedElement child, EdgeKind kind) { + child = this.getOperand() and + result = this.getInstruction(OnlyInstructionTag()) and + kind instanceof GotoEdge + } + + final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) { + tag = OnlyInstructionTag() and + result = this.getOperand().getResult() and + operandTag instanceof UnaryOperandTag + } + + private TranslatedExpr getOperand() { + result = getTranslatedExpr(expr.getExpr().getFullyConverted()) + } +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index 96c18a04ff7b..8ca2ace4cdca 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -2293,3 +2293,19 @@ class NextVarArgInstruction extends UnaryInstruction { class NewObjInstruction extends Instruction { NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj } } + +/** + * An instruction that returns the type info for its operand, where the + * operand occurs as an expression in the AST. + */ +class TypeidExprInstruction extends UnaryInstruction { + TypeidExprInstruction() { this.getOpcode() instanceof Opcode::TypeidExpr } +} + +/** + * An instruction that returns the type info for its operand, where the + * operand occurs as a type in the AST. + */ +class TypeidTypeInstruction extends Instruction { + TypeidTypeInstruction() { this.getOpcode() instanceof Opcode::TypeidType } +} diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 38f0a0a4f4f7..78f0bbd1e0c8 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -39983,4 +39983,17 @@ type_info_test.cpp: # 3| m3_4(unknown) = Chi : total:m3_2, partial:m3_3 # 3| r3_5(glval) = VariableAddress[x] : # 3| m3_6(int) = InitializeParameter[x] : &:r3_5 +# 3| m3_7(unknown) = Chi : total:m3_4, partial:m3_6 # 4| r4_1(glval) = VariableAddress[t1] : +# 4| r4_2(glval) = VariableAddress[x] : +# 4| r4_3(glval) = TypeidExpr : r4_2 +# 4| r4_4(type_info &) = CopyValue : r4_3 +# 4| m4_5(type_info &) = Store[t1] : &:r4_1, r4_4 +# 5| r5_1(glval) = VariableAddress[t2] : +# 5| r5_2(glval) = TypeidType : +# 5| r5_3(type_info &) = CopyValue : r5_2 +# 5| m5_4(type_info &) = Store[t2] : &:r5_1, r5_3 +# 6| v6_1(void) = NoOp : +# 3| v3_8(void) = ReturnVoid : +# 3| v3_9(void) = AliasedUse : m3_3 +# 3| v3_10(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected index 137b2aee2665..b83d9ea47e38 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency.expected @@ -6,7 +6,6 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor -| 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) | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected index 137b2aee2665..b83d9ea47e38 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ssa_consistency_unsound.expected @@ -6,7 +6,6 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor -| 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) | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction diff --git a/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected b/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected index 9cdfdd2dcd5e..e30106d35204 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected @@ -1,6 +1,4 @@ missingOperand -| 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) | -| 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) | unexpectedOperand duplicateOperand missingPhiOperand @@ -8,9 +6,6 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor -| 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) | -| 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) | -| 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) | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction @@ -26,8 +21,6 @@ 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() | -| 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) | -| 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) | switchInstructionWithoutDefaultEdge notMarkedAsConflated wronglyMarkedAsConflated 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 c9158233914d..68c2f3602983 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -38112,19 +38112,15 @@ type_info_test.cpp: # 3| r3_4(glval) = VariableAddress[x] : # 3| mu3_5(int) = InitializeParameter[x] : &:r3_4 # 4| r4_1(glval) = VariableAddress[t1] : - -# 4| Block 1 -# 4| r4_2(glval) = VariableAddress[x] : - -# 4| Block 2 -# 4| r4_3(type_info &) = CopyValue : -# 4| mu4_4(type_info &) = Store[t1] : &:r4_1, r4_3 -# 5| r5_1(glval) = VariableAddress[t2] : - -# 5| Block 3 -# 5| r5_2(type_info &) = CopyValue : -# 5| mu5_3(type_info &) = Store[t2] : &:r5_1, r5_2 -# 6| v6_1(void) = NoOp : -# 3| v3_6(void) = ReturnVoid : -# 3| v3_7(void) = AliasedUse : ~m? -# 3| v3_8(void) = ExitFunction : +# 4| r4_2(glval) = VariableAddress[x] : +# 4| r4_3(glval) = TypeidExpr : r4_2 +# 4| r4_4(type_info &) = CopyValue : r4_3 +# 4| mu4_5(type_info &) = Store[t1] : &:r4_1, r4_4 +# 5| r5_1(glval) = VariableAddress[t2] : +# 5| r5_2(glval) = TypeidType : +# 5| r5_3(type_info &) = CopyValue : r5_2 +# 5| mu5_4(type_info &) = Store[t2] : &:r5_1, r5_3 +# 6| v6_1(void) = NoOp : +# 3| v3_6(void) = ReturnVoid : +# 3| v3_7(void) = AliasedUse : ~m? +# 3| v3_8(void) = ExitFunction : diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected index 137b2aee2665..b83d9ea47e38 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency.expected @@ -6,7 +6,6 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor -| 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) | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction diff --git a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected index 137b2aee2665..b83d9ea47e38 100644 --- a/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected +++ b/cpp/ql/test/library-tests/ir/ir/unaliased_ssa_consistency_unsound.expected @@ -6,7 +6,6 @@ missingOperandType duplicateChiOperand sideEffectWithoutPrimary instructionWithoutSuccessor -| 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) | ambiguousSuccessors unexplainedLoop unnecessaryPhiInstruction From 54f11ca6111a062a9ac372dc8b3d552b696908ae Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 15 Jul 2025 20:40:57 +0200 Subject: [PATCH 2/4] C++: Fix typo in comment --- cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll index 5012f7787cf5..1555b4efa1dd 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll @@ -1285,7 +1285,7 @@ module Opcode { } /** - * The `Opcode` for a `TypeidInstruction`. + * The `Opcode` for a `TypeidExprInstruction`. * * See the `TypeidExprInstruction` documentation for more details. */ From a08d5943715abd4eca69e8c3d583c00f20e05452 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 15 Jul 2025 21:31:24 +0200 Subject: [PATCH 3/4] C++: Introduce `TypeidInstruction` base class --- .../lib/semmle/code/cpp/ir/implementation/Opcode.qll | 10 ++++++++++ .../cpp/ir/implementation/aliased_ssa/Instruction.qll | 11 +++++++++-- .../code/cpp/ir/implementation/raw/Instruction.qll | 11 +++++++++-- .../ir/implementation/unaliased_ssa/Instruction.qll | 11 +++++++++-- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll index 1555b4efa1dd..1f0de9784708 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll @@ -93,6 +93,7 @@ private newtype TOpcode = TInlineAsm() or TUnreached() or TNewObj() or + TTypeid() or TTypeidExpr() or TTypeidType() @@ -1284,6 +1285,15 @@ module Opcode { final override string toString() { result = "NewObj" } } + /** + * The `Opcode` for a `TypeidInstruction`. + * + * See the `TypeidInstruction` documentation for more details. + */ + class Typeid extends Opcode, TTypeid { + final override string toString() { result = "Typeid" } + } + /** * The `Opcode` for a `TypeidExprInstruction`. * diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll index 8ca2ace4cdca..d5332cecf85a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll @@ -2294,11 +2294,18 @@ class NewObjInstruction extends Instruction { NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj } } +/** + * An instruction that returns the type info for its operand. + */ +class TypeidInstruction extends Instruction { + TypeidInstruction() { this.getOpcode() instanceof Opcode::Typeid } +} + /** * An instruction that returns the type info for its operand, where the * operand occurs as an expression in the AST. */ -class TypeidExprInstruction extends UnaryInstruction { +class TypeidExprInstruction extends TypeidInstruction, UnaryInstruction { TypeidExprInstruction() { this.getOpcode() instanceof Opcode::TypeidExpr } } @@ -2306,6 +2313,6 @@ class TypeidExprInstruction extends UnaryInstruction { * An instruction that returns the type info for its operand, where the * operand occurs as a type in the AST. */ -class TypeidTypeInstruction extends Instruction { +class TypeidTypeInstruction extends TypeidInstruction { TypeidTypeInstruction() { this.getOpcode() instanceof Opcode::TypeidType } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll index 8ca2ace4cdca..d5332cecf85a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/Instruction.qll @@ -2294,11 +2294,18 @@ class NewObjInstruction extends Instruction { NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj } } +/** + * An instruction that returns the type info for its operand. + */ +class TypeidInstruction extends Instruction { + TypeidInstruction() { this.getOpcode() instanceof Opcode::Typeid } +} + /** * An instruction that returns the type info for its operand, where the * operand occurs as an expression in the AST. */ -class TypeidExprInstruction extends UnaryInstruction { +class TypeidExprInstruction extends TypeidInstruction, UnaryInstruction { TypeidExprInstruction() { this.getOpcode() instanceof Opcode::TypeidExpr } } @@ -2306,6 +2313,6 @@ class TypeidExprInstruction extends UnaryInstruction { * An instruction that returns the type info for its operand, where the * operand occurs as a type in the AST. */ -class TypeidTypeInstruction extends Instruction { +class TypeidTypeInstruction extends TypeidInstruction { TypeidTypeInstruction() { this.getOpcode() instanceof Opcode::TypeidType } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll index 8ca2ace4cdca..d5332cecf85a 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll @@ -2294,11 +2294,18 @@ class NewObjInstruction extends Instruction { NewObjInstruction() { this.getOpcode() instanceof Opcode::NewObj } } +/** + * An instruction that returns the type info for its operand. + */ +class TypeidInstruction extends Instruction { + TypeidInstruction() { this.getOpcode() instanceof Opcode::Typeid } +} + /** * An instruction that returns the type info for its operand, where the * operand occurs as an expression in the AST. */ -class TypeidExprInstruction extends UnaryInstruction { +class TypeidExprInstruction extends TypeidInstruction, UnaryInstruction { TypeidExprInstruction() { this.getOpcode() instanceof Opcode::TypeidExpr } } @@ -2306,6 +2313,6 @@ class TypeidExprInstruction extends UnaryInstruction { * An instruction that returns the type info for its operand, where the * operand occurs as a type in the AST. */ -class TypeidTypeInstruction extends Instruction { +class TypeidTypeInstruction extends TypeidInstruction { TypeidTypeInstruction() { this.getOpcode() instanceof Opcode::TypeidType } } From 529712122c00979192ecd1ff65dadc786ea7c0f5 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 15 Jul 2025 22:15:11 +0200 Subject: [PATCH 4/4] C++: Address review comments --- cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll index 1f0de9784708..90afabca30de 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/Opcode.qll @@ -93,7 +93,6 @@ private newtype TOpcode = TInlineAsm() or TUnreached() or TNewObj() or - TTypeid() or TTypeidExpr() or TTypeidType() @@ -1290,16 +1289,14 @@ module Opcode { * * See the `TypeidInstruction` documentation for more details. */ - class Typeid extends Opcode, TTypeid { - final override string toString() { result = "Typeid" } - } + abstract class Typeid extends Opcode { } /** * The `Opcode` for a `TypeidExprInstruction`. * * See the `TypeidExprInstruction` documentation for more details. */ - class TypeidExpr extends UnaryOpcode, TTypeidExpr { + class TypeidExpr extends Typeid, UnaryOpcode, TTypeidExpr { final override string toString() { result = "TypeidExpr" } } @@ -1308,7 +1305,7 @@ module Opcode { * * See the `TypeidTypeInstruction` documentation for more details. */ - class TypeidType extends Opcode, TTypeidType { + class TypeidType extends Typeid, TTypeidType { final override string toString() { result = "TypeidType" } } }