Summary:
There is a problem with analyzer that a wrong value is given when modeling the increment operator of the operand with type bool. After `rL307604` is applied, a unsigned overflow may occur.
Example:
```
void func() {
bool b = true;
// unsigned overflow occur, 2 -> 0 U1b
b++;
}
```
The use of an operand of type bool with the ++ operators is deprecated but valid untill C++17. And if the operand of the increment operator is of type bool, it is set to true.
This patch includes two parts:
- If the operand of the increment operator is of type bool or type _Bool, set to true.
- Modify `BasicValueFactory::getTruthValue()`, use `getIntWidth()` instead `getTypeSize()` and use `unsigned` instead `signed`.
Reviewers: alexshap, NoQ, dcoughlin, george.karpenkov
Reviewed By: NoQ
Subscribers: xazax.hun, szepet, a.sidorin, cfe-commits, MTC
Differential Revision: https://reviews.llvm.org/D43741
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@326776 91177308-0d34-0410-b5e6-96231b3b80d8
The assertion gets exposed when changing the exploration order.
This is a quick hacky fix, but the intention is that if the nodes do
merge, it should not matter which predecessor should be traverse.
A proper fix would be not to traverse predecessors at all, as all
information relevant for any decision should be avilable locally.
rdar://37540480
Differential Revision: https://reviews.llvm.org/D42773
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325977 91177308-0d34-0410-b5e6-96231b3b80d8
We didn't support the following syntax:
(std::initializer_list<int>){12}
which suddenly produces CompoundLiteralExpr that contains
CXXStdInitializerListExpr.
Lift the assertion and instead pass the value through CompoundLiteralExpr
transparently, as it doesn't add much.
Differential Revision: https://reviews.llvm.org/D39803
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@319058 91177308-0d34-0410-b5e6-96231b3b80d8
Do not crash when trying to compute x && y or x || y where x and y are
of a vector type.
For now we do not seem to properly model operations with vectors. In particular,
operations && and || on a pair of vectors are not short-circuit, unlike regular
logical operators, so even our CFG is incorrect.
Avoid the crash, add respective FIXME tests for later.
Differential Revision: https://reviews.llvm.org/D39682
rdar://problem/34317663
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@317700 91177308-0d34-0410-b5e6-96231b3b80d8
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
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@298927 91177308-0d34-0410-b5e6-96231b3b80d8
The patch also simplifies an assume of a constraint of the form: "(exp comparison_op expr) != 0" to true into an assume of "exp comparison_op expr" to true. (And similarly, an assume of the form "(exp comparison_op expr) == 0" to true as an assume of exp comparison_op expr to false.) which improves precision overall.
https://reviews.llvm.org/D22862
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@290505 91177308-0d34-0410-b5e6-96231b3b80d8
The patch also simplifies an assume of a constraint of the form: "(exp comparison_op expr) != 0" to true into an assume of "exp comparison_op expr" to true. (And similarly, an assume of the form "(exp comparison_op expr) == 0" to true as an assume of exp comparison_op expr to false.) which improves precision overall.
https://reviews.llvm.org/D22862
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@290413 91177308-0d34-0410-b5e6-96231b3b80d8
Add a new type of NonLoc SVal for C++ pointer-to-member operations. This SVal
supports both pointers to member functions and pointers to member data.
A patch by Kirill Romanenkov!
Differential Revision: https://reviews.llvm.org/D25475
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@289873 91177308-0d34-0410-b5e6-96231b3b80d8
latter case, a temporary array object is materialized, and can be
lifetime-extended by binding a reference to the member access. Likewise, in an
array-to-pointer decay, an rvalue array is materialized before being converted
into a pointer.
This caused IR generation to stop treating file-scope array compound literals
as having static storage duration in some cases in C++; that has been rectified
by modeling such a compound literal as an lvalue. This also improves clang's
compatibility with GCC for those cases.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@288654 91177308-0d34-0410-b5e6-96231b3b80d8
Dynamic casts are handled relatively well by the static analyzer.
BaseToDerived casts however are treated conservatively. This can cause some
false positives with the NewDeleteLeaks checker.
This patch alters the behavior of BaseToDerived casts. In case a dynamic cast
would succeed use the same semantics. Otherwise fall back to the conservative
approach.
Differential Revision: https://reviews.llvm.org/D23014
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@277989 91177308-0d34-0410-b5e6-96231b3b80d8
Currently Clang use int32 to represent sampler_t, which have been a source of issue for some backends, because in some backends sampler_t cannot be represented by int32. They have to depend on kernel argument metadata and use IPA to find the sampler arguments and global variables and transform them to target specific sampler type.
This patch uses opaque pointer type opencl.sampler_t* for sampler_t. For each use of file-scope sampler variable, it generates a function call of __translate_sampler_initializer. For each initialization of function-scope sampler variable, it generates a function call of __translate_sampler_initializer.
Each builtin library can implement its own __translate_sampler_initializer(). Since the real sampler type tends to be architecture dependent, allowing it to be initialized by a library function simplifies backend design. A typical implementation of __translate_sampler_initializer could be a table lookup of real sampler literal values. Since its argument is always a literal, the returned pointer is known at compile time and easily optimized to finally become some literal values directly put into image read instructions.
This patch is partially based on Alexey Sotkin's work in Khronos Clang (3d4eec6162).
Differential Revision: https://reviews.llvm.org/D21567
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@277024 91177308-0d34-0410-b5e6-96231b3b80d8
In {CG,}ExprConstant.cpp, we weren't treating vector splats properly.
This patch makes us treat splats more properly.
Additionally, this patch adds a new cast kind which allows a bool->int
cast to result in -1 or 0, instead of 1 or 0 (for true and false,
respectively), so we can sanely model OpenCL bool->int casts in the AST.
Differential Revision: http://reviews.llvm.org/D14877
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@257559 91177308-0d34-0410-b5e6-96231b3b80d8
The current workaround for truncations not being modelled is that the evaluation of integer to integer casts are simply bypassed and so the original symbol is used as the new casted symbol (cf SimpleSValBuilder::evalCastFromNonLoc).
This lead to the issue described in PR25078, as the RangeConstraintManager associates ranges with symbols.
The new evalIntegralCast method added by this patch wont bypass the cast if it finds the range of the symbol to be greater than the maximum value of the target type.
The fix to RangeSet::pin mentioned in the initial review will be committed separately.
Differential Revision: http://reviews.llvm.org/D12901
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@257464 91177308-0d34-0410-b5e6-96231b3b80d8
When the analyzer evaluates a CXXConstructExpr, it looks ahead in the CFG for
the current block to detect what region the object should be constructed into.
If the constructor was directly constructed into a local variable or field
region then there is no need to explicitly bind the constructed value to
the local or field when analyzing the DeclStmt or CXXCtorInitializer that
called the constructor.
Unfortunately, there were situations in which the CXXConstructExpr was
constructed into a temporary region but when evaluating the corresponding
DeclStmt or CXXCtorInitializer the analyzer assumed the object was constructed
into the local or field. This led to spurious warnings about uninitialized
values (PR25777).
To avoid these false positives, this commit factors out the logic for
determining when a CXXConstructExpr will be directly constructed into existing
storage, adds the inverse logic to detect when the corresponding later bind can
be safely skipped, and adds assertions to make sure these two checks are in
sync.
rdar://problem/21947725
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@255859 91177308-0d34-0410-b5e6-96231b3b80d8
clang converts C++ lambdas to blocks with an implicit user-defined conversion
operator method on the lambda record. This method returns a block that captures a copy
of the lambda. To inline a lambda-converted block, the analyzer now calls the lambda
records's call operator method on the lambda captured by the block.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@254702 91177308-0d34-0410-b5e6-96231b3b80d8
In llvm commit r243581, a reverse range adapter was added which allows
us to change code such as
for (auto I = Fields.rbegin(), E = Fields.rend(); I != E; ++I) {
in to
for (const FieldDecl *I : llvm::reverse(Fields))
This commit changes a few of the places in clang which are eligible to use
this new adapter.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@243663 91177308-0d34-0410-b5e6-96231b3b80d8
While we don't model pointer-to-member operators yet (neither .* nor ->*),
CallAndMessageChecker still checks to make sure the 'this' object is not
null or undefined first. However, it also expects that the object should
always have a valid MemRegion, something that's generally important elsewhere
in the analyzer as well. Ensure this is true ahead of time, just like we do
for member access.
PR19531
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@207561 91177308-0d34-0410-b5e6-96231b3b80d8
With the introduction of explicit address space casts into LLVM, there's
a need to provide a new cast kind the front-end can create for C/OpenCL/CUDA
and code to produce address space casts from those kinds when appropriate.
Patch by Michele Scandale!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@197036 91177308-0d34-0410-b5e6-96231b3b80d8
This reverts commit r189090.
The original patch introduced regressions (see the added live-variables.* tests). The patch depends on the correctness of live variable analyses, which are not computed correctly. I've opened PR18159 to track the proper resolution to this problem.
The patch was a stepping block to r189746. This is why part of the patch reverts temporary destructor tests that started crashing. The temporary destructors feature is disabled by default.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196593 91177308-0d34-0410-b5e6-96231b3b80d8
No tests because no in-tree checkers use this, but that shouldn't stop
out-of-tree checkers.
Found by Aemon Cannon!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190650 91177308-0d34-0410-b5e6-96231b3b80d8
Summary:
Instead of digging through the ExplodedGraph, to figure out which edge brought
us here, I compute the value of conditional expression by looking at the
sub-expression values.
To do this, I needed to change the liveness algorithm a bit -- now, the full
conditional expression also depends on all atomic sub-expressions, not only the
outermost ones.
Reviewers: jordan_rose
CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D1340
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@189090 91177308-0d34-0410-b5e6-96231b3b80d8
Summary:
ExprEngine had code which specificaly disabled using CXXTempObjectRegions in
InitListExprs. This was a hack put in r168757 to silence a false positive.
The underlying problem seems to have been fixed in the mean time, as removing
this code doesn't seem to break anything. Therefore I propose to remove it and
solve PR16629 in the process.
Reviewers: jordan_rose
CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D1325
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@188059 91177308-0d34-0410-b5e6-96231b3b80d8
While we don't model pointers-to-members besides "null" and "non-null",
we were using Loc symbols for valid pointers and NonLoc integers for the
null case. This hit the assert committed in r185401.
Fixed by using a true (Loc) null for null member pointers.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@185444 91177308-0d34-0410-b5e6-96231b3b80d8
It’s important for us to reason about the cast as it is used in std::addressof. The reason we did not
handle the cast previously was a crash on a test case (see commit r157478). The crash was in
processing array to pointer decay when the region type was not an array. Address the issue, by
just returning an unknown in that case.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@182808 91177308-0d34-0410-b5e6-96231b3b80d8
This occurs because in C++11 the compound literal syntax can trigger a
constructor call via list-initialization. That is, "Point{x, y}" and
"(Point){x, y}" end up being equivalent. If this occurs, the inner
CXXConstructExpr will have already handled the object construction; the
CompoundLiteralExpr just needs to propagate that value forwards.
<rdar://problem/13804098>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@181213 91177308-0d34-0410-b5e6-96231b3b80d8
When computing the value of ?: expression, we rely on the last expression in
the previous basic block to be the resulting value of the expression. This is
not the case for binary "?:" operator (GNU extension) in C++. As the last
basic block has the expression for the condition subexpression, which is an
R-value, whereas the true subexpression is the L-value.
Note the operator evaluation just happens to work in C since the true
subexpression is an R-value (like the condition subexpression). CFG is the
same in C and C++ case, but the AST nodes are different, which the LValue to
Rvalue conversion happening after the BinaryConditionalOperator evaluation.
Changed the logic to only use the last expression from the predecessor only
if it matches either true or false subexpression. Note, the logic needed
fortification anyway: L and R were passed but not even used by the function.
Also, change the conjureSymbolVal to correctly compute the type, when the
expression is an LG-value.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179574 91177308-0d34-0410-b5e6-96231b3b80d8
Previously, the analyzer used isIntegerType() everywhere, which uses the C
definition of "integer". The C++ predicate with the same behavior is
isIntegerOrUnscopedEnumerationType().
However, the analyzer is /really/ using this to ask if it's some sort of
"integrally representable" type, i.e. it should include C++11 scoped
enumerations as well. hasIntegerRepresentation() sounds like the right
predicate, but that includes vectors, which the analyzer represents by its
elements.
This commit audits all uses of isIntegerType() and replaces them with the
general isIntegerOrEnumerationType(), except in some specific cases where
it makes sense to exclude scoped enumerations, or any enumerations. These
cases now use isIntegerOrUnscopedEnumerationType() and getAs<BuiltinType>()
plus BuiltinType::isInteger().
isIntegerType() is hereby banned in the analyzer - lib/StaticAnalysis and
include/clang/StaticAnalysis. :-)
Fixes real assertion failures. PR15703 / <rdar://problem/12350701>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179081 91177308-0d34-0410-b5e6-96231b3b80d8
Use Optional<CFG*> where invalid states were needed previously. In the one case
where that's not possible (beginAutomaticObjDtorsInsert) just use a dummy
CFGAutomaticObjDtor.
Thanks for the help from Jordan Rose & discussion/feedback from Ted Kremenek
and Doug Gregor.
Post commit code review feedback on r175796 by Ted Kremenek.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@175938 91177308-0d34-0410-b5e6-96231b3b80d8