Summary:
If a noreturn destructor is executed while returning a value from a function,
the resulting CFG has had two edges to the exit block. This crashed the analyzer,
because it expects that blocks with no terminators have only one outgoing edge.
I added code to avoid creating the second edge in this case.
PS: The crashes did not manifest themselves always, as usually the
NoReturnFunctionChecker would stop program evaluation before the analyzer hit
the assertion, but in the case of lifetime extended temporaries, the checker
failed to do that (which is a separate bug in itself).
Reviewers: jordan_rose
CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D1513
llvm-svn: 190125
This paves the way for adding support for modeling the destructor of a
region before it is deleted. The statement "delete <expr>" now generates
this series of CFG elements:
1. <expr>
2. [B1.1]->~Foo() (Implicit destructor)
3. delete [B1.1]
Patch by Karthik Bhat!
llvm-svn: 189828
This is an improved version of r186498. It enables ExprEngine to reason about
temporary object destructors. However, these destructor calls are never
inlined, since this feature is still broken. Still, this is sufficient to
properly handle noreturn temporary destructors.
Now, the analyzer correctly handles expressions like "a || A()", and executes the
destructor of "A" only on the paths where "a" evaluted to false.
Temporary destructor processing is still off by default and one has to
explicitly request it by setting cfg-temporary-dtors=true.
Reviewers: jordan_rose
CC: cfe-commits
Differential Revision: http://llvm-reviews.chandlerc.com/D1259
llvm-svn: 189746
This builtin does not actually evaluate its arguments for side effects,
so we shouldn't include them in the CFG. In the analyzer, rely on the
constant expression evaluator to get the proper semantics, at least for
now. (In the future, we could get ambitious and try to provide path-
sensitive size values.)
In theory, this does pose a problem for liveness analysis: a variable can
be used within the __builtin_object_size argument expression but not show
up as live. However, it is very unlikely that such a value would be used
to compute the object size and not used to access the object in some way.
<rdar://problem/14760817>
llvm-svn: 188679
Add the back edge info by creating a basic block, marked as loop target. This is
consistent with how other loops are processed, but was omitted from
VisitObjCForCollectionStmt.
llvm-svn: 184617
Previously our edges were completely broken here; now, the final result
is a very simple set of edges in most cases: one up to the "for" keyword
for context, and one into the body of the loop. This matches the behavior
for ObjC for-in loops.
In the AST, however, CXXForRangeStmts are handled very differently from
ObjCForCollectionStmts. Since they are specified in terms of equivalent
statements in the C++ standard, we actually have implicit AST nodes for
all of the semantic statements. This makes evaluation very easy, but
diagnostic locations a bit trickier. Fortunately, the problem can be
generally defined away by marking all of the implicit statements as
part of the top-level for-range statement.
One of the implicit statements in a for-range statement is the declaration
of implicit iterators __begin and __end. The CFG synthesizes two
separate DeclStmts to match each of these decls, but until now these
synthetic DeclStmts weren't in the function's ParentMap. Now, the CFG
keeps track of its synthetic statements, and the AnalysisDeclContext will
make sure to add them to the ParentMap.
<rdar://problem/14038483>
llvm-svn: 183449
Consider the case where a SwitchStmt satisfied isAllEnumCasesCovered()
as well as having no cases at all (i.e. the enum it covers has no
enumerators).
In this case, we should add a successor to repair the CFG.
This fixes PR16212.
llvm-svn: 183237
Neither the compiler nor the analyzer are doing anything with non-VarDecl
decls in the CFG, and having them there creates extra nodes in the
analyzer's path diagnostics. Simplify the CFG (and the path edges) by
simply leaving them out. We can always add interesting decls back in when
they become relevant.
Note that this only affects decls declared in a DeclStmt, and then only
those that appear within a function body.
llvm-svn: 183157
This class is a StmtVisitor that distinguishes between block-level and
non-block-level statements in a CFG. However, it does so using a hard-coded
idea of which statements might be block-level, which probably isn't accurate
anymore. The only implementer of the CFGStmtVisitor hierarchy was the
analyzer's DeadStoresChecker, and the analyzer creates a linearized CFG
anyway (every non-trivial statement is a block-level statement).
This also allows us to remove the block-expr map ("BlkExprMap"), which
mapped statements to positions in the CFG. Apart from having a helper type
that really should have just been Optional<unsigned>, it was only being
used to ask /if/ a particular expression was block-level, for traversal
purposes in CFGStmtVisitor.
llvm-svn: 181945
The most common (non-buggy) case are where such objects are used as
return expressions in bool-returning functions or as boolean function
arguments. In those cases I've used (& added if necessary) a named
function to provide the equivalent (or sometimes negative, depending on
convenient wording) test.
DiagnosticBuilder kept its implicit conversion operator owing to the
prevalent use of it in return statements.
One bug was found in ExprConstant.cpp involving a comparison of two
PointerUnions (PointerUnion did not previously have an operator==, so
instead both operands were converted to bool & then compared). A test
is included in test/SemaCXX/constant-expression-cxx1y.cpp for the fix
(adding operator== to PointerUnion in LLVM).
llvm-svn: 181869
Add a CXXDefaultInitExpr, analogous to CXXDefaultArgExpr, and use it both in
CXXCtorInitializers and in InitListExprs to represent a default initializer.
There's an additional complication here: because the default initializer can
refer to the initialized object via its 'this' pointer, we need to make sure
that 'this' points to the right thing within the evaluation.
llvm-svn: 179958
This is an optional variant of the CFG. This allows analyses to model whether
or not a static initializer has run, e.g.:
static Foo x = bar();
For basic dataflow analysis in Sema we will just assume that the initializer
always runs. For the static analyzer we can use this branch to accurately
track whether or not initializers are on.
This patch just adds the (opt-in) functionality to the CFG. The
static analyzer still needs to be modified to adopt this feature.
llvm-svn: 178263
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.
llvm-svn: 175938
This is a more natural order of evaluation, and it is very important
for visualization in the static analyzer. Within Xcode, the arrows
will not jump from right to left, which looks very visually jarring.
It also provides a more natural location for dataflow-based diagnostics.
Along the way, we found a case in the analyzer diagnostics where we
needed to indicate that a variable was "captured" by a block.
-fsyntax-only timings on sqlite3.c show no visible performance change,
although this is just one test case.
Fixes <rdar://problem/13016513>
llvm-svn: 174447
it apart from [[gnu::noreturn]] / __attribute__((noreturn)), since their
semantics are not equivalent (for instance, we treat [[gnu::noreturn]] as
affecting the function type, whereas [[noreturn]] does not).
llvm-svn: 172691
First check only wrapped with i==8, second wrapped at i==2,8,18,28,...
This fix restores the intended behavior: i==8,18,28,...
Found with -fsanitize=integer.
llvm-svn: 171718
This code assigned the last created CFGBlock* to the variable 'Block',
which is a scratch variable which is null'ed out after a block is
completed. By assigning the last created block to 'Block', we start
editing a completed block, inserting CFGStmts that should be in
another block. This was the case with 'try'. The test case that
showed this had a while loop inside a 'try', and the logic before
the while loop was being included as part of the "condition block"
for the loop. This showed up as a bogus dead store, but could
have lots of implications.
Turns out this bug was replicated a few times within CFG.cpp, so
I went and fixed up those as well.
llvm-svn: 167788
While destructors will continue to not be inlined (unless the analyzer
config option 'c++-inlining' is set to 'destructors'), leaving them out
of the CFG is an incomplete model of the behavior of an object, and
can cause false positive warnings (like PR13751, now working).
Destructors for temporaries are still not on by default, since
(a) we haven't actually checked this code to be sure it's fully correct
(in particular, we probably need to be very careful with regard to
lifetime-extension when a temporary is bound to a reference,
C++11 [class.temporary]p5), and
(b) ExprEngine doesn't actually do anything when it sees a temporary
destructor in the CFG -- not even invalidate the object region.
To enable temporary destructors, set the 'cfg-temporary-dtors' analyzer
config option to '1'. The old -cfg-add-implicit-dtors cc1 option, which
controlled all implicit destructors, has been removed.
llvm-svn: 163264
A CXXDefaultArgExpr wraps an Expr owned by a ParmVarDecl belonging to the
called function. In general, ExprEngine and Environment ought to treat this
like a ParenExpr or other transparent wrapper expression, with the inside
expression evaluated first.
However, if we call the same function twice, we'd produce a CFG that contains
the same wrapped expression twice, and we're not set up to handle that. I've
added a FIXME to the CFG builder to come back to that, but meanwhile we can
at least handle expressions that don't need to be explicitly evaluated:
literals. This probably handles many common uses of default parameters:
true/false, null, etc.
Part of PR13385 / <rdar://problem/12156507>
llvm-svn: 162453
Also rename 'getCurrentBlockCounter()' to 'blockCount()'.
This ripples a bunch of code simplifications; mostly aesthetic,
but makes the code a bit tighter.
llvm-svn: 162349
a defaulted special member function until the exception specification is needed
(using the same criteria used for the delayed instantiation of exception
specifications for function temploids).
EST_Delayed is now EST_Unevaluated (using 1330's terminology), and, like
EST_Uninstantiated, carries a pointer to the FunctionDecl which will be used to
resolve the exception specification.
This is enabled for all C++ modes: it's a little faster in the case where the
exception specification isn't used, allows our C++11-in-C++98 extensions to
work, and is still correct for C++98, since in that mode the computation of the
exception specification can't fail.
The diagnostics here aren't great (in particular, we should include implicit
evaluation of exception specifications for defaulted special members in the
template instantiation backtraces), but they're not much worse than before.
Our approach to the problem of cycles between in-class initializers and the
exception specification for a defaulted default constructor is modified a
little by this change -- we now reject any odr-use of a defaulted default
constructor if that constructor uses an in-class initializer and the use is in
an in-class initialzer which is declared lexically earlier. This is a closer
approximation to the current draft solution in core issue 1351, but isn't an
exact match (but the current draft wording isn't reasonable, so that's to be
expected).
llvm-svn: 160847
short-circuiting when building the CFG. Also be sure to skip parens before
checking for the && / || special cases. Finally, fix some crashes in CFG
printing in the presence of calls to destructors for array of array of class
type.
llvm-svn: 160691
The CFG creates dummy DeclStmts with one Decl per statement, and it has
to do so from last to first in order to build the graph correctly.
llvm-svn: 160560
instead push the terminator for the branch down into the basic blocks of the subexpressions of '&&' and '||'
respectively. This eliminates some artifical control-flow from the CFG and results in a more
compact CFG.
Note that this patch only alters the branches 'while', 'if' and 'for'. This was complex enough for
one patch. The remaining branches (e.g., do...while) can be handled in a separate patch, but they
weren't immediately tackled because they were less important.
It is possible that this patch introduces some subtle bugs, particularly w.r.t. to destructor placement.
I've tried to audit these changes, but it is also known that the destructor logic needs some refinement
in the area of '||' and '&&' regardless (i.e., their are known bugs).
llvm-svn: 160218
This required moving the ctors for IntegerLiteral and FloatingLiteral out of
line which shouldn't change anything as they are usually called through Create
methods that are already out of line.
ASTContext::Deallocate has been a nop for a long time, drop it from ASTVector
and make it independent from ASTContext.h
Pass the StorageAllocator directly to AccessedEntity so it doesn't need to
have a definition of ASTContext around.
llvm-svn: 159718
In addition, I've made the pointer and reference typedef 'void' rather than T*
just so they can't get misused. I would've omitted them entirely but
std::distance likes them to be there even if it doesn't use them.
This rolls back r155808 and r155869.
Review by Doug Gregor incorporating feedback from Chandler Carruth.
llvm-svn: 158104
cases in switch statements. Also add a [[clang::fallthrough]] attribute, which
can be used to suppress the warning in the case of intentional fallthrough.
Patch by Alexander Kornienko!
The handling of C++11 attribute namespaces in this patch is temporary, and will
be replaced with a cleaner mechanism in a subsequent patch.
llvm-svn: 156086
filter_decl_iterator had a weird mismatch where both op* and op-> returned T*
making it difficult to generalize this filtering behavior into a reusable
library of any kind.
This change errs on the side of value, making op-> return T* and op* return
T&.
(reviewed by Richard Smith)
llvm-svn: 155808
We have a new flavor of exception specification, EST_Uninstantiated. A function
type with this exception specification carries a pointer to a FunctionDecl, and
the exception specification for that FunctionDecl is instantiated (if needed)
and used in the place of the function type's exception specification.
When a function template declaration with a non-trivial exception specification
is instantiated, the specialization's exception specification is set to this
new 'uninstantiated' kind rather than being instantiated immediately.
Expr::CanThrow has migrated onto Sema, so it can instantiate exception specs
on-demand. Also, any odr-use of a function triggers the instantiation of its
exception specification (the exception specification could be needed by IRGen).
In passing, fix two places where a DeclRefExpr was created but the corresponding
function was not actually marked odr-used. We used to get away with this, but
don't any more.
Also fix a bug where instantiating an exception specification which refers to
function parameters resulted in a crash. We still have the same bug in default
arguments, which I'll be looking into next.
This, plus a tiny patch to fix libstdc++'s common_type, is enough for clang to
parse (and, in very limited testing, support) all of libstdc++4.7's standard
headers.
llvm-svn: 154886
attached. Since we do not support any attributes which appertain to a statement
(yet), testing of this is necessarily quite minimal.
Patch by Alexander Kornienko!
llvm-svn: 154723