Commit Graph

272 Commits

Author SHA1 Message Date
Jordan Rose 69d0aed6f1 CFG: Properly print delegating initializer CFG elements.
...rather than segfaulting.

Patch by Enrico P!

llvm-svn: 193208
2013-10-22 23:19:47 +00:00
Matt Beaumont-Gay 093f240a73 Fix a crash introduced in r189828.
The predicates in CXXRecordDecl which test various properties of special
members can't be called on incomplete decls.

llvm-svn: 190353
2013-09-09 21:07:58 +00:00
Pavel Labath 921e7650d4 Avoid double edges when constructing CFGs
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
2013-09-06 08:12:48 +00:00
Jordan Rose d2f4079db9 Add an implicit dtor CFG node just before C++ 'delete' expressions.
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
2013-09-03 17:00:57 +00:00
Pavel Labath d527cf89e6 [analyzer] Add very limited support for temporary destructors
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
2013-09-02 09:09:15 +00:00
Jordan Rose 5374c07ab9 Omit arguments of __builtin_object_size from the CFG.
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
2013-08-19 16:27:28 +00:00
Richard Smith 5a0ef78cd7 Remove bogus VarDecl::extendsLifetimeOfTemporary function and inline it into
its only caller with a FIXME explaining why it's bogus.

llvm-svn: 185109
2013-06-27 21:43:17 +00:00
Anna Zaks 56b4975bad [CFG] Set the “loop target” (back edge) for VisitObjCForCollectionStmt loops
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
2013-06-22 00:23:20 +00:00
Jordan Rose cf10ea8cb2 [analyzer; new edges] Simplify edges in a C++11 for-range loop.
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
2013-06-06 21:53:45 +00:00
David Majnemer f69ce86048 Analysis: Add a CFG successor to a SwitchStmt if it is both empty and fully covered
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
2013-06-04 17:38:44 +00:00
Jordan Rose 5250b873bb CFG: In a DeclStmt, skip anything that's not a VarDecl.
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
2013-06-03 22:59:41 +00:00
Jordan Rose a7f94ce8a3 Remove unused, awkward CFGStmtVisitor and subclasses.
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
2013-05-15 23:22:55 +00:00
David Blaikie 7d17010db5 Use only explicit bool conversion operator
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
2013-05-15 07:37:26 +00:00
Richard Smith 852c9db72b C++1y: Allow aggregates to have default initializers.
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
2013-04-20 22:23:05 +00:00
Ted Kremenek f82d578f9d [cfg] Always guard (when AddStaticInitBranches == true) DeclStmts for static variables, not just ones with explicit initializers
llvm-svn: 178322
2013-03-29 00:42:56 +00:00
Ted Kremenek 338c3aa8d1 Add static analyzer support for conditionally executing static initializers.
llvm-svn: 178318
2013-03-29 00:09:28 +00:00
Ted Kremenek 0dd8feee93 Add CFG logic to create a conditional branch for modeling static initializers.
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
2013-03-28 18:43:15 +00:00
Rafael Espindola 210de57694 Add const in preparation for a simplify_type change in llvm.
llvm-svn: 178146
2013-03-27 15:37:54 +00:00
David Blaikie 00be69ab5c Remove the CFGElement "Invalid" state.
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
2013-02-23 00:29:34 +00:00
David Blaikie 2a01f5d426 Replace CFGElement llvm::cast support to be well-defined.
See r175462 for another example/more details.

llvm-svn: 175796
2013-02-21 20:58:29 +00:00
Ted Kremenek 7d86b9ce1e Add note why we used a switch.
llvm-svn: 174449
2013-02-05 22:03:14 +00:00
Ted Kremenek 8ae67871b4 Change subexpressions to be visited in the CFG from left-to-right.
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
2013-02-05 22:00:19 +00:00
Richard Smith 10876ef571 Implement C++11 semantics for [[noreturn]] attribute. This required splitting
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
2013-01-17 01:30:42 +00:00
Will Dietz df9a2bbcb1 CFG.cpp: Fix wrapping logic when printing block preds/succs.
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
2013-01-07 09:51:17 +00:00
Benjamin Kramer ea70eb30a0 Pull the Attr iteration parts out of Attr.h, so including DeclBase.h doesn't pull in all the generated Attr code.
Required to pull some functions out of line, but this shouldn't have a perf impact.
No functionality change.

llvm-svn: 169092
2012-12-01 15:09:41 +00:00
Ted Kremenek e6ee671e16 Fix bad CFG construction bug when handling C++ 'try' statements.
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
2012-11-13 00:12:13 +00:00
Ted Kremenek b9f7aa46dd Fix potential null deference in CFG printer.
llvm-svn: 165836
2012-10-12 22:56:31 +00:00
Ted Kremenek 451c4d51ae Remove dead store.
llvm-svn: 165835
2012-10-12 22:56:26 +00:00
Jordan Rose 6d671cc34a [analyzer] Always include destructors in the analysis CFG.
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
2012-09-05 22:55:23 +00:00
Ted Kremenek 64fea5fc8f Teach CFG that 'if (x & 0)' and 'if (x * 0)' is an unfeasible branch.
Fixes <rdar://problem/11005770>.

llvm-svn: 162545
2012-08-24 07:42:09 +00:00
Jordan Rose e5d5393efc [analyzer] Support C++ default arguments if they are literal values.
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
2012-08-23 18:10:53 +00:00
Ted Kremenek d94854a42e Rename 'currentX' to 'currX' throughout analyzer and libAnalysis.
Also rename 'getCurrentBlockCounter()' to 'blockCount()'.

This ripples a bunch of code simplifications; mostly aesthetic,
but makes the code a bit tighter.

llvm-svn: 162349
2012-08-22 06:26:15 +00:00
Richard Smith d3b5c90865 Final piece of core issue 1330: delay computing the exception specification of
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
2012-07-27 04:22:15 +00:00
Richard Smith f676e45e5f When a && or || appears as the condition of a ?:, perform appropriate
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
2012-07-24 21:02:14 +00:00
Jordan Rose 8c6c8a98b6 Add a reverse iterator to DeclStmt, and use it when building a CFG.
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
2012-07-20 18:50:48 +00:00
Ted Kremenek 3d6177306b Teach CFG construction about destructors resulting from references to array types. Fixes crash in <rdar://problem/11671507>.
llvm-svn: 160424
2012-07-18 04:57:57 +00:00
Ted Kremenek b50e716bac Refine CFG so that '&&' and '||' don't lead to extra confluence points when used in a branch, but
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
2012-07-14 05:04:10 +00:00
Ted Kremenek a16436f51e Hoist CFG builder logic for '&&' and '||' into helper method. No funcationlity change.
llvm-svn: 160217
2012-07-14 05:04:06 +00:00
Ted Kremenek e86723866d Remove unused method declaration.
llvm-svn: 160216
2012-07-14 05:04:04 +00:00
Ted Kremenek 6f40024d9e Sort prototypes. No functionality change.
llvm-svn: 160215
2012-07-14 05:04:01 +00:00
Benjamin Kramer 1ea8e092be Drop the ASTContext.h include from Stmt.h and fix up transitive users.
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
2012-07-04 17:04:04 +00:00
David Blaikie 40ed29730b Revert Decl's iterators back to pointer value_type rather than reference value_type
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
2012-06-06 20:45:41 +00:00
Francois Pichet b27ea02784 Zap the /Za compiler switch from MSVC projects, the option is considered harmful even by Microsoft people and clang won't build using the MSVC 2012 RC if not removed.
Only 1 minor code change was necessary: can't use cdecl as variable name anymore.

llvm-svn: 158063
2012-06-06 12:00:10 +00:00
Richard Smith 84837d5b5a Add -Wimplicit-fallthrough warning flag, which warns on fallthrough between
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
2012-05-03 18:27:39 +00:00
David Blaikie 2d7c57ec1d Remove the ref/value inconsistency in filter_decl_iterator.
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
2012-04-30 02:36:29 +00:00
Richard Smith f623c96260 Implement DR1330 in C++11 mode, to support libstdc++4.7 which uses it.
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
2012-04-17 00:58:00 +00:00
Richard Smith c202b2809a Add an AttributedStmt type to represent a statement with C++11 attributes
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
2012-04-14 00:33:13 +00:00
Ted Kremenek da76a94bcb Include lambda capture init expressions in CFG.
llvm-svn: 154611
2012-04-12 20:34:52 +00:00
Ted Kremenek e2499844a2 Fix CFGBuilder to not include the body of a LambdaExpr in the CFG of the enclosing function.
llvm-svn: 154607
2012-04-12 20:03:44 +00:00
NAKAMURA Takumi e9ca55ea9b clang/lib/Analysis/CFG.cpp: Get rid of early insertion of placeholder to the map.
llvm-svn: 153407
2012-03-25 06:30:37 +00:00