A node is considered to be trivial if it only has one successor, one
predecessor, and a state equal to the predecessor.
Can drastically (> 2x) reduce the size of the generated exploded
graph.
Differential Revision: https://reviews.llvm.org/D51665
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@341616 91177308-0d34-0410-b5e6-96231b3b80d8
The analyzer doesn't make use of them anyway and they seem to have
pretty weird AST from time to time, so let's just skip them for now.
Fixes a crash reported as pr37769.
Differential Revision: https://reviews.llvm.org/D50855
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@340977 91177308-0d34-0410-b5e6-96231b3b80d8
Once CFG-side support for argument construction contexts landed in r338436,
the analyzer could make use of them to evaluate argument constructors properly.
When evaluated as calls, constructors of arguments now use the variable region
of the parameter as their target. The corresponding stack frame does not yet
exist when the parameter is constructed, and this stack frame is created
eagerly.
Construction of functions whose body is unavailable and of virtual functions
is not yet supported. Part of the reason is the analyzer doesn't consistently
use canonical declarations o identify the function in these cases, and every
re-declaration or potential override comes with its own set of parameter
declarations. Also it is less important because if the function is not
inlined, there's usually no benefit in inlining the argument constructor.
Differential Revision: https://reviews.llvm.org/D49443
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@339745 91177308-0d34-0410-b5e6-96231b3b80d8
Because of incomplete support for CXXDefaultArgExpr, we cannot yet commit to
asserting that the same destructor won't be elided twice.
Suppress the assertion failure for now. Proper support is still an open problem.
Differential Revision: https://reviews.llvm.org/D49213
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@338441 91177308-0d34-0410-b5e6-96231b3b80d8
This is a refactoring patch; no functional change intended.
The common part of ConstructionContextLayer and ConstructedObjectKey is
factored out into a new structure, ConstructionContextItem.
Various sub-kinds of ConstructionContextItem are enumerated in order to
provide richer information about construction contexts.
Differential Revision: https://reviews.llvm.org/D49210.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@338439 91177308-0d34-0410-b5e6-96231b3b80d8
r335795 adds copy elision information to CFG. This commit allows static analyzer
to elide elidable copy constructors by constructing the objects that were
previously subject to elidable copy directly in the target region of the copy.
The chain of elided constructors may potentially be indefinitely long. This
only happens when the object is being returned from a function which in turn is
returned from another function, etc.
NRVO is not supported yet.
Differential Revision: https://reviews.llvm.org/D47671
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@335800 91177308-0d34-0410-b5e6-96231b3b80d8
This diff includes the logic for setting the precision bits for each primary fixed point type in the target info and logic for initializing a fixed point literal.
Fixed point literals are declared using the suffixes
```
hr: short _Fract
uhr: unsigned short _Fract
r: _Fract
ur: unsigned _Fract
lr: long _Fract
ulr: unsigned long _Fract
hk: short _Accum
uhk: unsigned short _Accum
k: _Accum
uk: unsigned _Accum
```
Errors are also thrown for illegal literal values
```
unsigned short _Accum u_short_accum = 256.0uhk; // expected-error{{the integral part of this literal is too large for this unsigned _Accum type}}
```
Differential Revision: https://reviews.llvm.org/D46915
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@335148 91177308-0d34-0410-b5e6-96231b3b80d8
The reasoning behind this change is similar to the previous commit, r334681.
Because members are already in scope when construction occurs, we are not
suffering from liveness problems, but we still want to figure out if the object
was constructed with construction context, because in this case we'll be able
to avoid trivial copy, which we don't always model perfectly. It'd also have
more importance when copy elision is implemented.
This also gets rid of the old CFG look-behind mechanism.
Differential Revision: https://reviews.llvm.org/D47350
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@334682 91177308-0d34-0410-b5e6-96231b3b80d8
When analyzing C++ code, a common operation in the analyzer is to discover
target region for object construction by looking at CFG metadata ("construction
contexts"), and then track the region path-sensitively until object construction
is resolved, where the amount of information, again, depends on construction
context.
Scan construction context only once for both purposes.
Differential Revision: https://reviews.llvm.org/D47304
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@334678 91177308-0d34-0410-b5e6-96231b3b80d8
ExprEngine already maintains three internal program state traits to track
path-sensitive information related to object construction: pointer returned by
operator new, and pointer to temporary object for two different purposes - for
destruction and for lifetime extension. We'll need to add 2-3 more in a few
follow-up commits.
Merge these traits into one because they all essentially serve one purpose and
work similarly.
Differential Revision: https://reviews.llvm.org/D47303
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@333719 91177308-0d34-0410-b5e6-96231b3b80d8
The bindDefault() API of the ProgramState allows setting a default value
for reads from memory regions that were not preceded by writes.
It was used for implementing C++ zeroing constructors (i.e. default constructors
that boil down to setting all fields of the object to 0).
Because differences between zeroing consturctors and other forms of default
initialization have been piling up (in particular, zeroing constructors can be
called multiple times over the same object, probably even at the same offset,
requiring a careful and potentially slow cleanup of previous bindings in the
RegionStore), we split the API in two: bindDefaultInitial() for modeling
initial values and bindDefaultZero() for modeling zeroing constructors.
This fixes a few assertion failures from which the investigation originated.
The imperfect protection from both inability of the RegionStore to support
binding extents and lack of information in ASTRecordLayout has been loosened
because it's, well, imperfect, and it is unclear if it fixing more than it
was breaking.
Differential Revision: https://reviews.llvm.org/D46368
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@331561 91177308-0d34-0410-b5e6-96231b3b80d8
Avoid crash when the sub-expression of operator delete[] is of array type.
This is not the same as simply using a delete[] syntax.
We're still not properly calling destructors in this case in the analyzer.
Differential Revision: https://reviews.llvm.org/D46146
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@331014 91177308-0d34-0410-b5e6-96231b3b80d8
If a pointer cast fails (evaluates to an UnknownVal, i.e. not implemented in the
analyzer) and such cast is in fact the last use of the pointer, the pointer
symbol is no longer referenced by the program state and a leak is
(mis-)diagnosed.
"Escape" the pointer upon a failed cast, i.e. inform the checker that we can no
longer reliably track it.
Differential Revision: https://reviews.llvm.org/D45698
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@330380 91177308-0d34-0410-b5e6-96231b3b80d8
Function return values can be constructed directly in variables or passed
directly into return statements, without even an elidable copy in between.
This is how the C++17 mandatory copy elision AST behaves. The behavior we'll
have in such cases is the "old" behavior that we've had before we've
implemented destructor inlining and proper lifetime extension support.
Differential Revision: https://reviews.llvm.org/D44755
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@328253 91177308-0d34-0410-b5e6-96231b3b80d8
My compiler (clang-3.8) complains that the RCC variable is unused.
That's not really true, as it's checked by the if-declaration, but it's
also kinda true, because we don't need to declaration if we only check
it in the if statement.
In reality, all this means that the dyn_cast<> can be replaced by isa<>,
so that's what I do here.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@327491 91177308-0d34-0410-b5e6-96231b3b80d8
This patch adds a new CFGStmt sub-class, CFGCXXRecordTypedCall, which replaces
the regular CFGStmt for the respective CallExpr whenever the CFG has additional
information to provide regarding the lifetime of the returned value.
This additional call site information is represented by a ConstructionContext
(which was previously used for CFGConstructor elements) that provides references
to CXXBindTemporaryExpr and MaterializeTemporaryExpr that surround the call.
This corresponds to the common C++ calling convention solution of providing
the target address for constructing the return value as an auxiliary implicit
argument during function call.
One of the use cases for such extra context at the call site would be to perform
any sort of inter-procedural analysis over the CFG that involves functions
returning objects by value. In this case the elidable constructor at the return
site would construct the object explained by the context at the call site, and
its lifetime would also be managed by the caller, not the callee.
The extra context would also be useful for properly handling the return-value
temporary at the call site, even if the callee is not being analyzed
inter-procedurally.
Differential Revision: https://reviews.llvm.org/D44120
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@327343 91177308-0d34-0410-b5e6-96231b3b80d8
This patch adds two new CFG elements CFGScopeBegin and CFGScopeEnd that indicate
when a local scope begins and ends respectively. We use first VarDecl declared
in a scope to uniquely identify it and add CFGScopeBegin and CFGScopeEnd elements
into corresponding basic blocks.
Differential Revision: https://reviews.llvm.org/D16403
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@327258 91177308-0d34-0410-b5e6-96231b3b80d8
Proper modeling still remains to be done.
Note that BindingDecl#getHoldingVar() is almost always null, and this
should probably be handled by dealing with DecompositionDecl beforehand.
rdar://36852163
Differential Revision: https://reviews.llvm.org/D44183
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@326951 91177308-0d34-0410-b5e6-96231b3b80d8
Originally submitted as r326323 and r326324.
Reverted in r326432.
Reverting the commit was a mistake.
The breakage was due to invalid build files in our internal buildsystem,
CMakeLists did not have any cyclic dependencies.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@326439 91177308-0d34-0410-b5e6-96231b3b80d8
Also revert "[analyzer] Fix a compiler warning"
This reverts commits r326323 and r326324.
Reason: the commits introduced a cyclic dependency in the build graph.
This happens to work with cmake, but breaks out internal integrate.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@326432 91177308-0d34-0410-b5e6-96231b3b80d8
Sometimes it is not known at compile time which temporary objects will be
constructed, eg. 'x ? A() : B()' or 'C() || D()'. In this case we track which
temporary was constructed to know how to properly call the destructor.
Once the construction context for temporaries was introduced, we moved the
tracking code to the code that investigates the construction context.
Bring back the old mechanism because construction contexts are not always
available yet - eg. in the case where a temporary is constructed without a
constructor expression, eg. returned from a function by value. The mechanism
should still go away eventually.
Additionally, fix a bug in the temporary cleanup code for the case when
construction contexts are not available, which could lead to temporaries
staying in the program state and increasing memory consumption.
Differential Revision: https://reviews.llvm.org/D43666
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@326246 91177308-0d34-0410-b5e6-96231b3b80d8
This patch uses the reference to MaterializeTemporaryExpr stored in the
construction context since r326014 in order to model that expression correctly.
When modeling MaterializeTemporaryExpr, instead of copying the raw memory
contents from the sub-expression's rvalue to a completely new temporary region,
that we conjure up for the lack of better options, we now have the better
option to recall the region into which the object was originally constructed
and declare that region to be the value of the expression, which is semantically
correct.
This only works when the construction context is available, which is worked on
independently.
The temporary region's liveness (in the sense of removeDeadBindings) is extended
until the MaterializeTemporaryExpr is resolved, in order to keep the store
bindings around, because it wouldn't be referenced from anywhere else in the
program state.
Differential Revision: https://reviews.llvm.org/D43497
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@326236 91177308-0d34-0410-b5e6-96231b3b80d8
Array destructors, like constructors, need to be called for each element of the
array separately. We do not have any mechanisms to do this in the analyzer,
so for now all we do is evaluate a single constructor or destructor
conservatively and give up. It automatically causes the necessary invalidation
and pointer escape for the whole array, because this is how RegionStore works.
Implement this conservative behavior for temporary destructors. This fixes the
crash on the provided test.
Differential Revision: https://reviews.llvm.org/D43149
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325286 91177308-0d34-0410-b5e6-96231b3b80d8
Inline them if possible - a separate flag is added to control this.
The whole thing is under the cfg-temporary-dtors flag, off by default so far.
Temporary destructors are called at the end of full-expression. If the
temporary is lifetime-extended, automatic destructors kick in instead,
which are not addressed in this patch, and normally already work well
modulo the overally broken support for lifetime extension.
The patch operates by attaching the this-region to the CXXBindTemporaryExpr in
the program state, and then recalling it during destruction that was triggered
by that CXXBindTemporaryExpr. It has become possible because
CXXBindTemporaryExpr is part of the construction context since r325210.
Differential revision: https://reviews.llvm.org/D43104
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325282 91177308-0d34-0410-b5e6-96231b3b80d8
EvalCallOptions were introduced in r324018 for allowing various parts of
ExprEngine to notify the inlining mechanism, while preparing for evaluating a
function call, of possible difficulties with evaluating the call that they
foresee. Then mayInlineCall() would still be a single place for making the
decision.
Use that mechanism for destructors as well - pass the necessary flags from the
CFG-element-specific destructor handlers.
Part of this patch accidentally leaked into r324018, which led into a change in
tests; this change is reverted now, because even though the change looked
correct, the underlying behavior wasn't. Both of these commits were not intended
to introduce any function changes otherwise.
Differential Revision: https://reviews.llvm.org/D42991
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@325209 91177308-0d34-0410-b5e6-96231b3b80d8
This expression may or may not be evaluated in compile time, so tracking the
result symbol is of potential interest. However, run-time offsetof is not yet
supported by the analyzer, so for now this callback is only there to assist
future implementation.
Patch by Henry Wong!
Differential Revision: https://reviews.llvm.org/D42300
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@324790 91177308-0d34-0410-b5e6-96231b3b80d8
This patch adds a new CFGStmt sub-class, CFGConstructor, which replaces
the regular CFGStmt with CXXConstructExpr in it whenever the CFG has additional
information to provide regarding what sort of object is being constructed.
It is useful for figuring out what memory is initialized in client of the
CFG such as the Static Analyzer, which do not operate by recursive AST
traversal, but instead rely on the CFG to provide all the information when they
need it. Otherwise, the statement that triggers the construction and defines
what memory is being initialized would normally occur after the
construct-expression, and the client would need to peek to the next CFG element
or use statement parent map to understand the necessary facts about
the construct-expression.
As a proof of concept, CFGConstructors are added for new-expressions
and the respective test cases are provided to demonstrate how it works.
For now, the only additional data contained in the CFGConstructor element is
the "trigger statement", such as new-expression, which is the parent of the
constructor. It will be significantly expanded in later commits. The additional
data is organized as an auxiliary structure - the "construction context",
which is allocated separately from the CFGElement.
Differential Revision: https://reviews.llvm.org/D42672
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@324668 91177308-0d34-0410-b5e6-96231b3b80d8
It makes it easier to discriminate between values of similar expressions
in different stack frames.
It also makes the separate backtrace section in ExplodedGraph dumps redundant.
Differential Revision: https://reviews.llvm.org/D42552
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@324660 91177308-0d34-0410-b5e6-96231b3b80d8
PreStmt<CXXNewExpr> was never called.
Additionally, under c++-allocator-inlining=true, PostStmt<CXXNewExpr> was
called twice when the allocator was inlined: once after evaluating the
new-expression itself, once after evaluating the allocator call which, for the
lack of better options, uses the new-expression as the call site.
This patch fixes both problems.
Differential Revision: https://reviews.llvm.org/D41934
rdar://problem/12180598
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@322797 91177308-0d34-0410-b5e6-96231b3b80d8