mirror of
https://github.com/github/codeql.git
synced 2026-05-02 12:15:17 +02:00
[CPP-434] Narrow down query.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @name Undefined result of signed test for overflow
|
||||
* @description Testing for oveflow by adding a value to a variable
|
||||
* @description Testing for overflow by adding a value to a variable
|
||||
* to see if it "wraps around" works only for
|
||||
* `unsigned` integer values.
|
||||
* @kind problem
|
||||
@@ -13,18 +13,18 @@
|
||||
|
||||
import cpp
|
||||
|
||||
from RelationalOperation ro, BinaryArithmeticOperation bao, VariableAccess va1, VariableAccess va2
|
||||
from RelationalOperation ro, AddExpr add, VariableAccess va1, VariableAccess va2
|
||||
where
|
||||
ro.getAnOperand() = bao and
|
||||
bao instanceof AddExpr and
|
||||
bao.getAnOperand() = va1 and
|
||||
ro.getAnOperand() = add and
|
||||
add.getAnOperand() = va1 and
|
||||
ro.getAnOperand() = va2 and
|
||||
va1.getTarget() = va2.getTarget() and
|
||||
(not exists(va1.getQualifier()) or va1.getQualifier() = va2.getQualifier()) and
|
||||
/*
|
||||
* if the addition (`bao`) has been promoted to a signed type,
|
||||
* if the addition (`add`) has been promoted to a signed type,
|
||||
* then the other operand (`va2`) must have been likewise promoted and so
|
||||
* have a signed comparison
|
||||
*/
|
||||
|
||||
bao.getFullyConverted().getType().(IntegralType).isSigned()
|
||||
add.getExplicitlyConverted().getType().(IntegralType).isSigned()
|
||||
select ro, "Testing for signed overflow may produce undefined results."
|
||||
|
||||
@@ -27,3 +27,55 @@ bool cannotHoldAnotherUInt(int n1, unsigned int delta) {
|
||||
// msvc 19.22 /O2: not deleted
|
||||
return n1 + delta < n1; // GOOD
|
||||
}
|
||||
|
||||
bool shortShort1(unsigned short n1, unsigned short delta) {
|
||||
// clang 8.0.0 -O2: deleted
|
||||
// gcc 9.2 -O2: deleted
|
||||
// msvc 19.22 /O2: not deleted
|
||||
return n1 + delta < n1; // BAD
|
||||
}
|
||||
|
||||
bool shortShort2(unsigned short n1, unsigned short delta) {
|
||||
// clang 8.0.0 -O2: not deleted
|
||||
// gcc 9.2 -O2: not deleted
|
||||
// msvc 19.22 /O2: not deleted
|
||||
return (unsigned short)(n1 + delta) < n1; // GOOD
|
||||
}
|
||||
|
||||
/* Distinguish `varname` from `ptr->varname` and `obj.varname` */
|
||||
struct N {
|
||||
unsigned short n1;
|
||||
} n, *np;
|
||||
|
||||
bool shortStruct1(unsigned short n1, unsigned short delta) {
|
||||
return np->n1 + delta < n1; // GOOD
|
||||
}
|
||||
|
||||
bool shortStruct1a(unsigned short n1, unsigned short delta) {
|
||||
return n1 + delta < n.n1; // GOOD
|
||||
}
|
||||
|
||||
bool shortStruct2(unsigned short n1, unsigned short delta) {
|
||||
return (unsigned short)(n1 + delta) < n.n1; // GOOD
|
||||
}
|
||||
|
||||
struct se {
|
||||
short xPos;
|
||||
short yPos;
|
||||
short xSize;
|
||||
short ySize;
|
||||
};
|
||||
|
||||
extern se *getSo(void);
|
||||
|
||||
bool func1(se *so) {
|
||||
se *o = getSo();
|
||||
if (so->xPos + so->xSize < o->xPos // GOOD
|
||||
|| so->xPos > o->xPos + o->xSize) { // GOOD
|
||||
// clang 8.0.0 -O2: not deleted
|
||||
// gcc 9.2 -O2: not deleted
|
||||
// msvc 19.22 /O2: not deleted
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
| SignedOverflowCheck.cpp:8:12:8:22 | ... < ... | Testing for signed overflow may produce undefined results. |
|
||||
| SignedOverflowCheck.cpp:18:12:18:26 | ... < ... | Testing for signed overflow may produce undefined results. |
|
||||
| SignedOverflowCheck.cpp:35:9:35:23 | ... < ... | Testing for signed overflow may produce undefined results. |
|
||||
|
||||
Reference in New Issue
Block a user