From 5484d7a35996e61af61bd05b493da5421c6485da Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 27 Nov 2025 13:58:18 +0100 Subject: [PATCH 1/5] C++: Update expected test results after frontend update --- .../library-tests/ir/ir/PrintAST.expected | 8 ++++ .../library-tests/ir/ir/aliased_ir.expected | 40 +++++++++---------- .../test/library-tests/ir/ir/raw_ir.expected | 40 +++++++++---------- .../scopes/parents/parents.expected | 4 +- .../isfromuninstantiatedtemplate.expected | 4 +- .../variables/template_variables.expected | 6 +-- .../SloppyGlobal/SloppyGlobal.expected | 6 +-- .../UnusedLocals/UnusedLocals.expected | 1 - .../Unused Entities/UnusedLocals/code2.cpp | 2 +- 9 files changed, 59 insertions(+), 52 deletions(-) diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index 630a4ca5ceba..132f5ebe070f 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -6,6 +6,14 @@ #-----| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) #-----| Type = [RValueReferenceType] __va_list_tag && +#-----| [CopyAssignmentOperator] std::__va_list& std::__va_list::operator=(std::__va_list const&) +#-----| : +#-----| getParameter(0): [Parameter] (unnamed parameter 0) +#-----| Type = [LValueReferenceType] const __va_list & +#-----| [MoveAssignmentOperator] std::__va_list& std::__va_list::operator=(std::__va_list&&) +#-----| : +#-----| getParameter(0): [Parameter] (unnamed parameter 0) +#-----| Type = [RValueReferenceType] __va_list && #-----| [Operator,TopLevelFunction] void operator delete(void*) #-----| : #-----| getParameter(0): [Parameter] (unnamed parameter 0) 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 566cf07423b8..7ef02eb31378 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -9648,29 +9648,29 @@ ir.cpp: # 1054| r1054_1(glval) = VariableAddress[lambda_inits] : # 1054| r1054_2(glval) = VariableAddress[#temp1054:22] : # 1054| m1054_3(decltype([...](...){...})) = Uninitialized[#temp1054:22] : &:r1054_2 -# 1054| r1054_4(glval) = FieldAddress[s] : r1054_2 -# 1054| r1054_5(glval) = VariableAddress[s] : -# 1054| r1054_6(String &) = Load[s] : &:r1054_5, m1040_9 -# 1054| r1054_7(glval) = CopyValue : r1054_6 -# 1054| r1054_8(String &) = CopyValue : r1054_7 -# 1054| m1054_9(String &) = Store[?] : &:r1054_4, r1054_8 +# 1054| r1054_4(glval) = FieldAddress[i] : r1054_2 +# 1054| r1054_5(glval) = VariableAddress[x] : +# 1054| r1054_6(int) = Load[x] : &:r1054_5, ~m1052_7 +# 1054| r1054_7(int) = Constant[1] : +# 1054| r1054_8(int) = Add : r1054_6, r1054_7 +# 1054| m1054_9(int) = Store[?] : &:r1054_4, r1054_8 # 1054| m1054_10(decltype([...](...){...})) = Chi : total:m1054_3, partial:m1054_9 -# 1054| r1054_11(glval) = FieldAddress[x] : r1054_2 -# 1054| r1054_12(glval) = VariableAddress[x] : -# 1054| r1054_13(int) = Load[x] : &:r1054_12, ~m1052_7 -# 1054| m1054_14(int) = Store[?] : &:r1054_11, r1054_13 +# 1054| r1054_11(glval) = FieldAddress[j] : r1054_2 +# 1054| r1054_12(glval) = VariableAddress[r] : +# 1054| r1054_13(int &) = CopyValue : r1054_12 +# 1054| m1054_14(int &) = Store[?] : &:r1054_11, r1054_13 # 1054| m1054_15(decltype([...](...){...})) = Chi : total:m1054_10, partial:m1054_14 -# 1054| r1054_16(glval) = FieldAddress[i] : r1054_2 -# 1054| r1054_17(glval) = VariableAddress[x] : -# 1054| r1054_18(int) = Load[x] : &:r1054_17, ~m1052_7 -# 1054| r1054_19(int) = Constant[1] : -# 1054| r1054_20(int) = Add : r1054_18, r1054_19 -# 1054| m1054_21(int) = Store[?] : &:r1054_16, r1054_20 +# 1054| r1054_16(glval) = FieldAddress[s] : r1054_2 +# 1054| r1054_17(glval) = VariableAddress[s] : +# 1054| r1054_18(String &) = Load[s] : &:r1054_17, m1040_9 +# 1054| r1054_19(glval) = CopyValue : r1054_18 +# 1054| r1054_20(String &) = CopyValue : r1054_19 +# 1054| m1054_21(String &) = Store[?] : &:r1054_16, r1054_20 # 1054| m1054_22(decltype([...](...){...})) = Chi : total:m1054_15, partial:m1054_21 -# 1054| r1054_23(glval) = FieldAddress[j] : r1054_2 -# 1054| r1054_24(glval) = VariableAddress[r] : -# 1054| r1054_25(int &) = CopyValue : r1054_24 -# 1054| m1054_26(int &) = Store[?] : &:r1054_23, r1054_25 +# 1054| r1054_23(glval) = FieldAddress[x] : r1054_2 +# 1054| r1054_24(glval) = VariableAddress[x] : +# 1054| r1054_25(int) = Load[x] : &:r1054_24, ~m1052_7 +# 1054| m1054_26(int) = Store[?] : &:r1054_23, r1054_25 # 1054| m1054_27(decltype([...](...){...})) = Chi : total:m1054_22, partial:m1054_26 # 1054| r1054_28(decltype([...](...){...})) = Load[#temp1054:22] : &:r1054_2, m1054_27 # 1054| m1054_29(decltype([...](...){...})) = Store[lambda_inits] : &:r1054_1, r1054_28 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 1d8f885cd15b..2e84ecd0a648 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -8892,26 +8892,26 @@ ir.cpp: # 1054| r1054_1(glval) = VariableAddress[lambda_inits] : # 1054| r1054_2(glval) = VariableAddress[#temp1054:22] : # 1054| mu1054_3(decltype([...](...){...})) = Uninitialized[#temp1054:22] : &:r1054_2 -# 1054| r1054_4(glval) = FieldAddress[s] : r1054_2 -# 1054| r1054_5(glval) = VariableAddress[s] : -# 1054| r1054_6(String &) = Load[s] : &:r1054_5, ~m? -# 1054| r1054_7(glval) = CopyValue : r1054_6 -# 1054| r1054_8(String &) = CopyValue : r1054_7 -# 1054| mu1054_9(String &) = Store[?] : &:r1054_4, r1054_8 -# 1054| r1054_10(glval) = FieldAddress[x] : r1054_2 -# 1054| r1054_11(glval) = VariableAddress[x] : -# 1054| r1054_12(int) = Load[x] : &:r1054_11, ~m? -# 1054| mu1054_13(int) = Store[?] : &:r1054_10, r1054_12 -# 1054| r1054_14(glval) = FieldAddress[i] : r1054_2 -# 1054| r1054_15(glval) = VariableAddress[x] : -# 1054| r1054_16(int) = Load[x] : &:r1054_15, ~m? -# 1054| r1054_17(int) = Constant[1] : -# 1054| r1054_18(int) = Add : r1054_16, r1054_17 -# 1054| mu1054_19(int) = Store[?] : &:r1054_14, r1054_18 -# 1054| r1054_20(glval) = FieldAddress[j] : r1054_2 -# 1054| r1054_21(glval) = VariableAddress[r] : -# 1054| r1054_22(int &) = CopyValue : r1054_21 -# 1054| mu1054_23(int &) = Store[?] : &:r1054_20, r1054_22 +# 1054| r1054_4(glval) = FieldAddress[i] : r1054_2 +# 1054| r1054_5(glval) = VariableAddress[x] : +# 1054| r1054_6(int) = Load[x] : &:r1054_5, ~m? +# 1054| r1054_7(int) = Constant[1] : +# 1054| r1054_8(int) = Add : r1054_6, r1054_7 +# 1054| mu1054_9(int) = Store[?] : &:r1054_4, r1054_8 +# 1054| r1054_10(glval) = FieldAddress[j] : r1054_2 +# 1054| r1054_11(glval) = VariableAddress[r] : +# 1054| r1054_12(int &) = CopyValue : r1054_11 +# 1054| mu1054_13(int &) = Store[?] : &:r1054_10, r1054_12 +# 1054| r1054_14(glval) = FieldAddress[s] : r1054_2 +# 1054| r1054_15(glval) = VariableAddress[s] : +# 1054| r1054_16(String &) = Load[s] : &:r1054_15, ~m? +# 1054| r1054_17(glval) = CopyValue : r1054_16 +# 1054| r1054_18(String &) = CopyValue : r1054_17 +# 1054| mu1054_19(String &) = Store[?] : &:r1054_14, r1054_18 +# 1054| r1054_20(glval) = FieldAddress[x] : r1054_2 +# 1054| r1054_21(glval) = VariableAddress[x] : +# 1054| r1054_22(int) = Load[x] : &:r1054_21, ~m? +# 1054| mu1054_23(int) = Store[?] : &:r1054_20, r1054_22 # 1054| r1054_24(decltype([...](...){...})) = Load[#temp1054:22] : &:r1054_2, ~m? # 1054| mu1054_25(decltype([...](...){...})) = Store[lambda_inits] : &:r1054_1, r1054_24 # 1055| r1055_1(glval) = VariableAddress[lambda_inits] : diff --git a/cpp/ql/test/library-tests/scopes/parents/parents.expected b/cpp/ql/test/library-tests/scopes/parents/parents.expected index 6d6e9fc2780a..0af30f5132b2 100644 --- a/cpp/ql/test/library-tests/scopes/parents/parents.expected +++ b/cpp/ql/test/library-tests/scopes/parents/parents.expected @@ -1,7 +1,7 @@ | 0 | file://:0:0:0:0 | (global namespace) | file://:0:0:0:0 | __va_list_tag | | 0 | file://:0:0:0:0 | (global namespace) | parents.cpp:2:11:2:13 | foo | | 0 | file://:0:0:0:0 | (global namespace) | parents.cpp:18:3:18:3 | var | -| 0 | file://:0:0:0:0 | (global namespace) | parents.cpp:18:7:18:7 | var | +| 0 | file://:0:0:0:0 | (global namespace) | parents.cpp:18:3:18:5 | var | | 0 | file://:0:0:0:0 | (global namespace) | parents.cpp:20:5:20:5 | g | | 1 | file://:0:0:0:0 | __va_list_tag | file://:0:0:0:0 | fp_offset | | 1 | file://:0:0:0:0 | __va_list_tag | file://:0:0:0:0 | gp_offset | @@ -22,6 +22,6 @@ | 1 | parents.cpp:6:11:10:7 | { ... } | parents.cpp:7:9:9:9 | for(...;...;...) ... | | 1 | parents.cpp:6:11:10:7 | { ... } | parents.cpp:7:33:9:9 | { ... } | | 1 | parents.cpp:7:33:9:9 | { ... } | parents.cpp:8:15:8:15 | k | -| 1 | parents.cpp:18:7:18:7 | var | parents.cpp:17:19:17:19 | T | +| 1 | parents.cpp:18:3:18:5 | var | parents.cpp:17:19:17:19 | T | | 1 | parents.cpp:20:5:20:5 | g | parents.cpp:20:9:24:1 | { ... } | | 1 | parents.cpp:20:9:24:1 | { ... } | parents.cpp:21:16:21:16 | l | diff --git a/cpp/ql/test/library-tests/templates/isfromtemplateinstantiation/isfromuninstantiatedtemplate.expected b/cpp/ql/test/library-tests/templates/isfromtemplateinstantiation/isfromuninstantiatedtemplate.expected index ce20dedcfca2..6210af105777 100644 --- a/cpp/ql/test/library-tests/templates/isfromtemplateinstantiation/isfromuninstantiatedtemplate.expected +++ b/cpp/ql/test/library-tests/templates/isfromtemplateinstantiation/isfromuninstantiatedtemplate.expected @@ -121,8 +121,8 @@ isFromUninstantiatedTemplate | isfromtemplateinstantiation.cpp:99:1:99:1 | return ... | isfromtemplateinstantiation.cpp:77:26:77:45 | AnotherTemplateClass | | isfromtemplateinstantiation.cpp:99:1:99:1 | return ... | isfromtemplateinstantiation.cpp:97:25:97:60 | myMethod2 | | isfromtemplateinstantiation.cpp:99:1:99:1 | return ... | isfromtemplateinstantiation.cpp:97:52:97:52 | myMethod2 | -| isfromtemplateinstantiation.cpp:110:15:110:15 | definition of var_template | isfromtemplateinstantiation.cpp:110:15:110:15 | var_template | -| isfromtemplateinstantiation.cpp:110:15:110:15 | var_template | isfromtemplateinstantiation.cpp:110:15:110:15 | var_template | +| isfromtemplateinstantiation.cpp:110:3:110:14 | definition of var_template | isfromtemplateinstantiation.cpp:110:3:110:14 | var_template | +| isfromtemplateinstantiation.cpp:110:3:110:14 | var_template | isfromtemplateinstantiation.cpp:110:3:110:14 | var_template | | isfromtemplateinstantiation.cpp:128:7:128:30 | AnotherTemplateClass | isfromtemplateinstantiation.cpp:128:7:128:30 | AnotherTemplateClass | | isfromtemplateinstantiation.cpp:128:7:128:30 | definition of AnotherTemplateClass | isfromtemplateinstantiation.cpp:128:7:128:30 | AnotherTemplateClass | | isfromtemplateinstantiation.cpp:129:6:129:6 | definition of f | isfromtemplateinstantiation.cpp:128:7:128:30 | AnotherTemplateClass | diff --git a/cpp/ql/test/library-tests/templates/variables/template_variables.expected b/cpp/ql/test/library-tests/templates/variables/template_variables.expected index 35c19e416e05..a0c26fd5c472 100644 --- a/cpp/ql/test/library-tests/templates/variables/template_variables.expected +++ b/cpp/ql/test/library-tests/templates/variables/template_variables.expected @@ -9,19 +9,19 @@ | variables.cpp:2:13:2:13 | pi | variables.cpp:25:12:25:16 | T | | | variables.cpp:2:13:2:13 | pi | variables.cpp:25:12:25:16, variables.cpp:37:16:37:24 | float | | | variables.cpp:2:13:2:13 | pi | variables.cpp:25:12:25:16, variables.cpp:38:16:38:22 | int | | -| variables.cpp:2:16:2:16 | pi | | T | TemplateVariable | +| variables.cpp:2:13:2:14 | pi | | T | TemplateVariable | | variables.cpp:5:23:5:37 | pi | | const char * | | | variables.cpp:8:13:8:13 | multi_arg | variables.cpp:33:19:33:33 | S, T | | | variables.cpp:8:13:8:13 | multi_arg | variables.cpp:33:19:33:33 | float, char | | | variables.cpp:8:13:8:13 | multi_arg | variables.cpp:33:19:33:33 | short, long | | | variables.cpp:8:13:8:13 | multi_arg | variables.cpp:40:23:40:60 | unsigned int, unsigned char | | | variables.cpp:8:13:8:13 | multi_arg | variables.cpp:41:23:41:42 | int, char | | -| variables.cpp:8:23:8:23 | multi_arg | | S, T | TemplateVariable | +| variables.cpp:8:13:8:21 | multi_arg | | S, T | TemplateVariable | | variables.cpp:11:3:11:3 | mutable_val | variables.cpp:26:3:26:16 | T | | | variables.cpp:11:3:11:3 | mutable_val | variables.cpp:26:3:26:16 | float | | | variables.cpp:11:3:11:3 | mutable_val | variables.cpp:26:3:26:16, variables.cpp:43:3:43:18 | int | | | variables.cpp:11:3:11:3 | mutable_val | variables.cpp:44:3:44:19 | long | | -| variables.cpp:11:15:11:15 | mutable_val | | T | TemplateVariable | +| variables.cpp:11:3:11:13 | mutable_val | | T | TemplateVariable | | variables.cpp:19:3:19:10 | bar | | T | TemplateVariable | | variables.cpp:19:8:19:8 | bar | variables.cpp:27:3:27:13 | T | | | variables.cpp:19:8:19:8 | bar | variables.cpp:27:3:27:13 | float | | diff --git a/cpp/ql/test/query-tests/Best Practices/SloppyGlobal/SloppyGlobal.expected b/cpp/ql/test/query-tests/Best Practices/SloppyGlobal/SloppyGlobal.expected index ceccd95ea3c4..24332580ddc1 100644 --- a/cpp/ql/test/query-tests/Best Practices/SloppyGlobal/SloppyGlobal.expected +++ b/cpp/ql/test/query-tests/Best Practices/SloppyGlobal/SloppyGlobal.expected @@ -2,6 +2,6 @@ | main.cpp:4:5:4:6 | ys | Poor global variable name 'ys'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | | main.cpp:9:5:9:6 | v1 | Poor global variable name 'v1'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | | main.cpp:10:5:10:6 | v2 | Poor global variable name 'v2'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | -| main.cpp:12:5:12:5 | v3 | Poor global variable name 'v3'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | -| main.cpp:14:5:14:5 | v4 | Poor global variable name 'v4'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | -| main.cpp:16:5:16:5 | v5 | Poor global variable name 'v5'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | +| main.cpp:12:3:12:4 | v3 | Poor global variable name 'v3'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | +| main.cpp:14:3:14:4 | v4 | Poor global variable name 'v4'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | +| main.cpp:16:3:16:4 | v5 | Poor global variable name 'v5'. Prefer longer, descriptive names for globals (eg. kMyGlobalConstant, not foo). | diff --git a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedLocals/UnusedLocals.expected b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedLocals/UnusedLocals.expected index 4d080c3f233d..8db9fdb3ec64 100644 --- a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedLocals/UnusedLocals.expected +++ b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedLocals/UnusedLocals.expected @@ -2,7 +2,6 @@ | code2.cpp:7:6:7:7 | v3 | Variable v3 is not used. | | code2.cpp:11:16:11:17 | v7 | Variable v7 is not used. | | code2.cpp:26:16:26:17 | v1 | Variable v1 is not used. | -| code2.cpp:27:16:27:17 | v2 | Variable v2 is not used. | | code2.cpp:42:11:42:16 | myVar1 | Variable myVar1 is not used. | | code2.cpp:64:7:64:8 | v3 | Variable v3 is not used. | | code2.cpp:108:11:108:12 | v2 | Variable v2 is not used. | diff --git a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedLocals/code2.cpp b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedLocals/code2.cpp index 00514347a084..9a70fe989064 100644 --- a/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedLocals/code2.cpp +++ b/cpp/ql/test/query-tests/Best Practices/Unused Entities/UnusedLocals/code2.cpp @@ -24,7 +24,7 @@ void myFunction() void test_template_parameter() { constexpr int v1 = 0; // BAD: unused - constexpr int v2 = 0; // GOOD: used as a template parameter below [FALSE POSITIVE] + constexpr int v2 = 0; // GOOD: used as a template parameter below myFunction(); } From 9e6b515a813f381e5ad5ea3d74226d9494434142 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 27 Nov 2025 15:49:37 +0100 Subject: [PATCH 2/5] C++: Update supported compiler versions --- docs/codeql/reusables/supported-versions-compilers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/codeql/reusables/supported-versions-compilers.rst b/docs/codeql/reusables/supported-versions-compilers.rst index 8dcfd1a5dc0f..6732ce5fb36c 100644 --- a/docs/codeql/reusables/supported-versions-compilers.rst +++ b/docs/codeql/reusables/supported-versions-compilers.rst @@ -4,9 +4,9 @@ :stub-columns: 1 Language,Variants,Compilers,Extensions - C/C++,"C89, C99, C11, C17, C23, C++98, C++03, C++11, C++14, C++17, C++20, C++23 [1]_ [2]_ [3]_","Clang (including clang-cl [4]_ and armclang) extensions (up to Clang 19.1.0), + C/C++,"C89, C99, C11, C17, C23, C++98, C++03, C++11, C++14, C++17, C++20, C++23 [1]_ [2]_ [3]_","Clang (including clang-cl [4]_ and armclang) extensions (up to Clang 21), - GNU extensions (up to GCC 15.0), + GNU extensions (up to GCC 15), Microsoft extensions (up to VS 2022), From 0541dc24b5fd706d9fb33ceb4a1ac6a2a20868a5 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 11 Dec 2025 14:39:11 +0100 Subject: [PATCH 3/5] C++: Add `cpp/constant-comparison` FP test cases after frontend update --- .../PointlessComparison.expected | 5 +++ .../PointlessComparison/RegressionTests.cpp | 31 +++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.expected b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.expected index 6c273b985eeb..4758d2ad04a7 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.expected @@ -50,4 +50,9 @@ | PointlessComparison.cpp:43:6:43:29 | ... >= ... | Comparison is always true because ... >> ... >= 140737488355327.5. | | PointlessComparison.cpp:44:6:44:28 | ... >= ... | Comparison is always true because ... >> ... >= 140737488355327.5. | | RegressionTests.cpp:57:7:57:22 | ... <= ... | Comparison is always true because * ... <= 4294967295. | +| RegressionTests.cpp:131:17:131:25 | ... < ... | Comparison is always true because 43 <= ... + .... | +| RegressionTests.cpp:135:26:135:52 | ... < ... | Comparison is always false because 16 >= ... * .... | +| RegressionTests.cpp:140:50:140:61 | ... < ... | Comparison is always false because ... * ... >= 84. | +| RegressionTests.cpp:154:21:154:31 | ... < ... | Comparison is always false because ... - ... >= 34. | +| RegressionTests.cpp:154:21:154:31 | ... < ... | Comparison is always false because ... - ... >= 38. | | Templates.cpp:9:10:9:24 | ... <= ... | Comparison is always true because local <= 32767. | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/RegressionTests.cpp b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/RegressionTests.cpp index 9813a07e29d4..17972a2536ff 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/RegressionTests.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/RegressionTests.cpp @@ -124,3 +124,34 @@ void testTempObject() { f(&x); if (x > 0) {} // GOOD [NO LONGER REPORTED] } + +void staticAssert() { + static const int a = 42; + static const int b = 43; + static_assert(a < b + 0, ""); // GOOD [FALSE POSITIVE] +} + +constexpr int global_1 = 42; +constexpr int global_2 = global_1 < 2 * sizeof(int*) ? 43 : 2 * sizeof(int*); // GOOD [FALSE POSITIVE] + +static const int global_3 = 42; +static const int global_4 = global_3 < 2 * sizeof(int*) ? 43 : 2 * sizeof(int*); // GOOD + +template +struct templateCompare : public templateCompare // GOOD [FALSE POSITIVE] +{ }; + +template< unsigned int p, unsigned int n> +struct templateCompare< p, n, false> +{ + static const unsigned int v = n; +}; + +unsigned int templateCompare_x = templateCompare<42, 42>::v; + +template +struct someType { + typedef someType<((n - 4) < 0 ? 0 : n - 4)> b; // GOOD [FALSE POSITIVE] +}; + +someType<42>::b someType_x; From ae5b58c49da007c987d9cac4059364e79c1fcb65 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 4 Dec 2025 23:09:48 +0100 Subject: [PATCH 4/5] C++: Exclude more comparisons from `cpp/constant-comparison` --- cpp/ql/src/Likely Bugs/Arithmetic/PointlessComparison.ql | 5 ++++- .../PointlessComparison/PointlessComparison.expected | 5 ----- .../Arithmetic/PointlessComparison/RegressionTests.cpp | 8 ++++---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessComparison.ql b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessComparison.ql index e2fe02be867f..df6648b5ff4b 100644 --- a/cpp/ql/src/Likely Bugs/Arithmetic/PointlessComparison.ql +++ b/cpp/ql/src/Likely Bugs/Arithmetic/PointlessComparison.ql @@ -25,11 +25,14 @@ import UnsignedGEZero // // So to reduce the number of false positives, we do not report a result if // the comparison is in a macro expansion. Similarly for template -// instantiations. +// instantiations, static asserts, non-type template arguments, and constexprs. from ComparisonOperation cmp, SmallSide ss, float left, float right, boolean value, string reason where not cmp.isInMacroExpansion() and not cmp.isFromTemplateInstantiation(_) and + not exists(StaticAssert s | s.getCondition() = cmp.getParent*()) and + not exists(Declaration d | d.getATemplateArgument() = cmp.getParent*()) and + not exists(Variable v | v.isConstexpr() | v.getInitializer().getExpr() = cmp.getParent*()) and not functionContainsDisabledCode(cmp.getEnclosingFunction()) and reachablePointlessComparison(cmp, left, right, value, ss) and // a comparison between an enum and zero is always valid because whether diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.expected b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.expected index 4758d2ad04a7..6c273b985eeb 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.expected @@ -50,9 +50,4 @@ | PointlessComparison.cpp:43:6:43:29 | ... >= ... | Comparison is always true because ... >> ... >= 140737488355327.5. | | PointlessComparison.cpp:44:6:44:28 | ... >= ... | Comparison is always true because ... >> ... >= 140737488355327.5. | | RegressionTests.cpp:57:7:57:22 | ... <= ... | Comparison is always true because * ... <= 4294967295. | -| RegressionTests.cpp:131:17:131:25 | ... < ... | Comparison is always true because 43 <= ... + .... | -| RegressionTests.cpp:135:26:135:52 | ... < ... | Comparison is always false because 16 >= ... * .... | -| RegressionTests.cpp:140:50:140:61 | ... < ... | Comparison is always false because ... * ... >= 84. | -| RegressionTests.cpp:154:21:154:31 | ... < ... | Comparison is always false because ... - ... >= 34. | -| RegressionTests.cpp:154:21:154:31 | ... < ... | Comparison is always false because ... - ... >= 38. | | Templates.cpp:9:10:9:24 | ... <= ... | Comparison is always true because local <= 32767. | diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/RegressionTests.cpp b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/RegressionTests.cpp index 17972a2536ff..84936325e823 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/RegressionTests.cpp +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/RegressionTests.cpp @@ -128,17 +128,17 @@ void testTempObject() { void staticAssert() { static const int a = 42; static const int b = 43; - static_assert(a < b + 0, ""); // GOOD [FALSE POSITIVE] + static_assert(a < b + 0, ""); // GOOD } constexpr int global_1 = 42; -constexpr int global_2 = global_1 < 2 * sizeof(int*) ? 43 : 2 * sizeof(int*); // GOOD [FALSE POSITIVE] +constexpr int global_2 = global_1 < 2 * sizeof(int*) ? 43 : 2 * sizeof(int*); // GOOD static const int global_3 = 42; static const int global_4 = global_3 < 2 * sizeof(int*) ? 43 : 2 * sizeof(int*); // GOOD template -struct templateCompare : public templateCompare // GOOD [FALSE POSITIVE] +struct templateCompare : public templateCompare // GOOD { }; template< unsigned int p, unsigned int n> @@ -151,7 +151,7 @@ unsigned int templateCompare_x = templateCompare<42, 42>::v; template struct someType { - typedef someType<((n - 4) < 0 ? 0 : n - 4)> b; // GOOD [FALSE POSITIVE] + typedef someType<((n - 4) < 0 ? 0 : n - 4)> b; // GOOD }; someType<42>::b someType_x; From 9e3d77210eb69dd3dc969f6561d9886d47749527 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Thu, 11 Dec 2025 15:27:16 +0100 Subject: [PATCH 5/5] C++: Accept test changes after frontend update and uncomment test case The new frontend version does less constant folding. --- cpp/ql/test/library-tests/constants/addresses/addresses.cpp | 4 +--- .../library-tests/constants/addresses/addresses.expected | 5 +++++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/cpp/ql/test/library-tests/constants/addresses/addresses.cpp b/cpp/ql/test/library-tests/constants/addresses/addresses.cpp index b15a6324878e..13d748771f2f 100644 --- a/cpp/ql/test/library-tests/constants/addresses/addresses.cpp +++ b/cpp/ql/test/library-tests/constants/addresses/addresses.cpp @@ -26,9 +26,7 @@ void constantAddresses(int param) { constexpr int *array2d = &int_arr_arr[1][1] + 1; constexpr int *const_ints = &int_arr_arr[int_const][extern_int_const]; - // Commented out because clang and EDG disagree on whether this is - // constant. - //constexpr int *stmtexpr_int = &int_arr[ ({ 1; }) ]; + constexpr int *stmtexpr_int = &int_arr[ ({ 1; }) ]; constexpr int *comma_int = &int_arr[ ((void)0, 1) ]; constexpr int *comma_addr = ((void)0, &int_var); diff --git a/cpp/ql/test/library-tests/constants/addresses/addresses.expected b/cpp/ql/test/library-tests/constants/addresses/addresses.expected index e69de29bb2d1..e96a08b04047 100644 --- a/cpp/ql/test/library-tests/constants/addresses/addresses.expected +++ b/cpp/ql/test/library-tests/constants/addresses/addresses.expected @@ -0,0 +1,5 @@ +| addresses.cpp:29:35:29:54 | & ... | stmtexpr_int | misclassified as NOT constant | +| addresses.cpp:31:32:31:55 | & ... | comma_int | misclassified as NOT constant | +| addresses.cpp:36:39:36:70 | ... ? ... : ... | ternary_ptr_cond | misclassified as NOT constant | +| addresses.cpp:37:35:37:69 | & ... | ptr_subtract | misclassified as NOT constant | +| addresses.cpp:39:35:39:50 | ... + ... | constexpr_va | misclassified as NOT constant |