Reapply after fixing the test by enabling the `debug.ExprInspection` checker.
-----
NonLoc symbolic SVal to Loc casts are not supported except for
nonloc::ConcreteInt.
This change simplifies the source SVals so that the more casts can
go through nonloc::ConcreteInt->loc::ConcreteInt path. For example:
void test_simplified_before_cast_add(long long t1) {
long long t2 = t1 + 3;
if (!t2) {
int *p = (int *) t2;
clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
}
}
If simplified, 't2' is 0, resulting 'p' is nullptr, otherwise 'p'
is unknown.
Fixes#62232
This reverts commit 3ebf3dd30da219f9f9aee12f42d45d18d55e7580.
I thought "Mergeing" will wait and confirm if the checks pass, and only
merge it if they succeed. Apparently, it's not the case here xD
The test is just broken in x86. See:
https://lab.llvm.org/buildbot/#/builders/109/builds/73686
NonLoc symbolic SVal to Loc casts are not supported except for
nonloc::ConcreteInt.
This change simplifies the source SVals so that the more casts can go
through nonloc::ConcreteInt->loc::ConcreteInt path. For example:
```c
void test_simplified_before_cast_add(long long t1) {
long long t2 = t1 + 3;
if (!t2) {
int *p = (int *) t2;
clang_analyzer_eval(p == 0); // expected-warning{{TRUE}}
}
}
```
If simplified, `t2` is 0, resulting `p` is nullptr, otherwise `p` is
unknown.
Fixes#62232
This commit releases a checker that was developed to a stable level in
the Ericsson-internal fork of Clang Static Analyzer.
Note that the functionality of this checker overlaps with
core.UndefinedBinaryOperatorResult ("UBOR"), but there are several
differences between them:
(1) UBOR is only triggered when the constant folding performed by the
Clang Static Analyzer engine determines that the value of a binary
operator expression is undefined; this checker can report issues where
the operands are not constants.
(2) UBOR has unrelated checks for handling other binary operators, this
checker only examines bitwise shifts.
(3) This checker has a Pedantic flag and by default does not report
expressions (e.g. -2 << 2) that're undefined by the standard but
consistently supported in practice.
(4) UBOR exhibits buggy behavior in code that involves cast expressions,
e.g.
void foo(unsigned short s) {
if (s == 2) {
(void) ((unsigned int) s) << 16;
}
}
Later it would be good to eliminate this overlap (perhaps by deprecating
and then eliminating the bitwise shift handling in UBOR), but in my
opinion that belongs to separate commits.
Differential Revision: https://reviews.llvm.org/D156312
Co-authored-by: Endre Fulop <endre.fulop@sigmatechnology.se>
Previously, the `SValBuilder` could not encounter expressions of the
following kind:
NonLoc OP Loc
Loc OP NonLoc
Where the `Op` is other than `BO_Add`.
As of now, due to the smarter simplification and the fixedpoint
iteration, it turns out we can.
It can happen if the `Loc` was perfectly constrained to a concrete
value (`nonloc::ConcreteInt`), thus the simplifier can do
constant-folding in these cases as well.
Unfortunately, this could cause assertion failures, since we assumed
that the operator must be `BO_Add`, causing a crash.
---
In the patch, I decided to preserve the original behavior (aka. swap the
operands (if the operator is commutative), but if the `RHS` was a
`loc::ConcreteInt` call `evalBinOpNN()`.
I think this interpretation of the arithmetic expression is closer to
reality.
I also tried naively introducing a separate handler for
`loc::ConcreteInt` RHS, before doing handling the more generic `Loc` RHS
case. However, it broke the `zoo1backwards()` test in the `nullptr.cpp`
file. This highlighted for me the importance to preserve the original
behavior for the `BO_Add` at least.
PS: Sorry for introducing yet another branch into this `evalBinOpXX`
madness. I've got a couple of ideas about refactoring these.
We'll see if I can get to it.
The test file demonstrates the issue and makes sure nothing similar
happens. The `no-crash` annotated lines show, where we crashed before
applying this patch.
Reviewed By: martong
Differential Revision: https://reviews.llvm.org/D115149