Merge pull request #15539 from MathiasVP/fix-ir-gen-for-conditional-decl-expr-without-var-access

C++: Fix IR generation when `ConditionDeclExpr` does not have an immediate `VariableAccess`
This commit is contained in:
Mathias Vorreiter Pedersen
2024-02-07 15:19:16 +00:00
committed by GitHub
14 changed files with 144 additions and 47 deletions

View File

@@ -244,9 +244,15 @@ class ConditionDeclExpr extends Expr, @condition_decl {
/**
* Gets the compiler-generated variable access that conceptually occurs after
* the initialization of the declared variable.
* the initialization of the declared variable, if any.
*/
VariableAccess getVariableAccess() { result = this.getChild(0) }
VariableAccess getVariableAccess() { result = this.getExpr() }
/**
* Gets the expression that is evaluated after the initialization of the declared
* variable.
*/
Expr getExpr() { result = this.getChild(0) }
/**
* Gets the expression that initializes the declared variable. This predicate

View File

@@ -3173,7 +3173,7 @@ class TranslatedConditionDeclExpr extends TranslatedNonConstantExpr {
private TranslatedConditionDecl getDecl() { result = getTranslatedConditionDecl(expr) }
private TranslatedExpr getConditionExpr() {
result = getTranslatedExpr(expr.getVariableAccess().getFullyConverted())
result = getTranslatedExpr(expr.getExpr().getFullyConverted())
}
}

View File

@@ -16132,6 +16132,31 @@ ir.cpp:
# 2112| getExpr(): [VariableAccess] end
# 2112| Type = [CharPointerType] char *
# 2112| ValueCategory = prvalue(load)
# 2115| [CopyAssignmentOperator] HasOperatorBool& HasOperatorBool::operator=(HasOperatorBool const&)
# 2115| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [LValueReferenceType] const HasOperatorBool &
# 2115| [MoveAssignmentOperator] HasOperatorBool& HasOperatorBool::operator=(HasOperatorBool&&)
# 2115| <params>:
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
#-----| Type = [RValueReferenceType] HasOperatorBool &&
# 2116| [ConversionOperator] bool HasOperatorBool::operator bool()
# 2116| <params>:
# 2119| [TopLevelFunction] void call_as_child_of_ConditionDeclExpr()
# 2119| <params>:
# 2119| getEntryPoint(): [BlockStmt] { ... }
# 2120| getStmt(0): [IfStmt] if (...) ...
# 2120| getCondition(): [ConditionDeclExpr] (condition decl)
# 2120| Type = [BoolType] bool
# 2120| ValueCategory = prvalue
# 2120| getChild(0): [FunctionCall] call to operator bool
# 2120| Type = [BoolType] bool
# 2120| ValueCategory = prvalue
# 2120| getQualifier(): [VariableAccess] b
# 2120| Type = [Struct] HasOperatorBool
# 2120| ValueCategory = prvalue(load)
# 2120| getThen(): [BlockStmt] { ... }
# 2121| getStmt(1): [ReturnStmt] return ...
perf-regression.cpp:
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
# 4| <params>:

View File

@@ -12441,6 +12441,38 @@ ir.cpp:
# 2109| v2109_12(void) = AliasedUse : m2109_3
# 2109| v2109_13(void) = ExitFunction :
# 2119| void call_as_child_of_ConditionDeclExpr()
# 2119| Block 0
# 2119| v2119_1(void) = EnterFunction :
# 2119| m2119_2(unknown) = AliasedDefinition :
# 2119| m2119_3(unknown) = InitializeNonLocal :
# 2119| m2119_4(unknown) = Chi : total:m2119_2, partial:m2119_3
# 2120| r2120_1(glval<HasOperatorBool>) = VariableAddress[b] :
# 2120| r2120_2(HasOperatorBool) = Constant[0] :
# 2120| m2120_3(HasOperatorBool) = Store[b] : &:r2120_1, r2120_2
# 2120| r2120_4(glval<HasOperatorBool>) = VariableAddress[b] :
# 2120| r2120_5(glval<unknown>) = FunctionAddress[operator bool] :
# 2120| r2120_6(bool) = Call[operator bool] : func:r2120_5, this:r2120_4
# 2120| m2120_7(unknown) = ^CallSideEffect : ~m2119_4
# 2120| m2120_8(unknown) = Chi : total:m2119_4, partial:m2120_7
# 2120| v2120_9(void) = ^IndirectReadSideEffect[-1] : &:r2120_4, m2120_3
# 2120| m2120_10(HasOperatorBool) = ^IndirectMayWriteSideEffect[-1] : &:r2120_4
# 2120| m2120_11(HasOperatorBool) = Chi : total:m2120_3, partial:m2120_10
# 2120| r2120_12(bool) = CopyValue : r2120_6
# 2120| v2120_13(void) = ConditionalBranch : r2120_12
#-----| False -> Block 2
#-----| True -> Block 1
# 2120| Block 1
# 2120| v2120_14(void) = NoOp :
#-----| Goto -> Block 2
# 2121| Block 2
# 2121| v2121_1(void) = NoOp :
# 2119| v2119_5(void) = ReturnVoid :
# 2119| v2119_6(void) = AliasedUse : ~m2120_8
# 2119| v2119_7(void) = ExitFunction :
perf-regression.cpp:
# 6| void Big::Big()
# 6| Block 0

View File

@@ -12,7 +12,11 @@ unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
operandAcrossFunctions
instructionWithoutUniqueBlock
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
containsLoopOfForwardEdges
missingIRType
multipleIRTypes
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
@@ -24,8 +28,4 @@ nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
thisArgumentIsNonPointer
nonUniqueIRVariable
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType
multipleIRTypes
missingCppType

View File

@@ -12,7 +12,11 @@ unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
operandAcrossFunctions
instructionWithoutUniqueBlock
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
containsLoopOfForwardEdges
missingIRType
multipleIRTypes
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
@@ -24,8 +28,4 @@ nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
thisArgumentIsNonPointer
nonUniqueIRVariable
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType
multipleIRTypes
missingCppType

View File

@@ -2112,4 +2112,12 @@ char* test_strtod(char *s) {
return end;
}
struct HasOperatorBool {
operator bool();
};
void call_as_child_of_ConditionDeclExpr() {
if(HasOperatorBool b = HasOperatorBool()) {}
}
// semmle-extractor-options: -std=c++17 --clang

View File

@@ -10070,6 +10070,23 @@
| ir.cpp:2112:10:2112:12 | Address | &:r2112_2 |
| ir.cpp:2112:10:2112:12 | Load | m2111_11 |
| ir.cpp:2112:10:2112:12 | StoreValue | r2112_3 |
| ir.cpp:2119:6:2119:39 | ChiPartial | partial:m2119_3 |
| ir.cpp:2119:6:2119:39 | ChiTotal | total:m2119_2 |
| ir.cpp:2119:6:2119:39 | SideEffect | ~m2120_8 |
| ir.cpp:2120:6:2120:42 | Address | &:r2120_1 |
| ir.cpp:2120:6:2120:42 | Condition | r2120_12 |
| ir.cpp:2120:22:2120:22 | Address | &:r2120_4 |
| ir.cpp:2120:22:2120:22 | Address | &:r2120_4 |
| ir.cpp:2120:22:2120:22 | Arg(this) | this:r2120_4 |
| ir.cpp:2120:22:2120:22 | CallTarget | func:r2120_5 |
| ir.cpp:2120:22:2120:22 | ChiPartial | partial:m2120_7 |
| ir.cpp:2120:22:2120:22 | ChiPartial | partial:m2120_10 |
| ir.cpp:2120:22:2120:22 | ChiTotal | total:m2119_4 |
| ir.cpp:2120:22:2120:22 | ChiTotal | total:m2120_3 |
| ir.cpp:2120:22:2120:22 | SideEffect | m2120_3 |
| ir.cpp:2120:22:2120:22 | SideEffect | ~m2119_4 |
| ir.cpp:2120:22:2120:22 | Unary | r2120_6 |
| ir.cpp:2120:25:2120:42 | StoreValue | r2120_2 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
| perf-regression.cpp:6:3:6:5 | Address | &:r6_7 |

View File

@@ -11647,6 +11647,35 @@ ir.cpp:
# 2109| v2109_11(void) = AliasedUse : ~m?
# 2109| v2109_12(void) = ExitFunction :
# 2119| void call_as_child_of_ConditionDeclExpr()
# 2119| Block 0
# 2119| v2119_1(void) = EnterFunction :
# 2119| mu2119_2(unknown) = AliasedDefinition :
# 2119| mu2119_3(unknown) = InitializeNonLocal :
# 2120| r2120_1(glval<HasOperatorBool>) = VariableAddress[b] :
# 2120| r2120_2(HasOperatorBool) = Constant[0] :
# 2120| mu2120_3(HasOperatorBool) = Store[b] : &:r2120_1, r2120_2
# 2120| r2120_4(glval<HasOperatorBool>) = VariableAddress[b] :
# 2120| r2120_5(glval<unknown>) = FunctionAddress[operator bool] :
# 2120| r2120_6(bool) = Call[operator bool] : func:r2120_5, this:r2120_4
# 2120| mu2120_7(unknown) = ^CallSideEffect : ~m?
# 2120| v2120_8(void) = ^IndirectReadSideEffect[-1] : &:r2120_4, ~m?
# 2120| mu2120_9(HasOperatorBool) = ^IndirectMayWriteSideEffect[-1] : &:r2120_4
# 2120| r2120_10(bool) = CopyValue : r2120_6
# 2120| v2120_11(void) = ConditionalBranch : r2120_10
#-----| False -> Block 2
#-----| True -> Block 1
# 2120| Block 1
# 2120| v2120_12(void) = NoOp :
#-----| Goto -> Block 2
# 2121| Block 2
# 2121| v2121_1(void) = NoOp :
# 2119| v2119_4(void) = ReturnVoid :
# 2119| v2119_5(void) = AliasedUse : ~m?
# 2119| v2119_6(void) = ExitFunction :
perf-regression.cpp:
# 6| void Big::Big()
# 6| Block 0

View File

@@ -12,7 +12,11 @@ unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
operandAcrossFunctions
instructionWithoutUniqueBlock
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
containsLoopOfForwardEdges
missingIRType
multipleIRTypes
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
@@ -24,8 +28,4 @@ nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
thisArgumentIsNonPointer
nonUniqueIRVariable
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType
multipleIRTypes
missingCppType

View File

@@ -12,7 +12,11 @@ unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
operandAcrossFunctions
instructionWithoutUniqueBlock
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
containsLoopOfForwardEdges
missingIRType
multipleIRTypes
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
@@ -24,8 +28,4 @@ nonUniqueEnclosingIRFunction
fieldAddressOnNonPointer
thisArgumentIsNonPointer
nonUniqueIRVariable
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType
multipleIRTypes
missingCppType

View File

@@ -8,10 +8,6 @@ duplicateChiOperand
sideEffectWithoutPrimary
instructionWithoutSuccessor
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
| condition_decls.cpp:16:19:16:20 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
| condition_decls.cpp:26:23:26:24 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
| condition_decls.cpp:41:22:41:23 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| condition_decls.cpp:48:52:48:53 | Chi: call to BoxedInt | Instruction 'Chi: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
@@ -21,7 +17,11 @@ unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
operandAcrossFunctions
instructionWithoutUniqueBlock
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
containsLoopOfForwardEdges
missingIRType
multipleIRTypes
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
@@ -36,8 +36,4 @@ thisArgumentIsNonPointer
| pointer_to_member.cpp:23:5:23:54 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
| pointer_to_member.cpp:24:5:24:49 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
nonUniqueIRVariable
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType
multipleIRTypes
missingCppType

View File

@@ -1,8 +1,4 @@
missingOperand
| condition_decls.cpp:16:6:16:20 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
| condition_decls.cpp:26:10:26:24 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
| condition_decls.cpp:41:9:41:23 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| condition_decls.cpp:48:39:48:53 | CopyValue: (condition decl) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| misc.c:125:5:125:11 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | misc.c:97:6:97:10 | void misc3() | void misc3() |
| try_catch.cpp:23:5:23:18 | CopyValue: (statement expression) | Instruction 'CopyValue' is missing an expected operand with tag 'Unary' in function '$@'. | try_catch.cpp:19:6:19:23 | void throw_from_nonstmt(int) | void throw_from_nonstmt(int) |
unexpectedOperand
@@ -15,14 +11,6 @@ instructionWithoutSuccessor
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
| VacuousDestructorCall.cpp:3:3:3:3 | VariableAddress: x | Instruction 'VariableAddress: x' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
| VacuousDestructorCall.cpp:4:3:4:3 | Load: y | Instruction 'Load: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
| condition_decls.cpp:16:19:16:20 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
| condition_decls.cpp:26:19:26:20 | IndirectMayWriteSideEffect: bi | Instruction 'IndirectMayWriteSideEffect: bi' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
| condition_decls.cpp:26:23:26:24 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
| condition_decls.cpp:41:22:41:23 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| condition_decls.cpp:48:52:48:53 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| file://:0:0:0:0 | CompareNE: (bool)... | Instruction 'CompareNE: (bool)...' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |

View File

@@ -8,10 +8,6 @@ duplicateChiOperand
sideEffectWithoutPrimary
instructionWithoutSuccessor
| VacuousDestructorCall.cpp:2:29:2:29 | InitializeIndirection: y | Instruction 'InitializeIndirection: y' has no successors in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor<int>(int, int*) | void CallDestructor<int>(int, int*) |
| condition_decls.cpp:16:19:16:20 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:15:6:15:17 | void if_decl_bind(int) | void if_decl_bind(int) |
| condition_decls.cpp:26:23:26:24 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:25:6:25:21 | void switch_decl_bind(int) | void switch_decl_bind(int) |
| condition_decls.cpp:41:22:41:23 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:40:6:40:20 | void while_decl_bind(int) | void while_decl_bind(int) |
| condition_decls.cpp:48:52:48:53 | IndirectMayWriteSideEffect: call to BoxedInt | Instruction 'IndirectMayWriteSideEffect: call to BoxedInt' has no successors in function '$@'. | condition_decls.cpp:47:6:47:18 | void for_decl_bind(int) | void for_decl_bind(int) |
| ms_try_mix.cpp:35:13:35:19 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:29:6:29:19 | void ms_finally_mix(int) | void ms_finally_mix(int) |
| ms_try_mix.cpp:53:5:53:11 | ThrowValue: throw ... | Instruction 'ThrowValue: throw ...' has no successors in function '$@'. | ms_try_mix.cpp:49:6:49:28 | void ms_empty_finally_at_end() | void ms_empty_finally_at_end() |
| stmt_expr.cpp:27:5:27:15 | Store: ... = ... | Instruction 'Store: ... = ...' has no successors in function '$@'. | stmt_expr.cpp:21:13:21:13 | void stmtexpr::g(int) | void stmtexpr::g(int) |
@@ -21,7 +17,11 @@ unnecessaryPhiInstruction
memoryOperandDefinitionIsUnmodeled
operandAcrossFunctions
instructionWithoutUniqueBlock
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
containsLoopOfForwardEdges
missingIRType
multipleIRTypes
lostReachability
backEdgeCountMismatch
useNotDominatedByDefinition
@@ -36,8 +36,4 @@ thisArgumentIsNonPointer
| pointer_to_member.cpp:23:5:23:54 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
| pointer_to_member.cpp:24:5:24:49 | Call: call to expression | Call instruction 'Call: call to expression' has a `this` argument operand that is not an address, in function '$@'. | pointer_to_member.cpp:14:5:14:9 | int usePM(int PM::*) | int usePM(int PM::*) |
nonUniqueIRVariable
missingCanonicalLanguageType
multipleCanonicalLanguageTypes
missingIRType
multipleIRTypes
missingCppType