From da7da80b2b1ec88e0b14e0313ed88e133c3d28fb Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Tue, 10 Mar 2026 08:42:05 +0000 Subject: [PATCH 1/6] C++: Add pseudo-buildless test cases (some missing declarations). --- .../Arithmetic/IntMultToLong/Buildless.c | 28 +++++++++++++++++++ .../IntMultToLong/IntMultToLong.expected | 5 ++++ 2 files changed, 33 insertions(+) create mode 100644 cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/Buildless.c diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/Buildless.c b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/Buildless.c new file mode 100644 index 000000000000..8f14110a3b93 --- /dev/null +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/Buildless.c @@ -0,0 +1,28 @@ +// semmle-extractor-options: --expect_errors + +void test_float_double1(float f, double d) { + float r1 = f * f; // GOOD + float r2 = f * d; // GOOD + double r3 = f * f; // BAD + double r4 = f * d; // GOOD + + float f1 = fabsf(f * f); // GOOD [FALSE POSITIVE] + float f2 = fabsf(f * d); // GOOD + double f3 = fabs(f * f); // BAD + double f4 = fabs(f * d); // GOOD +} + +double fabs(double f); +float fabsf(float f); + +void test_float_double2(float f, double d) { + float r1 = f * f; // GOOD + float r2 = f * d; // GOOD + double r3 = f * f; // BAD + double r4 = f * d; // GOOD + + float f1 = fabsf(f * f); // GOOD + float f2 = fabsf(f * d); // GOOD + double f3 = fabs(f * f); // BAD + double f4 = fabs(f * d); // GOOD +} diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected index 2806aaa809fe..1a2427beb20e 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected @@ -1,3 +1,8 @@ +| Buildless.c:6:17:6:21 | ... * ... | Multiplication result may overflow 'float' before it is converted to 'double'. | +| Buildless.c:9:22:9:26 | ... * ... | Multiplication result may overflow 'float' before it is converted to 'double'. | +| Buildless.c:11:22:11:26 | ... * ... | Multiplication result may overflow 'float' before it is converted to 'double'. | +| Buildless.c:21:17:21:21 | ... * ... | Multiplication result may overflow 'float' before it is converted to 'double'. | +| Buildless.c:26:22:26:26 | ... * ... | Multiplication result may overflow 'float' before it is converted to 'double'. | | IntMultToLong.c:4:10:4:14 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'long long'. | | IntMultToLong.c:7:16:7:20 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'long long'. | | IntMultToLong.c:18:19:18:23 | ... * ... | Multiplication result may overflow 'float' before it is converted to 'double'. | From 00d8a100515db3cf39cc8531bf5964e81b98fc64 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 11 Mar 2026 17:42:30 +0000 Subject: [PATCH 2/6] C++: Add Function.hasAmbiguousReturnType. --- cpp/ql/lib/semmle/code/cpp/Function.qll | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cpp/ql/lib/semmle/code/cpp/Function.qll b/cpp/ql/lib/semmle/code/cpp/Function.qll index 10b156e3fb64..b5ea5b3cbc73 100644 --- a/cpp/ql/lib/semmle/code/cpp/Function.qll +++ b/cpp/ql/lib/semmle/code/cpp/Function.qll @@ -524,6 +524,14 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function { not exists(NewOrNewArrayExpr new | e = new.getAllocatorCall().getArgument(0)) ) } + + /** + * Holds if this function has ambiguous return type (this occurs sometimes in + * Build Mode None). + */ + predicate hasAmbiguousReturnType() { + count(this.getType()) != 1 + } } pragma[noinline] From 6552c849f0d05d706b1cff7fe5ff21ff0d345f1e Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 11 Mar 2026 15:42:28 +0000 Subject: [PATCH 3/6] C++: Fix BMN issue in cpp/integer-multiplication-cast-to-long. --- cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql | 4 +++- .../Likely Bugs/Arithmetic/IntMultToLong/Buildless.c | 6 +++--- .../Arithmetic/IntMultToLong/IntMultToLong.expected | 3 --- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql b/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql index a54ac9020c8c..6747d177c80e 100644 --- a/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql +++ b/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql @@ -218,7 +218,9 @@ where // only report if we cannot prove that the result of the // multiplication will be less (resp. greater) than the // maximum (resp. minimum) number we can compute. - overflows(me, t1) + overflows(me, t1) and + // exclude cases where the expression type may not have been extracted accurately + not me.getParent().(Call).getTarget().hasAmbiguousReturnType() select me, "Multiplication result may overflow '" + me.getType().toString() + "' before it is converted to '" + me.getFullyConverted().getType().toString() + "'." diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/Buildless.c b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/Buildless.c index 8f14110a3b93..3d01a28fae0a 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/Buildless.c +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/Buildless.c @@ -6,9 +6,9 @@ void test_float_double1(float f, double d) { double r3 = f * f; // BAD double r4 = f * d; // GOOD - float f1 = fabsf(f * f); // GOOD [FALSE POSITIVE] + float f1 = fabsf(f * f); // GOOD float f2 = fabsf(f * d); // GOOD - double f3 = fabs(f * f); // BAD + double f3 = fabs(f * f); // BAD [NOT DETECTED] double f4 = fabs(f * d); // GOOD } @@ -23,6 +23,6 @@ void test_float_double2(float f, double d) { float f1 = fabsf(f * f); // GOOD float f2 = fabsf(f * d); // GOOD - double f3 = fabs(f * f); // BAD + double f3 = fabs(f * f); // BAD [NOT DETECTED] double f4 = fabs(f * d); // GOOD } diff --git a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected index 1a2427beb20e..05b2b7e1ea3c 100644 --- a/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected +++ b/cpp/ql/test/query-tests/Likely Bugs/Arithmetic/IntMultToLong/IntMultToLong.expected @@ -1,8 +1,5 @@ | Buildless.c:6:17:6:21 | ... * ... | Multiplication result may overflow 'float' before it is converted to 'double'. | -| Buildless.c:9:22:9:26 | ... * ... | Multiplication result may overflow 'float' before it is converted to 'double'. | -| Buildless.c:11:22:11:26 | ... * ... | Multiplication result may overflow 'float' before it is converted to 'double'. | | Buildless.c:21:17:21:21 | ... * ... | Multiplication result may overflow 'float' before it is converted to 'double'. | -| Buildless.c:26:22:26:26 | ... * ... | Multiplication result may overflow 'float' before it is converted to 'double'. | | IntMultToLong.c:4:10:4:14 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'long long'. | | IntMultToLong.c:7:16:7:20 | ... * ... | Multiplication result may overflow 'int' before it is converted to 'long long'. | | IntMultToLong.c:18:19:18:23 | ... * ... | Multiplication result may overflow 'float' before it is converted to 'double'. | From 4a39055322bff79e0f2e4d3c3e283c6291440e19 Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Wed, 11 Mar 2026 17:52:34 +0000 Subject: [PATCH 4/6] C++: Change note. --- .../2026-03-11-integer-multiplication-cast-to-long.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 cpp/ql/src/change-notes/2026-03-11-integer-multiplication-cast-to-long.md diff --git a/cpp/ql/src/change-notes/2026-03-11-integer-multiplication-cast-to-long.md b/cpp/ql/src/change-notes/2026-03-11-integer-multiplication-cast-to-long.md new file mode 100644 index 000000000000..a0efd8a87852 --- /dev/null +++ b/cpp/ql/src/change-notes/2026-03-11-integer-multiplication-cast-to-long.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Fixed an issue with the "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query causing false positive results in Build Mode Node databases. From 2f7526d70bfd9498dda4868bb3b0311957bab13c Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 16 Mar 2026 16:38:29 +0000 Subject: [PATCH 5/6] C++: Clarify doc comment and make build-mode: nonereferences more consistent. --- cpp/ql/lib/semmle/code/cpp/Function.qll | 4 ++-- .../2026-03-11-integer-multiplication-cast-to-long.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/Function.qll b/cpp/ql/lib/semmle/code/cpp/Function.qll index b5ea5b3cbc73..4ed678f90eb8 100644 --- a/cpp/ql/lib/semmle/code/cpp/Function.qll +++ b/cpp/ql/lib/semmle/code/cpp/Function.qll @@ -526,8 +526,8 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function { } /** - * Holds if this function has ambiguous return type (this occurs sometimes in - * Build Mode None). + * Holds if this function has an ambiguous return type, meaning that zero or multiple return + * types for this function are present in the database (this can occur in `build-mode: none`). */ predicate hasAmbiguousReturnType() { count(this.getType()) != 1 diff --git a/cpp/ql/src/change-notes/2026-03-11-integer-multiplication-cast-to-long.md b/cpp/ql/src/change-notes/2026-03-11-integer-multiplication-cast-to-long.md index a0efd8a87852..4d4a66c0a226 100644 --- a/cpp/ql/src/change-notes/2026-03-11-integer-multiplication-cast-to-long.md +++ b/cpp/ql/src/change-notes/2026-03-11-integer-multiplication-cast-to-long.md @@ -1,4 +1,4 @@ --- category: minorAnalysis --- -* Fixed an issue with the "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query causing false positive results in Build Mode Node databases. +* Fixed an issue with the "Multiplication result converted to larger type" (`cpp/integer-multiplication-cast-to-long`) query causing false positive results in `build-mode: none` databases. From 8df4dfb585370d003261f646ead59e3d3f5cea1a Mon Sep 17 00:00:00 2001 From: Geoffrey White <40627776+geoffw0@users.noreply.github.com> Date: Mon, 16 Mar 2026 16:40:27 +0000 Subject: [PATCH 6/6] C++: Autoformat. --- cpp/ql/lib/semmle/code/cpp/Function.qll | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/Function.qll b/cpp/ql/lib/semmle/code/cpp/Function.qll index 4ed678f90eb8..8d93ac0f2a3a 100644 --- a/cpp/ql/lib/semmle/code/cpp/Function.qll +++ b/cpp/ql/lib/semmle/code/cpp/Function.qll @@ -529,9 +529,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function { * Holds if this function has an ambiguous return type, meaning that zero or multiple return * types for this function are present in the database (this can occur in `build-mode: none`). */ - predicate hasAmbiguousReturnType() { - count(this.getType()) != 1 - } + predicate hasAmbiguousReturnType() { count(this.getType()) != 1 } } pragma[noinline]