Converting a pointer to an integer whose result cannot represented in the
integer type is undefined behavior is C and prohibited in C++. C++ already
has a diagnostic when casting. This adds a diagnostic for C.
Since this diagnostic uses the range of the conversion it also modifies
int-to-pointer-cast diagnostic to use a range.
Fixes PR8718: No warning on casting between pointer and non-pointer-sized int
Differential Revision: https://reviews.llvm.org/D72231
This patch is a different approach to landing the reverted r349701.
It is expected to have the same object (memory region) treated as if it has
different types in different program points. The correct behavior for
RegionStore when an object is stored as an object of type T1 but loaded as
an object of type T2 is to store the object as if it has type T1 but cast it
to T2 during load.
Note that the cast here is some sort of a "reinterpret_cast" (even in C). For
instance, if you store an integer and load a float, you won't get your integer
represented as a float; instead, you will get garbage.
Admit that we cannot perform the cast and return an unknown value.
Differential Revision: https://reviews.llvm.org/D55875
rdar://problem/45062567
llvm-svn: 349984
This reverts commit r349701.
The patch was incorrect. The whole point of CastRetrievedVal()
is to handle the case in which the type from which the cast is made
(i.e., the "type" of value `V`) has nothing to do with the type of
the region it was loaded from (i.e., `R->getValueType()`).
Differential Revision: https://reviews.llvm.org/D55875
rdar://problem/45062567
llvm-svn: 349798
It is expected to have the same object (memory region) treated as if it has
different types in different program points. The correct behavior for
RegionStore when an object is stored as an object of type T1 but loaded as
an object of type T2 is to store the object as if it has type T1 but cast it
to T2 during load.
Note that the cast here is some sort of a "reinterpret_cast" (even in C). For
instance, if you store a float and load an integer, you won't have your float
rounded to an integer; instead, you will have garbage.
Admit that we cannot perform the cast as long as types we're dealing with are
non-trivial (neither integers, nor pointers).
Of course, if the cast is not necessary (eg, T1 == T2), we can still load the
value just fine.
Differential Revision: https://reviews.llvm.org/D55875
rdar://problem/45062567
llvm-svn: 349701
By making sure the returned value from getKnownSVal is consistent with
the value used inside expression engine.
PR38427
Differential Revision: https://reviews.llvm.org/D51252
llvm-svn: 340965
It now actually produces a signed APSInt when the QualType passed into it is
signed, which is what any caller would expect.
Fixes a couple of crashes.
Differential Revision: https://reviews.llvm.org/D50363
llvm-svn: 339088
This fix is similar to r337769 and addresses a regression caused by r337167.
When an operation between a nonloc::LocAsInteger and a non-pointer symbol
is performed, the LocAsInteger-specific part of information is lost.
When the non-pointer symbol is collapsing into a constant, we cannot easily
re-evaluate the result, because we need to recover the missing
LocAsInteger-specific information (eg., integer type, or the very fact that
this pointer was at some point converted to an integer).
Add one more defensive check to prevent crashes on trying to simplify a
SymSymExpr with different Loc-ness of operands.
Differential Revision:
llvm-svn: 338420
Remove an assertion in RangeConstraintManager that expects such symbols to never
appear, while admitting that the constraint manager doesn't yet handle them.
Differential Revision: https://reviews.llvm.org/D49703
llvm-svn: 337769
C allows us to write any bytes into any memory region. When loading weird bytes
from memory regions of known types, the analyzer is required to make sure that
the loaded value makes sense by casting it to an appropriate type.
Fix such cast for loading values that represent void pointers from non-void
pointer type places.
Differential Revision: https://reviews.llvm.org/D46415
llvm-svn: 331562
The checker used to crash when a mempcpy's length argument is symbolic. In this
case the cast from 'void *' to 'char *' failed because the respective
ElementRegion that represents cast is hard to add on top of the existing
ElementRegion that represents the offset to the last copied byte, while
preseving a sane memory region structure.
Additionally, a few test cases are added (to casts.c) which demonstrate problems
caused by existing sloppy work we do with multi-layer ElementRegions. If said
cast would be modeled properly in the future, these tests would need to be
taken into account.
Differential Revision: https://reviews.llvm.org/D38797
llvm-svn: 315742
If the value is known, but we cannot increment it, conjure a symbol to
represent the result of the operation based on the operator expression,
not on the sub-expression.
In particular, no longer crash on comparing a result of a LocAsInteger increment
to a constant integer.
rdar://problem/31067356
Differential Revision: https://reviews.llvm.org/D31289
llvm-svn: 298927
null comparison when the pointer is known to be non-null.
This catches the array to pointer decay, function to pointer decay and
address of variables. This does not catch address of function since this
has been previously used to silence a warning.
Pointer to bool conversion is under -Wbool-conversion.
Pointer to null comparison is under -Wtautological-pointer-compare, a sub-group
of -Wtautological-compare.
void foo() {
int arr[5];
int x;
// warn on these conditionals
if (foo);
if (arr);
if (&x);
if (foo == null);
if (arr == null);
if (&x == null);
if (&foo); // no warning
}
llvm-svn: 202216
This doesn't appear to be the cause of the slowdown. I'll have to try a
manual bisect to see if there's really anything there, or if it's just
the bot itself taking on additional load. Meanwhile, this change helps
with correctness.
This changes an assertion and adds a test case, then re-applies r180638,
which was reverted in r180714.
<rdar://problem/13296133> and PR15863
llvm-svn: 180864
This seems to be causing quite a slowdown on our internal analyzer bot,
and I'm not sure why. Needs further investigation.
This reverts r180638 / 9e161ea981f22ae017b6af09d660bfc3ddf16a09.
llvm-svn: 180714
Casts to bool (and _Bool) are equivalent to checks against zero,
not truncations to 1 bit or 8 bits.
This improved reasoning does cause a change in the behavior of the alpha
BoolAssignment checker. Previously, this checker complained about statements
like "bool x = y" if 'y' was known not to be 0 or 1. Now it does not, since
that conversion is well-defined. It's hard to say what the "best" behavior
here is: this conversion is safe, but might be better written as an explicit
comparison against zero.
More usefully, besides improving our model of booleans, this fixes spurious
warnings when returning the address of a local variable cast to bool.
<rdar://problem/13296133>
llvm-svn: 180638
to reason about.
As part of taint propagation, we now allow creation of non-integer
symbolic expressions like a cast from int to float.
Addresses PR12511 (radar://11215362).
llvm-svn: 156578
- This is designed to make it obvious that %clang_cc1 is a "test variable"
which is substituted. It is '%clang_cc1' instead of '%clang -cc1' because it
can be useful to redefine what gets run as 'clang -cc1' (for example, to set
a default target).
llvm-svn: 91446