Merge pull request #21457 from geoffw0/intmultlong

C++: Fix BMN issue with cpp/integer-multiplication-cast-to-long.
This commit is contained in:
Geoffrey White
2026-03-16 19:02:16 +00:00
committed by GitHub
5 changed files with 43 additions and 1 deletions

View File

@@ -524,6 +524,12 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
not exists(NewOrNewArrayExpr new | e = new.getAllocatorCall().getArgument(0))
)
}
/**
* 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 }
}
pragma[noinline]

View File

@@ -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() + "'."

View File

@@ -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: none` databases.

View File

@@ -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
float f2 = fabsf(f * d); // GOOD
double f3 = fabs(f * f); // BAD [NOT DETECTED]
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 [NOT DETECTED]
double f4 = fabs(f * d); // GOOD
}

View File

@@ -1,3 +1,5 @@
| Buildless.c:6:17:6:21 | ... * ... | 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'. |
| 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'. |