Skip to content

Commit 878cdf7

Browse files
C++: Fix false positive in PointlessComparison
We avoid putting a variable into SSA if its address is ever taken in a way that could allow mutation of the variable via indirection. We currently just look to see if the address is either "pointer to non-const" or "reference to non-const". However, if the address was cast to an integral type (e.g. `uintptr_t n = (uintptr_t)&x;`), we were treating it as unescaped. This change makes the conservative assumption that casting a pointer to an integer may result in the pointed-to value being modified later. This fixes a customer-reported false positive (#2 from https://discuss.lgtm.com/t/2-false-positives-in-c-for-comparison-is-always-same/1943)
1 parent 5101a5b commit 878cdf7

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

cpp/ql/src/semmle/code/cpp/dataflow/EscapesTree.qll

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,10 @@ private predicate valueMayEscapeMutablyAt(Expr e) {
198198
or
199199
t instanceof ReferenceType and
200200
not t.(ReferenceType).getBaseType().isConst()
201+
or
202+
// If the address has been cast to an integral type, conservatively assume that it may eventually be cast back to a
203+
// pointer to non-const type.
204+
t instanceof IntegralType
201205
)
202206
}
203207

cpp/ql/test/query-tests/Likely Bugs/Arithmetic/PointlessComparison/PointlessComparison.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,3 +342,25 @@ int nan2(double x) {
342342
}
343343
}
344344
}
345+
346+
struct info_t {
347+
int id;
348+
unsigned long long value;
349+
};
350+
351+
int command(void* p, unsigned int s);
352+
353+
int callCommand(void)
354+
{
355+
struct info_t info;
356+
unsigned int tmp = 0;
357+
358+
info.id = 1;
359+
info.value = (unsigned long long)& tmp;
360+
if (command(&info, sizeof(info))) {
361+
return 0;
362+
}
363+
if (tmp == 1) // tmp could have been modified by the call.
364+
return 1;
365+
return 0;
366+
}

0 commit comments

Comments
 (0)