From d603b7ac3c19671a577663502056200212974d19 Mon Sep 17 00:00:00 2001 From: Alex Eyers-Taylor Date: Wed, 6 Sep 2023 18:52:10 +0100 Subject: [PATCH 1/2] CPP: Make functions that reach the end return. This is UB in C++ but not C where it is only bad if the result is used. --- .../2023-09-07-return-from-end.md | 5 + .../raw/internal/IRConstruction.qll | 3 - .../raw/internal/TranslatedStmt.qll | 29 +++-- .../ir/ir/operand_locations.expected | 41 +++++-- .../ir/ir/raw_consistency.expected | 10 +- .../test/library-tests/ir/ir/raw_ir.expected | 106 ++++++++++-------- 6 files changed, 111 insertions(+), 83 deletions(-) create mode 100644 cpp/ql/lib/change-notes/2023-09-07-return-from-end.md diff --git a/cpp/ql/lib/change-notes/2023-09-07-return-from-end.md b/cpp/ql/lib/change-notes/2023-09-07-return-from-end.md new file mode 100644 index 00000000000..8f1b8e9be88 --- /dev/null +++ b/cpp/ql/lib/change-notes/2023-09-07-return-from-end.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Treat functions that reach the end of the function as returning in the IR. + They used to be treated as unreachable but it is allowed in C. \ No newline at end of file diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll index 8c0695247f8..ed4b39bc24b 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/IRConstruction.qll @@ -405,9 +405,6 @@ predicate hasUnreachedInstruction(IRFunction func) { exists(Call c | c.getEnclosingFunction() = func.getFunction() and any(Options opt).exits(c.getTarget()) - ) and - not exists(TranslatedUnreachableReturnStmt return | - return.getEnclosingFunction().getFunction() = func.getFunction() ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll index 497c16d407d..aa7527451c3 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedStmt.qll @@ -442,29 +442,26 @@ class TranslatedReturnVoidStmt extends TranslatedReturnStmt { /** * The IR translation of an implicit `return` statement generated by the extractor to handle control - * flow that reaches the end of a non-`void`-returning function body. Since such control flow - * produces undefined behavior, we simply generate an `Unreached` instruction to prevent that flow - * from continuing on to pollute other analysis. The assumption is that the developer is certain - * that the implicit `return` is unreachable, even if the compiler cannot prove it. + * flow that reaches the end of a non-`void`-returning function body. Such control flow + * produces undefined behavior in C++ but not in C. However even in C using the return value is + * undefined behaviour. We make it return uninitialized memory to get as much flow as possible. */ -class TranslatedUnreachableReturnStmt extends TranslatedReturnStmt { - TranslatedUnreachableReturnStmt() { +class TranslatedNoValueReturnStmt extends TranslatedReturnStmt, TranslatedVariableInitialization { + TranslatedNoValueReturnStmt() { not stmt.hasExpr() and hasReturnValue(stmt.getEnclosingFunction()) } - override TranslatedElement getChild(int id) { none() } - - override Instruction getFirstInstruction() { result = this.getInstruction(OnlyInstructionTag()) } - - override predicate hasInstruction(Opcode opcode, InstructionTag tag, CppType resultType) { - tag = OnlyInstructionTag() and - opcode instanceof Opcode::Unreached and - resultType = getVoidType() + final override Instruction getInitializationSuccessor() { + result = this.getEnclosingFunction().getReturnSuccessorInstruction() } - override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) { none() } + final override Type getTargetType() { result = this.getEnclosingFunction().getReturnType() } - override Instruction getChildSuccessor(TranslatedElement child) { none() } + final override TranslatedInitialization getInitialization() { none() } + + final override IRVariable getIRVariable() { + result = this.getEnclosingFunction().getReturnVariable() + } } /** diff --git a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected index e8a8d7e06b7..63ece7fa36f 100644 --- a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected +++ b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected @@ -6207,10 +6207,12 @@ | ir.cpp:1286:25:1286:49 | ChiPartial | partial:m1286_7 | | ir.cpp:1286:25:1286:49 | ChiTotal | total:m1286_4 | | ir.cpp:1286:25:1286:49 | SideEffect | ~m1286_4 | -| ir.cpp:1289:5:1289:22 | Address | &:r1289_9 | +| ir.cpp:1289:5:1289:22 | Address | &:r1289_10 | | ir.cpp:1289:5:1289:22 | ChiPartial | partial:m1289_3 | | ir.cpp:1289:5:1289:22 | ChiTotal | total:m1289_2 | -| ir.cpp:1289:5:1289:22 | Load | m1291_4 | +| ir.cpp:1289:5:1289:22 | Load | m1289_9 | +| ir.cpp:1289:5:1289:22 | Phi | from 2:m1291_4 | +| ir.cpp:1289:5:1289:22 | Phi | from 3:m1293_2 | | ir.cpp:1289:5:1289:22 | SideEffect | m1289_3 | | ir.cpp:1289:29:1289:29 | Address | &:r1289_5 | | ir.cpp:1289:36:1289:36 | Address | &:r1289_7 | @@ -6221,6 +6223,7 @@ | ir.cpp:1291:16:1291:16 | Address | &:r1291_2 | | ir.cpp:1291:16:1291:16 | Load | m1289_8 | | ir.cpp:1291:16:1291:16 | StoreValue | r1291_3 | +| ir.cpp:1293:1:1293:1 | Address | &:r1293_1 | | ir.cpp:1295:6:1295:15 | ChiPartial | partial:m1295_3 | | ir.cpp:1295:6:1295:15 | ChiTotal | total:m1295_2 | | ir.cpp:1295:6:1295:15 | SideEffect | ~m1296_8 | @@ -8393,16 +8396,23 @@ | ir.cpp:1747:39:1747:39 | ChiTotal | total:m1747_20 | | ir.cpp:1747:39:1747:39 | SideEffect | ~m1747_4 | | ir.cpp:1747:39:1747:39 | SideEffect | ~m1747_15 | +| ir.cpp:1750:5:1750:34 | Address | &:r1750_5 | | ir.cpp:1750:5:1750:34 | ChiPartial | partial:m1750_3 | | ir.cpp:1750:5:1750:34 | ChiTotal | total:m1750_2 | +| ir.cpp:1750:5:1750:34 | Load | m1755_2 | +| ir.cpp:1750:5:1750:34 | SideEffect | ~m1754_10 | | ir.cpp:1751:51:1751:51 | Address | &:r1751_1 | | ir.cpp:1751:51:1751:51 | Address | &:r1751_1 | | ir.cpp:1751:51:1751:51 | Address | &:r1751_3 | +| ir.cpp:1751:51:1751:51 | Address | &:r1751_3 | | ir.cpp:1751:51:1751:51 | Load | m1751_2 | +| ir.cpp:1751:51:1751:51 | SideEffect | m1751_4 | | ir.cpp:1752:48:1752:48 | Address | &:r1752_1 | | ir.cpp:1752:48:1752:48 | Address | &:r1752_1 | | ir.cpp:1752:48:1752:48 | Address | &:r1752_3 | +| ir.cpp:1752:48:1752:48 | Address | &:r1752_3 | | ir.cpp:1752:48:1752:48 | Load | m1752_2 | +| ir.cpp:1752:48:1752:48 | SideEffect | m1752_4 | | ir.cpp:1753:40:1753:41 | Address | &:r1753_1 | | ir.cpp:1753:40:1753:41 | Address | &:r1753_1 | | ir.cpp:1753:40:1753:41 | Arg(this) | this:r1753_1 | @@ -8435,6 +8445,7 @@ | ir.cpp:1754:42:1754:42 | SideEffect | ~m1752_4 | | ir.cpp:1754:42:1754:42 | Unary | r1754_5 | | ir.cpp:1754:42:1754:42 | Unary | r1754_6 | +| ir.cpp:1755:1:1755:1 | Address | &:r1755_1 | | ir.cpp:1757:6:1757:22 | ChiPartial | partial:m1757_3 | | ir.cpp:1757:6:1757:22 | ChiTotal | total:m1757_2 | | ir.cpp:1757:6:1757:22 | SideEffect | m1757_3 | @@ -9588,22 +9599,27 @@ | ir.cpp:2021:23:2021:40 | SideEffect | ~m2021_27 | | ir.cpp:2021:23:2021:40 | Unary | r2021_20 | | ir.cpp:2021:23:2021:40 | Unary | r2021_28 | +| ir.cpp:2026:14:2026:22 | Address | &:r2026_7 | | ir.cpp:2026:14:2026:22 | ChiPartial | partial:m2026_3 | | ir.cpp:2026:14:2026:22 | ChiTotal | total:m2026_2 | +| ir.cpp:2026:14:2026:22 | Load | m2031_2 | +| ir.cpp:2026:14:2026:22 | SideEffect | ~m2028_6 | | ir.cpp:2026:37:2026:37 | Address | &:r2026_5 | | ir.cpp:2027:16:2027:16 | Address | &:r2027_1 | -| ir.cpp:2028:3:2028:3 | Address | &:r2028_9 | +| ir.cpp:2028:3:2028:3 | Address | &:r2028_10 | | ir.cpp:2028:7:2028:7 | Address | &:r2028_1 | | ir.cpp:2028:7:2028:7 | Left | r2028_2 | | ir.cpp:2028:7:2028:7 | Load | m2026_6 | | ir.cpp:2028:7:2028:13 | Condition | r2028_4 | -| ir.cpp:2028:7:2030:28 | Address | &:r2028_7 | -| ir.cpp:2028:7:2030:28 | Address | &:r2028_11 | -| ir.cpp:2028:7:2030:28 | Address | &:r2028_13 | -| ir.cpp:2028:7:2030:28 | Load | m2028_6 | -| ir.cpp:2028:7:2030:28 | Phi | from 2:m2028_12 | -| ir.cpp:2028:7:2030:28 | Phi | from 3:m2028_14 | -| ir.cpp:2028:7:2030:28 | StoreValue | r2028_8 | +| ir.cpp:2028:7:2030:28 | Address | &:r2028_8 | +| ir.cpp:2028:7:2030:28 | Address | &:r2028_12 | +| ir.cpp:2028:7:2030:28 | Address | &:r2028_14 | +| ir.cpp:2028:7:2030:28 | Load | m2028_7 | +| ir.cpp:2028:7:2030:28 | Phi | from 2:m2028_13 | +| ir.cpp:2028:7:2030:28 | Phi | from 2:~m2029_6 | +| ir.cpp:2028:7:2030:28 | Phi | from 3:m2028_15 | +| ir.cpp:2028:7:2030:28 | Phi | from 3:~m2030_6 | +| ir.cpp:2028:7:2030:28 | StoreValue | r2028_9 | | ir.cpp:2028:11:2028:13 | Right | r2028_3 | | ir.cpp:2029:6:2029:20 | CallTarget | func:r2029_1 | | ir.cpp:2029:6:2029:20 | ChiPartial | partial:m2029_5 | @@ -9626,6 +9642,7 @@ | ir.cpp:2030:22:2030:22 | Arg(0) | 0:r2030_3 | | ir.cpp:2030:22:2030:22 | Load | m2026_6 | | ir.cpp:2030:26:2030:27 | Unary | r2030_7 | +| ir.cpp:2031:1:2031:1 | Address | &:r2031_1 | | ir.cpp:2033:6:2033:17 | ChiPartial | partial:m2033_3 | | ir.cpp:2033:6:2033:17 | ChiTotal | total:m2033_2 | | ir.cpp:2033:6:2033:17 | SideEffect | ~m2036_6 | @@ -9721,8 +9738,11 @@ | ir.cpp:2051:32:2051:32 | Address | &:r2051_7 | | ir.cpp:2051:32:2051:32 | Load | m2051_6 | | ir.cpp:2051:32:2051:32 | SideEffect | m2051_8 | +| ir.cpp:2056:5:2056:18 | Address | &:r2056_5 | | ir.cpp:2056:5:2056:18 | ChiPartial | partial:m2056_3 | | ir.cpp:2056:5:2056:18 | ChiTotal | total:m2056_2 | +| ir.cpp:2056:5:2056:18 | Load | m2066_2 | +| ir.cpp:2056:5:2056:18 | SideEffect | ~m2065_6 | | ir.cpp:2058:12:2058:13 | Address | &:r2058_1 | | ir.cpp:2058:17:2058:27 | Address | &:r2058_4 | | ir.cpp:2058:17:2058:27 | Address | &:r2058_8 | @@ -9796,6 +9816,7 @@ | ir.cpp:2065:12:2065:12 | Address | &:r2065_2 | | ir.cpp:2065:12:2065:12 | Arg(0) | 0:r2065_3 | | ir.cpp:2065:12:2065:12 | Load | m2064_15 | +| ir.cpp:2066:1:2066:1 | Address | &:r2066_1 | | ir.cpp:2070:6:2070:26 | ChiPartial | partial:m2070_3 | | ir.cpp:2070:6:2070:26 | ChiTotal | total:m2070_2 | | ir.cpp:2070:6:2070:26 | SideEffect | ~m2072_5 | 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 4f3f9315c01..d2a11541fd1 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_consistency.expected @@ -12,13 +12,15 @@ unnecessaryPhiInstruction memoryOperandDefinitionIsUnmodeled operandAcrossFunctions instructionWithoutUniqueBlock +missingCanonicalLanguageType +multipleCanonicalLanguageTypes containsLoopOfForwardEdges +missingIRType +multipleIRTypes lostReachability backEdgeCountMismatch useNotDominatedByDefinition | ir.cpp:1486:8:1486:8 | Unary | Operand 'Unary' is not dominated by its definition in function '$@'. | ir.cpp:1486:8:1486:8 | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() | void StructuredBindingDataMemberStruct::StructuredBindingDataMemberStruct() | -| ir.cpp:1751:51:1751:51 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | ir.cpp:1750:5:1750:34 | int implicit_copy_constructor_test(CopyConstructorTestNonVirtualClass const&, CopyConstructorTestVirtualClass const&) | int implicit_copy_constructor_test(CopyConstructorTestNonVirtualClass const&, CopyConstructorTestVirtualClass const&) | -| ir.cpp:1752:48:1752:48 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | ir.cpp:1750:5:1750:34 | int implicit_copy_constructor_test(CopyConstructorTestNonVirtualClass const&, CopyConstructorTestVirtualClass const&) | int implicit_copy_constructor_test(CopyConstructorTestNonVirtualClass const&, CopyConstructorTestVirtualClass const&) | | 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) | @@ -35,8 +37,4 @@ nonUniqueEnclosingIRFunction fieldAddressOnNonPointer thisArgumentIsNonPointer nonUniqueIRVariable -missingCanonicalLanguageType -multipleCanonicalLanguageTypes -missingIRType -multipleIRTypes missingCppType 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 8bb7c6dde6a..1ca119060f6 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -7201,21 +7201,26 @@ ir.cpp: # 1290| r1290_1(glval) = VariableAddress[b] : # 1290| r1290_2(bool) = Load[b] : &:r1290_1, ~m? # 1290| v1290_3(void) = ConditionalBranch : r1290_2 -#-----| False -> Block 2 -#-----| True -> Block 1 +#-----| False -> Block 3 +#-----| True -> Block 2 -# 1291| Block 1 -# 1291| r1291_1(glval) = VariableAddress[#return] : -# 1291| r1291_2(glval) = VariableAddress[x] : -# 1291| r1291_3(int) = Load[x] : &:r1291_2, ~m? -# 1291| mu1291_4(int) = Store[#return] : &:r1291_1, r1291_3 +# 1289| Block 1 # 1289| r1289_8(glval) = VariableAddress[#return] : # 1289| v1289_9(void) = ReturnValue : &:r1289_8, ~m? # 1289| v1289_10(void) = AliasedUse : ~m? # 1289| v1289_11(void) = ExitFunction : -# 1293| Block 2 -# 1293| v1293_1(void) = Unreached : +# 1291| Block 2 +# 1291| r1291_1(glval) = VariableAddress[#return] : +# 1291| r1291_2(glval) = VariableAddress[x] : +# 1291| r1291_3(int) = Load[x] : &:r1291_2, ~m? +# 1291| mu1291_4(int) = Store[#return] : &:r1291_1, r1291_3 +#-----| Goto -> Block 1 + +# 1293| Block 3 +# 1293| r1293_1(glval) = VariableAddress[#return] : +# 1293| mu1293_2(int) = Uninitialized[#return] : &:r1293_1 +#-----| Goto -> Block 1 # 1295| void returnVoid(int, int) # 1295| Block 0 @@ -9526,15 +9531,14 @@ ir.cpp: # 1754| mu1754_9(unknown) = ^CallSideEffect : ~m? # 1754| v1754_10(void) = ^BufferReadSideEffect[0] : &:r1754_7, ~m? # 1754| mu1754_11(CopyConstructorTestVirtualClass) = ^IndirectMayWriteSideEffect[-1] : &:r1754_1 -# 1755| v1755_1(void) = Unreached : - -# 1751| Block 1 -# 1751| v1751_5(void) = ReturnIndirection[x] : &:r1751_3, ~m? -# 1752| v1752_5(void) = ReturnIndirection[y] : &:r1752_3, ~m? -# 1750| r1750_4(glval) = VariableAddress[#return] : -# 1750| v1750_5(void) = ReturnValue : &:r1750_4, ~m? -# 1750| v1750_6(void) = AliasedUse : ~m? -# 1750| v1750_7(void) = ExitFunction : +# 1755| r1755_1(glval) = VariableAddress[#return] : +# 1755| mu1755_2(int) = Uninitialized[#return] : &:r1755_1 +# 1751| v1751_5(void) = ReturnIndirection[x] : &:r1751_3, ~m? +# 1752| v1752_5(void) = ReturnIndirection[y] : &:r1752_3, ~m? +# 1750| r1750_4(glval) = VariableAddress[#return] : +# 1750| v1750_5(void) = ReturnValue : &:r1750_4, ~m? +# 1750| v1750_6(void) = AliasedUse : ~m? +# 1750| v1750_7(void) = ExitFunction : # 1757| void if_initialization(int) # 1757| Block 0 @@ -10199,24 +10203,32 @@ ir.cpp: # 1900| r1900_3(int) = Constant[10] : # 1900| r1900_4(bool) = CompareLT : r1900_2, r1900_3 # 1900| v1900_5(void) = ConditionalBranch : r1900_4 -#-----| False -> Block 2 -#-----| True -> Block 1 +#-----| False -> Block 3 +#-----| True -> Block 2 -# 1901| Block 1 -# 1901| r1901_1(glval) = VariableAddress[#return] : -# 1901| r1901_2(glval) = VariableAddress[x] : -# 1901| r1901_3(int) = Load[x] : &:r1901_2, ~m? -# 1901| mu1901_4(int) = Store[#return] : &:r1901_1, r1901_3 +# 1899| Block 1 # 1899| r1899_6(glval) = VariableAddress[#return] : # 1899| v1899_7(void) = ReturnValue : &:r1899_6, ~m? # 1899| v1899_8(void) = AliasedUse : ~m? # 1899| v1899_9(void) = ExitFunction : -# 1903| Block 2 +# 1901| Block 2 +# 1901| r1901_1(glval) = VariableAddress[#return] : +# 1901| r1901_2(glval) = VariableAddress[x] : +# 1901| r1901_3(int) = Load[x] : &:r1901_2, ~m? +# 1901| mu1901_4(int) = Store[#return] : &:r1901_1, r1901_3 +#-----| Goto -> Block 1 + +# 1903| Block 3 # 1903| r1903_1(glval) = FunctionAddress[noreturnFunc] : # 1903| v1903_2(void) = Call[noreturnFunc] : func:r1903_1 # 1903| mu1903_3(unknown) = ^CallSideEffect : ~m? -# 1905| v1905_1(void) = Unreached : +# 1899| v1899_10(void) = Unreached : + +# 1905| Block 4 +# 1905| r1905_1(glval) = VariableAddress[#return] : +# 1905| mu1905_2(int) = Uninitialized[#return] : &:r1905_1 +#-----| Goto -> Block 1 # 1907| int noreturnTest2(int) # 1907| Block 0 @@ -11069,23 +11081,22 @@ ir.cpp: # 2028| r2028_3(unsigned int) = Constant[100] : # 2028| r2028_4(bool) = CompareLT : r2028_2, r2028_3 # 2028| v2028_5(void) = ConditionalBranch : r2028_4 -#-----| False -> Block 4 -#-----| True -> Block 3 +#-----| False -> Block 3 +#-----| True -> Block 2 -# 2026| Block 1 -# 2026| r2026_6(glval) = VariableAddress[#return] : -# 2026| v2026_7(void) = ReturnValue : &:r2026_6, ~m? -# 2026| v2026_8(void) = AliasedUse : ~m? -# 2026| v2026_9(void) = ExitFunction : - -# 2028| Block 2 +# 2028| Block 1 # 2028| r2028_6(glval) = VariableAddress[#temp2028:7] : # 2028| r2028_7(unsigned int) = Load[#temp2028:7] : &:r2028_6, ~m? # 2028| r2028_8(glval) = VariableAddress[y] : # 2028| mu2028_9(unsigned int) = Store[y] : &:r2028_8, r2028_7 -# 2031| v2031_1(void) = Unreached : +# 2031| r2031_1(glval) = VariableAddress[#return] : +# 2031| mu2031_2(unsigned int) = Uninitialized[#return] : &:r2031_1 +# 2026| r2026_6(glval) = VariableAddress[#return] : +# 2026| v2026_7(void) = ReturnValue : &:r2026_6, ~m? +# 2026| v2026_8(void) = AliasedUse : ~m? +# 2026| v2026_9(void) = ExitFunction : -# 2029| Block 3 +# 2029| Block 2 # 2029| r2029_1(glval) = FunctionAddress[CommaTestHelper] : # 2029| r2029_2(glval) = VariableAddress[x] : # 2029| r2029_3(unsigned int) = Load[x] : &:r2029_2, ~m? @@ -11096,9 +11107,9 @@ ir.cpp: # 2029| r2029_8(unsigned int) = CopyValue : r2029_7 # 2028| r2028_10(glval) = VariableAddress[#temp2028:7] : # 2028| mu2028_11(unsigned int) = Store[#temp2028:7] : &:r2028_10, r2029_8 -#-----| Goto -> Block 2 +#-----| Goto -> Block 1 -# 2030| Block 4 +# 2030| Block 3 # 2030| r2030_1(glval) = FunctionAddress[CommaTestHelper] : # 2030| r2030_2(glval) = VariableAddress[x] : # 2030| r2030_3(unsigned int) = Load[x] : &:r2030_2, ~m? @@ -11109,7 +11120,7 @@ ir.cpp: # 2030| r2030_8(unsigned int) = Convert : r2030_7 # 2028| r2028_12(glval) = VariableAddress[#temp2028:7] : # 2028| mu2028_13(unsigned int) = Store[#temp2028:7] : &:r2028_12, r2030_8 -#-----| Goto -> Block 2 +#-----| Goto -> Block 1 # 2033| void NewDeleteMem() # 2033| Block 0 @@ -11295,13 +11306,12 @@ ir.cpp: # 2065| r2065_3(Derived2 *) = Load[d] : &:r2065_2, ~m? # 2065| v2065_4(void) = Call[?] : func:r2065_1, 0:r2065_3 # 2065| mu2065_5(unknown) = ^CallSideEffect : ~m? -# 2066| v2066_1(void) = Unreached : - -# 2056| Block 1 -# 2056| r2056_4(glval) = VariableAddress[#return] : -# 2056| v2056_5(void) = ReturnValue : &:r2056_4, ~m? -# 2056| v2056_6(void) = AliasedUse : ~m? -# 2056| v2056_7(void) = ExitFunction : +# 2066| r2066_1(glval) = VariableAddress[#return] : +# 2066| mu2066_2(int) = Uninitialized[#return] : &:r2066_1 +# 2056| r2056_4(glval) = VariableAddress[#return] : +# 2056| v2056_5(void) = ReturnValue : &:r2056_4, ~m? +# 2056| v2056_6(void) = AliasedUse : ~m? +# 2056| v2056_7(void) = ExitFunction : # 2070| void test_constant_folding() # 2070| Block 0 From e8dfecc4a4cf0d14b814ef4ad80b81a9052b9752 Mon Sep 17 00:00:00 2001 From: Alex Eyers-Taylor Date: Thu, 7 Sep 2023 12:49:13 +0100 Subject: [PATCH 2/2] CPP: Fix test result --- .../library-tests/syntax-zoo/raw_consistency.expected | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/cpp/ql/test/library-tests/syntax-zoo/raw_consistency.expected b/cpp/ql/test/library-tests/syntax-zoo/raw_consistency.expected index 6fa6c863aeb..bee483d992b 100644 --- a/cpp/ql/test/library-tests/syntax-zoo/raw_consistency.expected +++ b/cpp/ql/test/library-tests/syntax-zoo/raw_consistency.expected @@ -34,13 +34,15 @@ unnecessaryPhiInstruction memoryOperandDefinitionIsUnmodeled operandAcrossFunctions instructionWithoutUniqueBlock +missingCanonicalLanguageType +multipleCanonicalLanguageTypes containsLoopOfForwardEdges +missingIRType +multipleIRTypes lostReachability backEdgeCountMismatch useNotDominatedByDefinition | VacuousDestructorCall.cpp:2:29:2:29 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | VacuousDestructorCall.cpp:2:6:2:6 | void CallDestructor(int, int*) | void CallDestructor(int, int*) | -| misc.c:219:47:219:48 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | misc.c:219:5:219:26 | int assign_designated_init(someStruct*) | int assign_designated_init(someStruct*) | -| ms_assume.cpp:11:30:11:33 | Address | Operand 'Address' is not dominated by its definition in function '$@'. | ms_assume.cpp:11:12:11:12 | int f(int, char*[]) | int f(int, char*[]) | | ms_try_except.cpp:9:19:9:19 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) | | ms_try_except.cpp:9:19:9:19 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) | | ms_try_except.cpp:19:17:19:21 | Left | Operand 'Left' is not dominated by its definition in function '$@'. | ms_try_except.cpp:2:6:2:18 | void ms_try_except(int) | void ms_try_except(int) | @@ -58,8 +60,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