Commit Graph

2204 Commits

Author SHA1 Message Date
Pavel Labath 868bebf844 Teach static analyzer about AttributedStmts
Summary:
Static analyzer used to abort when encountering AttributedStmts, because it
asserted that the statements should not appear in the CFG. This is however not
the case, since at least the clang::fallthrough annotation makes it through.

This commit simply makes the analyzer ignore the statement attributes.

CC: cfe-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D1030

llvm-svn: 185417
2013-07-02 09:38:48 +00:00
Jordan Rose b8e286548c [analyzer] Handle zeroing CXXConstructExprs.
Re-apply r184511, reverted in r184561, with the trivial default constructor
fast path removed -- it turned out not to be necessary here.

Certain expressions can cause a constructor invocation to zero-initialize
its object even if the constructor itself does no initialization. The
analyzer now handles that before evaluating the call to the constructor,
using the same "default binding" mechanism that calloc() uses, rather
than simply ignoring the zero-initialization flag.

<rdar://problem/14212563>

llvm-svn: 184815
2013-06-25 01:56:08 +00:00
Jordan Rose b3b976f061 [analyzer] Don't initialize virtual base classes more than once.
In order to make sure virtual base classes are always initialized once,
the AST contains initializers for the base class in /all/ of its
descendents, not just the immediate descendents. However, at runtime,
the most-derived object is responsible for initializing all the virtual
base classes; all the other initializers will be ignored.

The analyzer now checks to see if it's being called from another base
constructor, and if so does not perform virtual base initialization.

<rdar://problem/14236851>

llvm-svn: 184814
2013-06-25 01:55:59 +00:00
Reid Kleckner 7f62b95480 Check the canonical parameter type with getAs<>() in a static checker
This will prevent breakage when I introduce the DecayedType sugar node.

llvm-svn: 184755
2013-06-24 16:56:16 +00:00
Anna Zaks 27982c70fc [analyzer] Use output form collections’ count to decide if ObjC for loop should be entered
This fixes false positives by allowing us to know that a loop is always entered if
the collection count method returns a positive value and vice versa.

Addresses radar://14169391.

llvm-svn: 184618
2013-06-22 00:23:26 +00:00
Jordan Rose e83cb0922b Revert "[analyzer] Handle zeroing CXXConstructExprs."
Per review from Anna, this really should have been two commits, and besides
it's causing problems on our internal buildbot. Reverting until these have
been worked out.

This reverts r184511 / 98123284826bb4ce422775563ff1a01580ec5766.

llvm-svn: 184561
2013-06-21 16:30:32 +00:00
Jordan Rose 4ace1a74c0 [analyzer] Handle zeroing CXXConstructExprs.
Certain expressions can cause a constructor invocation to zero-initialize
its object even if the constructor itself does no initialization. The
analyzer now handles that before evaluating the call to the constructor,
using the same "default binding" mechanism that calloc() uses, rather
than simply ignoring the zero-initialization flag.

As a bonus, trivial default constructors are now no longer inlined; they
are instead processed explicitly by ExprEngine. This has a (positive)
effect on the generated path edges: they no longer stop at a default
constructor call unless there's a user-provided implementation.

<rdar://problem/14212563>

llvm-svn: 184511
2013-06-21 00:59:00 +00:00
Pavel Labath cb0b876b39 Fix static analyzer crash when casting from an incomplete type
Summary:
When doing a reinterpret+dynamic cast from an incomplete type, the analyzer
would crash (bug #16308). This fix makes the dynamic cast evaluator ignore
incomplete types, as they can never be used in a dynamic_cast. Also adding a
regression test.

CC: cfe-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D1006

llvm-svn: 184403
2013-06-20 07:45:01 +00:00
Pavel Labath 963f91b3a2 Fix a crash in the static analyzer (bug #16307)
Summary:
When processing a call to a function, which got passed less arguments than it
expects, the analyzer would crash.

I've also added a test for that and a analyzer warning which detects these
cases.

CC: cfe-commits

Differential Revision: http://llvm-reviews.chandlerc.com/D994

llvm-svn: 184288
2013-06-19 08:19:56 +00:00
Anna Zaks d60a41d941 [analyzer] Do not create a CompoundVal for lvalue InitListExprs.
These should be treated like scalars. This fixes a crash reported in radar://14164698.

llvm-svn: 184257
2013-06-18 23:16:20 +00:00
Anna Zaks 0325646705 [analyzer] Do not report uninitialized value warnings inside swap functions.
This silences warnings that could occur when one is swapping partially initialized structs. We suppress
not only the assignments of uninitialized members, but any values inside swap because swap could
potentially be used as a subroutine to swap class members.

This silences a warning from std::try::function::swap() on partially initialized objects.

llvm-svn: 184256
2013-06-18 23:16:15 +00:00
Anna Zaks 22895473af [analyzer; alternate edges] Fix the edge locations in presence of macros.
We drew the diagnostic edges to wrong statements in cases the note was on a macro.
The fix is simple, but seems to work just fine for a whole bunch of test cases (plist-macros.cpp).

Also, removes an unnecessary edge in edges-new.mm, when function signature starts with a macro.

llvm-svn: 183599
2013-06-08 00:29:24 +00:00
Anna Zaks de2ae19cf6 [analyzer] Address Jordan’s code review for r183451
llvm-svn: 183455
2013-06-06 22:32:11 +00:00
Anna Zaks b1b95d9409 [analyzer] Ensure that pieces with invalid locations always get removed from the BugReport
The function in which we were doing it used to be conditionalized. Add a new unconditional
cleanup step.

This fixes PR16227 (radar://14073870) - a crash when generating html output for one of the test files.

llvm-svn: 183451
2013-06-06 22:02:58 +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
Jordan Rose 69dd5fce3e [analyzer] Look through ExprWithCleanups to see if an expr's consumed.
We based decisions during analysis and during path generation on whether
or not an expression is consumed, so if a top-level expression has
cleanups it's important for us to look through that.

<rdar://problem/14076125>

llvm-svn: 183368
2013-06-06 01:57:24 +00:00
Jordan Rose 7a8bd94365 [analyzer; new edges] Don't crash if the top-level entry edge is missing.
We previously asserted that there was a top-level function entry edge, but
if the function decl's location is invalid (or within a macro) this edge
might not exist. Change the assertion to an actual check, and don't drop
the first path piece if it doesn't match.

<rdar://problem/14070304>

llvm-svn: 183358
2013-06-06 00:12:41 +00:00
Jordan Rose b67b7b201f [analyzer; new edges] Ignore self-edges, not all edges with the same location.
The edge optimizer needs to see edges for, say, implicit casts (which have
the same source location as their operand) to uniformly simplify the
entire path. However, we still don't want to produce edges from a statement
to /itself/, which could occur when two nodes in a row have the same
statement location.

This necessitated moving the check for redundant notes to after edge
optimization, since the check relies on notes being adjacent in the path.

<rdar://problem/14061675>

llvm-svn: 183357
2013-06-06 00:12:37 +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 5e2b3a30a0 [analyzer] Enable the new edge algorithm by default.
...but don't yet migrate over the existing plist tests. Some of these
would be trivial to migrate; others could use a bit of inspection first.
In any case, though, the new edge algorithm seems to have proven itself,
and we'd like more coverage (and more usage) of it going forwards.

llvm-svn: 183165
2013-06-03 23:00:19 +00:00
Jordan Rose 7ce598aeee [analyzer; new edges] Omit subexpression back-edges that span multiple lines.
A.1 -> A -> B
becomes
A.1 -> B

This only applies if there's an edge from a subexpression to its parent
expression, and that is immediately followed by another edge from the
parent expression to a subsequent expression. Normally this is useful for
bringing the edges back to the left side of the code, but when the
subexpression is on a different line the backedge ends up looking strange,
and may even obscure code. In these cases, it's better to just continue
to the next top-level statement.

llvm-svn: 183164
2013-06-03 23:00:09 +00:00
Jordan Rose 5f16849b34 [analyzer; new edges] Don't eliminate subexpr edge cycles if the line is long.
Specifically, if the line is over 80 characters, or if the top-level
statement spans mulitple lines, we should preserve sub-expression edges
even if they form a simple cycle as described in the last commit, because
it's harder to infer what's going on than it is for shorter lines.

llvm-svn: 183163
2013-06-03 23:00:05 +00:00
Jordan Rose 8c54b44fb3 [analyzer; new edges] Eliminate "cycle edges" for a single subexpression.
Generating context arrows can result in quite a few arrows surrounding a
relatively simple expression, often containing only a single path note.

|
1 +--2---+
v/       v
auto m = new m // 3 (the path note)
|\       |
5 +--4---+
v

Note also that 5 and 1 are two ends of the "same" arrow, i.e. they go from
event to event. 3 is not an arrow but the path note itself.

Now, if we see a pair of edges like 2 and 4---where 4 is the reverse of 2
and there is optionally a single path note between them---we will
eliminate /both/ edges. Anything more complicated will be left as is
(more edges involved, an inlined call, etc).

The next commit will refine this to preserve the arrows in a larger
expression, so that we don't lose all context.

llvm-svn: 183162
2013-06-03 23:00:00 +00:00
Jordan Rose b60b844265 [analyzer; new edges] Extra test case.
llvm-svn: 183161
2013-06-03 22:59:56 +00:00
Jordan Rose 06e800727e [analyzer; new edges] Improve enclosing contexts for logical expressions.
The old edge builder didn't have a notion of nested statement contexts,
so there was no special treatment of a logical operator inside an if
(or inside another logical operator). The new edge builder always tries
to establish the full context up to the top-level statement, so it's
important to know how much context has been established already rather
than just checking the innermost context.

This restores some of the old behavior for the old edge generation:
the context of a logical operator's non-controlling expression is the
subexpression in the old edge algorithm, but the entire operator
expression in the new algorithm.

llvm-svn: 183160
2013-06-03 22:59:53 +00:00
Jordan Rose b1db073dac [analyzer; new edges] Include context for edges to sub-expressions.
The current edge-generation algorithm sometimes creates edges from a
top-level statement A to a sub-expression B.1 that's not at the start of B.
This creates a "swoosh" effect where the arrow is drawn on top of the
text at the start of B. In these cases, the results are clearer if we see
an edge from A to B, then another one from B to B.1.

Admittedly, this does create a /lot/ of arrows, some of which merely hop
into a subexpression and then out again for a single note. The next commit
will eliminate these if the subexpression is simple enough.

This updates and reuses some of the infrastructure from the old edge-
generation algorithm to find the "enclosing statement" context for a
given expression. One change in particular marks the context of the
LHS or RHS of a logical binary operator (&&, ||) as the entire operator
expression, rather than the subexpression itself. This matches our behavior
for ?:, and allows us to handle nested context information.

<rdar://problem/13902816>

llvm-svn: 183159
2013-06-03 22:59:48 +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
Anna Zaks a4bc5e1201 [analyzer] Malloc checker should only escape the receiver when “[O init..]” is called.
Jordan has pointed out that it is valuable to warn in cases when the arguments to init escape.
For example, NSData initWithBytes id not going to free the memory.

llvm-svn: 183062
2013-05-31 23:47:32 +00:00
Anna Zaks 737926ba6c [analyzer] Fix a false positive reported on rare strange code, which happens to be in JSONKit
llvm-svn: 183055
2013-05-31 22:39:13 +00:00
Ted Kremenek 7c6b4084dd [analyzer; new edges] add simplifySimpleBranches() to reduce edges for branches.
In many cases, the edge from the "if" to the condition, followed by an edge from the branch condition to the target code, is uninteresting.

In such cases, we should fold the two edges into one from the "if" to the target.

This also applies to loops.

Implements <rdar://problem/14034763>.

llvm-svn: 183018
2013-05-31 16:56:54 +00:00
Ted Kremenek 263595f4f3 [analyzer; new edges] in splitBranchConditionEdges() do not check that predecessor edge has source in the same lexical scope as the target branch.
Fixes <rdar://problem/14031292>.

llvm-svn: 182987
2013-05-31 06:11:17 +00:00
Jordan Rose ca0ecb61e1 Revert "[analyzer; alternate edges] don't add an edge incoming from the start of a function"
...and make this work correctly in the current codebase.

After living on this for a while, it turns out to look very strange for
inlined functions that have only a single statement, and somewhat strange
for inlined functions in general (since they are still conceptually in the
middle of the path, and there is a function-entry path note).

It's worth noting that this only affects inlined functions; in the new
arrow generation algorithm, the top-level function still starts at the
first real statement in the function body, not the enclosing CompoundStmt.

This reverts r182078 / dbfa950abe0e55b173286a306ee620eff5f72ea.

llvm-svn: 182963
2013-05-30 21:30:17 +00:00
Jordan Rose 278d9de314 [analyzer] Don't crash if a block's signature just has the return type.
It is okay to declare a block without an argument list: ^ {} or ^void {}.
In these cases, the BlockDecl's signature-as-written will just contain
the return type, rather than the entire function type. It is unclear if
this is intentional, but the analyzer shouldn't crash because of it.

<rdar://problem/14018351>

llvm-svn: 182948
2013-05-30 18:14:27 +00:00
Jordan Rose 543bdd1237 [analyzer; new edges] In for(;;), use the ForStmt itself for loop notes.
Most loop notes (like "entering loop body") are attached to the condition
expression guarding a loop or its equivalent. For loops may not have a
condition expression, though. Rather than crashing, just use the entire
ForStmt as the location. This is probably the best we can do.

<rdar://problem/14016063>

llvm-svn: 182904
2013-05-30 01:05:58 +00:00
Jordan Rose 1bd1927a14 [analyzer] Accept references to variables declared "extern void" (C only).
In C, 'void' is treated like any other incomplete type, and though it is
never completed, you can cast the address of a void-typed variable to do
something useful. (In C++ it's illegal to declare a variable with void type.)

Previously we asserted on this code; now we just treat it like any other
incomplete type.

And speaking of incomplete types, we don't know their extent. Actually
check that in TypedValueRegion::getExtent, though that's not being used
by any checkers that are on by default.

llvm-svn: 182880
2013-05-29 20:50:34 +00:00
Anna Zaks 5416ab0156 [analyzer] Use the expression’s type instead of region’s type in ArrayToPointer decay evaluation
This gives slightly better precision, specifically, in cases where a non-typed region represents the array
or when the type is a non-array type, which can happen when an array is a result of a reinterpret_cast.

llvm-svn: 182810
2013-05-28 23:24:01 +00:00
Anna Zaks 6477e97af7 [analyzer] Re-enable reasoning about CK_LValueBitCast
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.

llvm-svn: 182808
2013-05-28 22:32:08 +00:00
Anna Zaks bac964e14f [analyzer] Use a more generic MemRegion.getAsOffset to evaluate bin operators on MemRegions
In addition to enabling more code reuse, this suppresses some false positives by allowing us to
compare an element region to its base. See the ptr-arith.cpp test cases for an example.

llvm-svn: 182780
2013-05-28 17:31:43 +00:00
Jordan Rose 14cce0561c [analyzer] Fix test for r182677.
llvm-svn: 182678
2013-05-24 21:49:58 +00:00
Jordan Rose 56138268b0 [analyzer] Treat analyzer-synthesized function bodies like implicit bodies.
When generating path notes, implicit function bodies are shown at the call
site, so that, say, copying a POD type in C++ doesn't jump you to a header
file. This is especially important when the synthesized function itself
calls another function (or block), in which case we should try to jump the
user around as little as possible.

By checking whether a called function has a body in the AST, we can tell
if the analyzer synthesized the body, and if we should therefore collapse
the call down to the call site like a true implicitly-defined function.

<rdar://problem/13978414>

llvm-svn: 182677
2013-05-24 21:43:11 +00:00
Jordan Rose 7291666cd9 [analyzer; new edges] Properly set location after exiting an inlined call.
The new edge algorithm would keep track of the previous location in each
location context, so that it could draw arrows coming in and out of each
inlined call. However, it tried to access the location of the call before
it was actually set (at the CallEnter node). This only affected
unterminated calls at the end of a path; calls with visible exit nodes
already had a valid location.

This patch ditches the location context map, since we're processing the
nodes in order anyway, and just unconditionally updates the PrevLoc
variable after popping out of an inlined call.

<rdar://problem/13983470>

llvm-svn: 182676
2013-05-24 21:43:05 +00:00
Ted Kremenek abfcca30d8 [analyzer; alternate edges] Add a new test case file to regression test the new arrows algorithm.
This essentially combines the tests in plist-output.m and plist-alternate-output.m.

llvm-svn: 182612
2013-05-23 21:33:12 +00:00
Jordan Rose 1bfe9c787f [analyzer] Don't crash if a block doesn't have a type signature.
Currently, blocks instantiated in templates lose their "signature as
written"; it's not clear if this is intentional. Change the analyzer's
use of BlockDecl::getSignatureAsWritten to check whether or not the
signature is actually there.

<rdar://problem/13954714>

llvm-svn: 182497
2013-05-22 18:09:44 +00:00
Anna Zaks 2f74ff1b3c [analyzer] Do not assert on reports ending in calls within macros.
The crash is triggered by the newly added option (-analyzer-config report-in-main-source-file=true) introduced in r182058.

Note, ideally, we’d like to report the issue within the main source file here as well.
For now, just do not crash.

llvm-svn: 182445
2013-05-22 01:54:34 +00:00
Anna Zaks 6334579623 [analyzer] Address Jordan's review comments for r182058
llvm-svn: 182156
2013-05-17 20:51:16 +00:00
Jordan Rose fbe4d85035 [analyzer] Don't inline ~shared_ptr.
The analyzer can't see the reference count for shared_ptr, so it doesn't
know whether a given destruction is going to delete the referenced object.
This leads to spurious leak and use-after-free warnings.

For now, just ban destructors named '~shared_ptr', which catches
std::shared_ptr, std::tr1::shared_ptr, and boost::shared_ptr.

PR15987

llvm-svn: 182071
2013-05-17 02:16:49 +00:00
Anna Zaks c5e2eca042 [analyzer] Add an option to use the last location in the main source file as the report location.
Previously, we’ve used the last location of the analyzer issue path as the location of the
report. This might not provide the best user experience, when one analyzer a source
file and the issue appears in the header. Introduce an option to use the last location
of the path that is in the main source file as the report location.

New option can be enabled with -analyzer-config report-in-main-source-file=true.

llvm-svn: 182058
2013-05-16 22:30:45 +00:00
Fariborz Jahanian 478536b1c1 improve of note message and minor refactoring of my last
patch (r181847).

llvm-svn: 181896
2013-05-15 15:27:35 +00:00
Fariborz Jahanian 773df4a11f Objective-C [diagnostics] [QOI], when method is not
found for a receiver, note where receiver class
is declaraed (this is most common when receiver is a forward
class). // rdar://3258331

llvm-svn: 181847
2013-05-14 23:24:17 +00:00
Anna Zaks 6afa8f1609 [analyzer] Refactor: address Jordan’s code review of r181738.
(Modifying the checker to record that the values are no longer nil will be done separately.)

llvm-svn: 181744
2013-05-13 23:49:51 +00:00
Anna Zaks bb2a2c865f [analyzer] Warn about nil elements/keys/values in array and dictionary literals.
llvm-svn: 181738
2013-05-13 21:48:20 +00:00
Anna Zaks 4063fa1cdc [analyzer] Assume [NSNull null] does not return nil.
llvm-svn: 181616
2013-05-10 18:04:46 +00:00
Anna Zaks 3feb2cd5bb [analyzer] Do not check if sys/queue.h file is a system header.
In most cases it is, by just looking at the name. Also, this check prevents the heuristic from working in strange user settings.
radar://13839692

llvm-svn: 181615
2013-05-10 18:04:43 +00:00
Jordan Rose 757fbb0b14 [analyzer] Indirect invalidation counts as an escape for leak checkers.
Consider this example:

  char *p = malloc(sizeof(char));
  systemFunction(&p);
  free(p);

In this case, when we call systemFunction, we know (because it's a system
function) that it won't free 'p'. However, we /don't/ know whether or not
it will /change/ 'p', so the analyzer is forced to invalidate 'p', wiping
out any bindings it contains. But now the malloc'd region looks like a
leak, since there are no more bindings pointing to it, and we'll get a
spurious leak warning.

The fix for this is to notice when something is becoming inaccessible due
to invalidation (i.e. an imperfect model, as opposed to being explicitly
overwritten) and stop tracking it at that point. Currently, the best way
to determine this for a call is the "indirect escape" pointer-escape kind.

In practice, all the patch does is take the "system functions don't free
memory" special case and limit it to direct parameters, i.e. just the
arguments to a call and not other regions accessible to them. This is a
conservative change that should only cause us to escape regions more
eagerly, which means fewer leak warnings.

This isn't perfect for several reasons, the main one being that this
example is treated the same as the one above:

  char **p = malloc(sizeof(char *));
  systemFunction(p + 1);
  // leak

Currently, "addresses accessible by offsets of the starting region" and
"addresses accessible through bindings of the starting region" are both
considered "indirect" regions, hence this uniform treatment.

Another issue is our longstanding problem of not distinguishing const and
non-const bindings; if in the first example systemFunction's parameter were
a char * const *, we should know that the function will not overwrite 'p',
and thus we can safely report the leak.

<rdar://problem/13758386>

llvm-svn: 181607
2013-05-10 17:07:16 +00:00
Anna Zaks e5e416c6de [analyzer] Fix a crash triggered by printing a note on a default argument
Instead, use the location of the call to print the note.

llvm-svn: 181337
2013-05-07 17:42:42 +00:00
Jordan Rose 5d2abefb62 [analyzer] Handle CXXTemporaryObjectExprs in compound literals.
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>

llvm-svn: 181213
2013-05-06 16:48:20 +00:00
Jordan Rose 320fbf057c [analyzer] Check the stack frame when looking for a var's initialization.
FindLastStoreBRVisitor is responsible for finding where a particular region
gets its value; if the region is a VarRegion, it's possible that value was
assigned at initialization, i.e. at its DeclStmt. However, if a function is
called recursively, the same DeclStmt may be evaluated multiple times in
multiple stack frames. FindLastStoreBRVisitor was not taking this into
account and just picking the first one it saw.

<rdar://problem/13787723>

llvm-svn: 180997
2013-05-03 05:47:31 +00:00
Jordan Rose cea47b78fc [analyzer] Fix trackNullOrUndef when tracking args that have nil receivers.
There were actually two bugs here:
- if we decided to look for an interesting lvalue or call expression, we
  wouldn't go find its node if we also knew we were at a (different) call.
- if we looked through one message send with a  nil receiver, we thought we
  were still looking at an argument to the original call.

Put together, this kept us from being able to track the right values, which
means sub-par diagnostics and worse false-positive suppression.

Noticed by inspection.

llvm-svn: 180996
2013-05-03 05:47:24 +00:00
Jordan Rose c76d7e3d96 [analyzer] Don't try to evaluate MaterializeTemporaryExpr as a constant.
...and don't consider '0' to be a null pointer constant if it's the
initializer for a float!

Apparently null pointer constant evaluation looks through both
MaterializeTemporaryExpr and ImplicitCastExpr, so we have to be more
careful about types in the callers. For RegionStore this just means giving
up a little more; for ExprEngine this means handling the
MaterializeTemporaryExpr case explicitly.

Follow-up to r180894.

llvm-svn: 180944
2013-05-02 19:51:20 +00:00
Jordan Rose b147918252 [analyzer] RetainCountChecker: don't track through xpc_connection_set_context.
It is unfortunate that we have to mark these exceptions in multiple places.
This was already in CallEvent. I suppose it does let us be more precise
about saying /which/ arguments have their retain counts invalidated -- the
connection's is still valid even though the context object's isn't -- but
we're not tracking the retain count of XPC objects anyway.

<rdar://problem/13783514>

llvm-svn: 180904
2013-05-02 01:51:40 +00:00
Jordan Rose 89bbd1fb64 [analyzer] Consolidate constant evaluation logic in SValBuilder.
Previously, this was scattered across Environment (literal expressions),
ExprEngine (default arguments), and RegionStore (global constants). The
former special-cased several kinds of simple constant expressions, while
the latter two deferred to the AST's constant evaluator.

Now, these are all unified as SValBuilder::getConstantVal(). To keep
Environment fast, the special cases for simple constant expressions have
been left in, but the main benefits are that (a) unusual constants like
ObjCStringLiterals now work as default arguments and global constant
initializers, and (b) we're not duplicating code between ExprEngine and
RegionStore.

This actually caught a bug in our test suite, which is awesome: we stop
tracking allocated memory if it's passed as an argument along with some
kind of callback, but not if the callback is 0. We were testing this in
a case where the callback parameter had a default value, but that value
was 0. After this change, the analyzer now (correctly) flags that as a
leak!

<rdar://problem/13773117>

llvm-svn: 180894
2013-05-01 23:10:44 +00:00
Jordan Rose 7023a90378 [analyzer] Don't inline the [cd]tors of C++ iterators.
This goes with r178516, which instructed the analyzer not to inline the
constructors and destructors of C++ container classes. This goes a step
further and does the same thing for iterators, so that the analyzer won't
falsely decide we're trying to construct an iterator pointing to a
nonexistent element.

The heuristic for determining whether something is an iterator is the
presence of an 'iterator_category' member. This is controlled under the
same -analyzer-config option as container constructor/destructor inlining:
'c++-container-inlining'.

<rdar://problem/13770187>

llvm-svn: 180890
2013-05-01 22:39:31 +00:00
Jordan Rose dc16628c93 Re-apply "[analyzer] Model casts to bool differently from other numbers."
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
2013-05-01 18:19:59 +00:00
Jordan Rose 49f888bbab Revert "[analyzer] Model casts to bool differently from other numbers."
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
2013-04-29 17:23:03 +00:00
Jordan Rose 9de821ebfd [analyzer] An ObjC for-in loop runs 0 times if the collection is nil.
In an Objective-C for-in loop "for (id element in collection) {}", the loop
will run 0 times if the collection is nil. This is because the for-in loop
is implemented using a protocol method that returns 0 when there are no
elements to iterate, and messages to nil will result in a 0 return value.

At some point we may want to actually model this message send, but for now
we may as well get the nil case correct, and avoid the false positives that
would come with this case.

<rdar://problem/13744632>

llvm-svn: 180639
2013-04-26 21:43:01 +00:00
Jordan Rose 9661c1d18a [analyzer] Model casts to bool differently from other numbers.
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
2013-04-26 21:42:55 +00:00
Jordan Rose 0541159d68 [analyzer] Consolidate BoolAssignmentChecker tests by using two RUN lines.
llvm-svn: 180637
2013-04-26 21:42:47 +00:00
Anna Zaks 144579e299 [analyzer] Teach DeadStoreChecker to look though BO_Comma and disregard the LHS.
llvm-svn: 180579
2013-04-25 21:52:35 +00:00
Anna Zaks 99394bbd02 [analyzer] Fix a crash in RetainCountChecker - we should not rely on CallEnter::getCallExpr to return non-NULL
We get a CallEnter with a null expression, when processing a destructor. All other users of
CallEnter::getCallExpr work fine with null as return value.

(Addresses PR15832, Thanks to Jordan for reducing the test case!)

llvm-svn: 180234
2013-04-25 00:41:32 +00:00
Anna Zaks 7712f38978 [analyzer] IvarInvalidation: correctly handle cases where only partial invalidators exist
- If only partial invalidators exist and there are no full invalidators in @implementation, report every ivar that has
not been invalidated. (Previously, we reported the first Ivar in the list, which could actually have been invalidated
by a partial invalidator. The code assumed you cannot have only partial invalidators.)

- Do not report missing invalidation method declaration if a partial invalidation method declaration exists.

llvm-svn: 180170
2013-04-24 02:49:16 +00:00
Anna Zaks 404028798f [analyzer] Set the allocation site to be the uniqueing location for retain count checker leaks.
The uniqueing location is the location which is part of the hash used to determine if two reports are
the same. This is used by the CmpRuns.py script to compare two analyzer runs and determine which
warnings are new.

llvm-svn: 180166
2013-04-23 23:57:50 +00:00
Anna Zaks 4e16b29c13 [analyzer] Refactor BugReport::getLocation and PathDiagnosticLocation::createEndOfPath for greater code reuse
The 2 functions were computing the same location using different logic (each one had edge case bugs that the other
one did not). Refactor them to rely on the same logic.

The location of the warning reported in text/command line output format will now match that of the plist file.

There is one change in the plist output as well. When reporting an error on a BinaryOperator, we use the location of the
operator instead of the beginning of the BinaryOperator expression. This matches our output on command line and
looks better in most cases.

llvm-svn: 180165
2013-04-23 23:57:43 +00:00
Jordan Rose 7467f06533 [analyzer] RetainCountChecker: Clean up path notes for autorelease.
No functionality change.

<rdar://problem/13710586>

llvm-svn: 180075
2013-04-23 01:42:25 +00:00
Jordan Rose 6e3cf2ba85 [analyzer] Model strsep(), particularly that it returns its input.
This handles the false positive leak warning in PR15374, and also serves
as a basic model for the strsep() function.

llvm-svn: 180069
2013-04-22 23:18:42 +00:00
Jordan Rose b957113b3f [analyzer] Treat reinterpret_cast like a base cast in certain cases.
The analyzer represents all pointer-to-pointer bitcasts the same way, but
this can be problematic if an implicit base cast gets layered on top of a
manual base cast (performed with reinterpret_cast instead of static_cast).
Fix this (and avoid a valid assertion) by looking through cast regions.

Using reinterpret_cast this way is only valid if the base class is at the
same offset as the derived class; this is checked by -Wreinterpret-base-class.
In the interest of performance, the analyzer doesn't repeat this check
anywhere; it will just silently do the wrong thing (use the wrong offsets
for fields of the base class) if the user code is wrong.

PR15394

llvm-svn: 180052
2013-04-22 21:36:49 +00:00
Jordan Rose 3437669ca9 [analyzer] Type information from C++ new expressions is perfect.
This improves our handling of dynamic_cast and devirtualization for
objects allocated by 'new'.

llvm-svn: 180051
2013-04-22 21:36:44 +00:00
Anna Zaks 6c0c47ede5 [analyzer] Ensure BugReporterTracking works on regions with pointer arithmetic
Introduce a new helper function, which computes the first symbolic region in
the base region chain. The corresponding symbol has been used for assuming that
a pointer is null. Now, it will also be used for checking if it is null.

This ensures that we are tracking a null pointer correctly in the BugReporter.

llvm-svn: 179916
2013-04-20 01:15:42 +00:00
Anna Zaks 4e88300256 [analyzer] Correct the comment
llvm-svn: 179914
2013-04-20 01:15:32 +00:00
Ted Kremenek d51ad8c125 [analyzer] Refine 'nil receiver' diagnostics to mention the name of the method not called.
llvm-svn: 179776
2013-04-18 17:44:15 +00:00
Jordan Rose 3720e2f006 [analyzer] "Force" LazyCompoundVals on bind when they are simple enough.
The analyzer uses LazyCompoundVals to represent rvalues of aggregate types,
most importantly structs and arrays. This allows us to efficiently copy
around an entire struct, rather than doing a memberwise load every time a
struct rvalue is encountered. This can also keep memory usage down by
allowing several structs to "share" the same snapshotted bindings.

However, /lookup/ through LazyCompoundVals can be expensive, especially
since they can end up chaining back to the original value. While we try
to reuse LazyCompoundVals whenever it's safe, and cache information about
this transitivity, the fact is it's sometimes just not a good idea to
perpetuate LazyCompoundVals -- the tradeoffs just aren't worth it.

This commit changes RegionStore so that binding a LazyCompoundVal to struct
will do a memberwise copy if the struct is simple enough. Today's definition
of "simple enough" is "up to N scalar members" (see below), but that could
easily be changed in the future. This is enough to bring the test case in
PR15697 back down to a manageable analysis time (within 20% of its original
time, in an unfair test where the new analyzer is not compiled with LTO).

The actual value of "N" is controlled by a new -analyzer-config option,
'region-store-small-struct-limit'. It defaults to "2", meaning structs with
zero, one, or two scalar members will be considered "simple enough" for
this code path.

It's worth noting that a more straightforward implementation would do this
on load, not on bind, and make use of the structure we already have for this:
CompoundVal. A long time ago, this was actually how RegionStore modeled
aggregate-to-aggregate copies, but today it's only used for compound literals.
Unfortunately, it seems that we've special-cased LazyCompoundVal in certain
places (such as liveness checks) but failed to similarly special-case
CompoundVal in all of them. Until we're confident that CompoundVal is
handled properly everywhere, this solution is safer, since the entire
optimization is just an implementation detail of RegionStore.

<rdar://problem/13599304>

llvm-svn: 179767
2013-04-18 16:33:46 +00:00
Jordan Rose cdb44bdb3d [analyzer] Don't crash if we cache out after making a temporary region.
A C++ overloaded operator may be implemented as an instance method, and
that instance method may be called on an rvalue object, which has no
associated region. The analyzer handles this by creating a temporary region
just for the evaluation of this call; however, it is possible that /by
creating the region/, the analyzer ends up in a previously-explored state.
In this case we don't need to continue along this path.

This doesn't actually show any behavioral change now, but it starts being
used with the next commit and prevents an assertion failure there.

llvm-svn: 179766
2013-04-18 16:33:40 +00:00
Anna Zaks 05139fff42 [analyzer] Tweak getDerefExpr more to track DeclRefExprs to references.
In the committed example, we now see a note that tells us when the pointer
was assumed to be null.

This is the only case in which getDerefExpr returned null (failed to get
the dereferenced expr) throughout our regression tests. (There were multiple
occurrences of this one.)

llvm-svn: 179736
2013-04-18 00:15:15 +00:00
Anna Zaks 1baf545fa6 [analyzer] Improve dereferenced expression tracking for MemberExpr with a dot and non-reference base
llvm-svn: 179734
2013-04-17 23:17:43 +00:00
Anna Zaks 4f59835182 [analyzer] Gain more precision retrieving the right SVal by specifying the type of the expression.
Thanks to Jordan for suggesting the fix.

llvm-svn: 179732
2013-04-17 22:29:51 +00:00
Anna Zaks 54f4d01bd3 [analyzer] Allow TrackConstraintBRVisitor to work when the value it’s tracking is not live in the last node of the path
We always register the visitor on a node in which the value we are tracking is live and constrained. However,
the visitation can restart at a node, later on the path, in which the value is under constrained because
it is no longer live. Previously, we just silently stopped tracking in that case.

llvm-svn: 179731
2013-04-17 22:29:47 +00:00
Jordan Rose add14263ea [analyzer] Don't warn for returning void expressions in void blocks.
This was slightly tricky because BlockDecls don't currently store an
inferred return type. However, we can rely on the fact that blocks with
inferred return types will have return statements that match the inferred
type.

<rdar://problem/13665798>

llvm-svn: 179699
2013-04-17 18:03:48 +00:00
Andy Gibbs fcc699aee8 Extended VerifyDiagnosticConsumer to also verify source file for diagnostic.
VerifyDiagnosticConsumer previously would not check that the diagnostic and
its matching directive referenced the same source file.  Common practice was
to create directives that referenced other files but only by line number,
and this led to problems such as when the file containing the directive
didn't have enough lines to match the location of the diagnostic in the
other file, leading to bizarre file formatting and other oddities.

This patch causes VerifyDiagnosticConsumer to match source files as well as
line numbers.  Therefore, a new syntax is made available for directives, for
example:

// expected-error@file:line {{diagnostic message}}

This extends the @line feature where "file" is the file where the diagnostic
is generated.  The @line syntax is still available and uses the current file
for the diagnostic.  "file" can be specified either as a relative or absolute
path - although the latter has less usefulness, I think!  The #include search
paths will be used to locate the file and if it is not found an error will be
generated.

The new check is not optional: if the directive is in a different file to the
diagnostic, the file must be specified.  Therefore, a number of test-cases
have been updated with regard to this.

This closes out PR15613.

llvm-svn: 179677
2013-04-17 08:06:46 +00:00
Ted Kremenek 20871cd6b9 Make test portable.
llvm-svn: 179635
2013-04-16 21:59:21 +00:00
Ted Kremenek 8671acba95 [analyzer] Add experimental option "leak-diagnostics-reference-allocation".
This is an opt-in tweak for leak diagnostics to reference the allocation
site if the diagnostic consumer only wants a pithy amount of information,
and not the entire path.

This is a strawman enhancement that I expect to see some experimentation
with over the next week, and can go away if we don't want it.

Currently it is only used by RetainCountChecker, but could be used
by MallocChecker if and when we decide this should stay in.

llvm-svn: 179634
2013-04-16 21:44:22 +00:00
Anna Zaks e4cfcd4e41 [analyzer] Improve the malloc checker stack hint message
llvm-svn: 179580
2013-04-16 00:22:55 +00:00
Anna Zaks 8591aa78db [analyzer] Do not crash when processing binary "?:" in C++
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.

llvm-svn: 179574
2013-04-15 22:38:07 +00:00
Anna Zaks 7460deb15d [analyzer] Add pretty printing to CXXBaseObjectRegion.
llvm-svn: 179573
2013-04-15 22:38:04 +00:00
Anna Zaks e2e8ea62df [analyzer] Address code review for r179395
Mostly refactoring + handle the nested fields by printing the innermost field only.

llvm-svn: 179572
2013-04-15 22:37:59 +00:00
Anna Zaks 0881b8882e [analyzer] Add more specialized error messages for corner cases as per Jordan's code review for r179396
llvm-svn: 179571
2013-04-15 22:37:53 +00:00
Jordan Rose 27ae8a2800 [analyzer] Don't assert on a temporary of pointer-to-member type.
While we don't do anything intelligent with pointers-to-members today,
it's perfectly legal to need a temporary of pointer-to-member type to, say,
pass by const reference. Tweak an assertion to allow this.

PR15742 and PR15747

llvm-svn: 179563
2013-04-15 22:03:38 +00:00
Jordan Rose fa80736bca [analyzer] Re-enable using global regions as a symbolic base.
Now that we're invalidating global regions properly, we want to continue
taking advantage of a particular optimization: if all global regions are
invalidated together, we can represent the bindings of each region with
a "derived region value" symbol. Essentially, this lazily links each
global region with a single symbol created at invalidation time, rather
than binding each region with a new symbolic value.

We used to do this, but haven't been for a while; the previous commit
re-enabled this code path, and this handles the fallout.

<rdar://problem/13464044>

llvm-svn: 179554
2013-04-15 20:39:45 +00:00
Jordan Rose 577749a337 [analyzer] Properly invalidate global regions on opaque function calls.
This fixes a regression where a call to a function we can't reason about
would not actually invalidate global regions that had explicit bindings.

  void test_that_now_works() {
    globalInt = 42;
    clang_analyzer_eval(globalInt == 42); // expected-warning{{TRUE}}

    invalidateGlobals();
    clang_analyzer_eval(globalInt == 42); // expected-warning{{UNKNOWN}}
  }

This has probably been around since the initial "cluster" refactoring of
RegionStore, if not longer.

<rdar://problem/13464044>

llvm-svn: 179553
2013-04-15 20:39:41 +00:00
Jordan Rose d02adbf03c [analyzer] Tests: move system functions into system header simulator files.
Some checkers ascribe different behavior to functions declared in system
headers, so when working with standard library functions it's probably best
to always have them in a standard location.

Test change only (no functionality change), but necessary for the next commit.

llvm-svn: 179552
2013-04-15 20:39:37 +00:00
Anton Yartsev 7af0aa86dd [analyzer] Enable NewDelete checker if NewDeleteLeaks checker is enabled.
llvm-svn: 179428
2013-04-12 23:25:40 +00:00
Anton Yartsev b0e284824f NewDeleteLeaks is a subchecker of NewDelete checker; it is tested in NewDelete-checker-test.cpp
llvm-svn: 179426
2013-04-12 23:18:46 +00:00
Anton Yartsev c92f2c5899 [analyzer] Makes NewDeleteLeaks checker work independently from NewDelete.
llvm-svn: 179410
2013-04-12 20:48:49 +00:00
Anna Zaks 685e913d71 [analyzer] Print a diagnostic note even if the region cannot be printed.
There are few cases where we can track the region, but cannot print the note,
which makes the testing limited. (Though, I’ve tested this manually by making
all regions non-printable.) Even though the applicability is limited now, the enhancement
will be more relevant as we start tracking more regions.

llvm-svn: 179396
2013-04-12 18:40:27 +00:00
Anna Zaks 6cea7d9e5e [analyzer]Print field region even when the base region is not printable
llvm-svn: 179395
2013-04-12 18:40:21 +00:00
Jordan Rose 526d93c55d [analyzer] Show "Returning from ..." note at caller's depth, not callee's.
Before:
  1. Calling 'foo'
    2. Doing something interesting
    3. Returning from 'foo'
  4. Some kind of error here

After:
  1. Calling 'foo'
    2. Doing something interesting
  3. Returning from 'foo'
  4. Some kind of error here

The location of the note is already in the caller, not the callee, so this
just brings the "depth" attribute in line with that.

This only affects plist diagnostic consumers (i.e. Xcode). It's necessary
for Xcode to associate the control flow arrows with the right stack frame.

<rdar://problem/13634363>

llvm-svn: 179351
2013-04-12 00:44:17 +00:00
Jordan Rose ce781ae6ae [analyzer] Don't emit extra context arrow after returning from an inlined call.
In this code

  int getZero() {
    return 0;
  }

  void test() {
    int problem = 1 / getZero(); // expected-warning {{Division by zero}}
  }

we generate these arrows:

    +-----------------+
    |                 v
    int problem = 1 / getZero();
                  ^   |
                  +---+

where the top one represents the control flow up to the first call, and the
bottom one represents the flow to the division.* It turns out, however, that
we were generating the top arrow twice, as if attempting to "set up context"
after we had already returned from the call. This resulted in poor
highlighting in Xcode.

* Arguably the best location for the division is the '/', but that's a
  different problem.

<rdar://problem/13326040>

llvm-svn: 179350
2013-04-12 00:44:01 +00:00
Jordan Rose b1312a5495 Force a load when creating a reference to a temporary copied from a bitfield.
For this source:
  const int &ref = someStruct.bitfield;

We used to generate this AST:

  DeclStmt [...]
  `-VarDecl [...] ref 'const int &'
    `-MaterializeTemporaryExpr [...] 'const int' lvalue
      `-ImplicitCastExpr [...] 'const int' lvalue <NoOp>
        `-MemberExpr [...] 'int' lvalue bitfield .bitfield [...]
          `-DeclRefExpr [...] 'struct X' lvalue ParmVar [...] 'someStruct' 'struct X'

Notice the lvalue inside the MaterializeTemporaryExpr, which is very
confusing (and caused an assertion to fire in the analyzer - PR15694).

We now generate this:

  DeclStmt [...]
  `-VarDecl [...] ref 'const int &'
    `-MaterializeTemporaryExpr [...] 'const int' lvalue
      `-ImplicitCastExpr [...] 'int' <LValueToRValue>
        `-MemberExpr [...] 'int' lvalue bitfield .bitfield [...]
          `-DeclRefExpr [...] 'struct X' lvalue ParmVar [...] 'someStruct' 'struct X'

Which makes a lot more sense. This allows us to remove code in both
CodeGen and AST that hacked around this special case.

The commit also makes Clang accept this (legal) C++11 code:

  int &&ref = std::move(someStruct).bitfield

PR15694 / <rdar://problem/13600396>

llvm-svn: 179250
2013-04-11 00:58:58 +00:00
Anna Zaks 07804ef87e [analyzer] Address Jordan’s review of r179219
llvm-svn: 179235
2013-04-10 22:56:33 +00:00
Anton Yartsev 8fc29db312 [analyzer] +Testcase: several used-after-free args passed to a function.
llvm-svn: 179232
2013-04-10 22:36:16 +00:00
Anton Yartsev cb2ccd6b79 [analyzer] Switched to checkPreCall interface for detecting usage after free.
Now the check is also applied to arguments for Objective-C method calls and to 'this' pointer.

llvm-svn: 179230
2013-04-10 22:21:41 +00:00
Anna Zaks 60d98befe8 [analyzer] Fix a crash in SyntaxCString checker when given a custom strncat.
Fixes PR13476

llvm-svn: 179228
2013-04-10 22:06:29 +00:00
Anna Zaks e51362e7f7 [analyzer] When reporting a leak in RetainCount checker due to an early exit from init, step into init.
The heuristic here (proposed by Jordan) is that, usually, if a leak is due to an early exit from init, the allocation site will be
a call to alloc. Note that in other cases init resets self to [super init], which becomes the allocation site of the object.

llvm-svn: 179221
2013-04-10 21:42:06 +00:00
Anna Zaks 7c19abeba6 [analyzer] Cleanup leak warnings: do not print the names of variables from other functions.
llvm-svn: 179219
2013-04-10 21:42:02 +00:00
Jordan Rose 61e221f68d [analyzer] Replace isIntegerType() with isIntegerOrEnumerationType().
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>

llvm-svn: 179081
2013-04-09 02:30:33 +00:00
Anna Zaks 93a21a8cfe [analyzer] Keep tracking the pointer after the escape to more aggressively report mismatched deallocator
Test that the path notes do not change. I don’t think we should print a note on escape.

Also, I’ve removed a check that assumed that the family stored in the RefStete could be
AF_None and added an assert in the constructor.

llvm-svn: 179075
2013-04-09 00:30:28 +00:00
Ted Kremenek e06df46f3f Tweak warning text for nil value in ObjC container warning.
llvm-svn: 179034
2013-04-08 18:09:16 +00:00
Jordan Rose 4db7c1e7e5 [analyzer] When creating a trimmed graph, preserve whether a node is a sink.
This is important because sometimes two nodes are identical, except the
second one is a sink.

This bug has probably been around for a while, but it wouldn't have been an
issue in the old report graph algorithm. I'm ashamed to say I actually looked
at this the first time around and thought it would never be a problem...and
then didn't include an assertion to back that up.

PR15684

llvm-svn: 178944
2013-04-06 01:42:02 +00:00
Anna Zaks a1de8567fc [analyzer] Shorten the malloc checker’s leak message
As per Ted’s suggestion!

llvm-svn: 178938
2013-04-06 00:41:36 +00:00
Anna Zaks 4d1e30471d [analyzer] Reword error messages for nil keys and values of NSMutableDictionary.
llvm-svn: 178935
2013-04-05 23:50:18 +00:00
Anna Zaks 94b48bdbba [analyzer] Fix null tracking for the given test case, by using the proper state and removing redundant code.
llvm-svn: 178933
2013-04-05 23:50:11 +00:00
Jordan Rose 10ad081fc6 [analyzer] Re-enable cplusplus.NewDelete (but not NewDeleteLeaks).
As mentioned in the previous commit message, the use-after-free and
double-free warnings for 'delete' are worth enabling even while the
leak warnings still have false positives.

llvm-svn: 178891
2013-04-05 17:55:07 +00:00
Jordan Rose 26330563f2 [analyzer] Split new/delete checker into use-after-free and leaks parts.
This splits the leak-checking part of alpha.cplusplus.NewDelete into a
separate user-level checker, alpha.cplusplus.NewDeleteLeaks. All the
difficult false positives we've seen with the new/delete checker have been
spurious leak warnings; the use-after-free warnings and mismatched
deallocator warnings, while rare, have always been valid.

<rdar://problem/6194569>

llvm-svn: 178890
2013-04-05 17:55:00 +00:00
Anton Yartsev f0593d67a7 [analyzer] Path notes for the MismatchedDeallocator checker.
llvm-svn: 178862
2013-04-05 11:25:10 +00:00
Anton Yartsev cd65509322 [analyzer] Better name for the test.
llvm-svn: 178861
2013-04-05 10:49:41 +00:00
Anna Zaks ece622ab46 [analyzer] Show path diagnostic for C++ initializers
Also had to modify the PostInitializer ProgramLocation to contain the field region.

llvm-svn: 178826
2013-04-05 00:59:33 +00:00
Anton Yartsev 06dc8aa5f8 [analyzer] Updated the testcase.
Missed check added to testMallocFreeNoWarn().
Removed FIXMEs as the current behaviour is considered acceptable now.

llvm-svn: 178824
2013-04-05 00:37:32 +00:00
Anton Yartsev e3377fbca2 [analyzer] Reduced the unwanted correlations between checkers living inside MallocChecker.cpp
This fixes an issue pointed to by Jordan: if unix.Malloc and unix.MismatchedDeallocator are both on, then we end up still tracking leaks of memory allocated by new.
Moved the guards right before emitting the bug reports to unify and simplify the logic of handling of multiple checkers. Now all the checkers perform their checks regardless of if they were enabled, or not, and it is decided just before the emitting of the report, if it should be emitted. (idea from Anna).

Additional changes: 
improved test coverage for checker correlations;
refactoring: BadDealloc -> MismatchedDealloc

llvm-svn: 178814
2013-04-04 23:46:29 +00:00
Jordan Rose 2de3daa0a2 [analyzer] Enable destructor inlining by default (c++-inlining=destructors).
This turns on not only destructor inlining, but inlining of constructors
for types with non-trivial destructors. Per r178516, we will still not
inline the constructor or destructor of anything that looks like a
container unless the analyzer-config option 'c++-container-inlining' is
set to 'true'.

In addition to the more precise path-sensitive model, this allows us to
catch simple smart pointer issues:

  #include <memory>

  void test() {
    std::auto_ptr<int> releaser(new int[4]);
  } // memory allocated with 'new[]' should not be deleted with 'delete'

<rdar://problem/12295363>

llvm-svn: 178805
2013-04-04 23:10:29 +00:00
Jordan Rose 3903247e48 [analyzer] RetainCountChecker: refactor annotation handling.
...and add a new test case.

I thought this was broken, but it isn't; refactoring and reformatting anyway
so that I don't make the same mistake again. No functionality change.

llvm-svn: 178799
2013-04-04 22:31:48 +00:00
Anna Zaks d3254b4462 [analyzer] Allow tracknullOrUndef look through the ternary operator even when condition is unknown
Improvement of r178684 and r178685.

Jordan has pointed out that I should not rely on the value of the condition to know which expression branch
has been taken. It will not work in cases the branch condition is an unknown value (ex: we do not track the constraints for floats).
The better way of doing this would be to find out if the current node is the right or left successor of the node
that has the ternary operator as a terminator (which is how this is done in other places, like ConditionBRVisitor).

llvm-svn: 178701
2013-04-03 21:34:12 +00:00
Jordan Rose 8647ffcda5 [analyzer] Correctly handle destructors for lifetime-extended temporaries.
The lifetime of a temporary can be extended when it is immediately bound
to a local reference:

  const Value &MyVal = Value("temporary");

In this case, the temporary object's lifetime is extended for the entire
scope of the reference; at the end of the scope it is destroyed.

The analyzer was modeling this improperly in two ways:
- Since we don't model temporary constructors just yet, we create a fake
  temporary region when it comes time to "materialize" a temporary into
  a real object (lvalue). This wasn't taking base casts into account when
  the bindings being materialized was Unknown; now it always respects base
  casts except when the temporary region is itself a pointer.
- When actually destroying the region, the analyzer did not actually load
  from the reference variable -- it was basically destroying the reference
  instead of its referent. Now it does do the load.

This will be more useful whenever we finally start modeling temporaries,
or at least those that get bound to local reference variables.

<rdar://problem/13552274>

llvm-svn: 178697
2013-04-03 21:16:58 +00:00
Anna Zaks 8ef07e5181 [analyzer] Rename “Mac OS X API”, “Mac OS API” -> “API Misuse (Apple)”
As they are relevant on both Mac and iOS.

llvm-svn: 178687
2013-04-03 19:28:22 +00:00
Anna Zaks c610bcacde [analyzer] Warn when nil receiver results in forming null reference
This also allows us to ensure IDC/return null suppression gets triggered in such cases.

llvm-svn: 178686
2013-04-03 19:28:19 +00:00
Anna Zaks b5d2fe8a1d [analyzer] make peelOffOuterExpr in BugReporterVisitors recursively peel off select Exprs
llvm-svn: 178685
2013-04-03 19:28:15 +00:00
Anna Zaks ede0983f88 [analyzer] Properly handle the ternary operator in trackNullOrUndefValue
1) Look for the node where the condition expression is live when checking if
it is constrained to true or false.

2) Fix a bug in ProgramState::isNull, which was masking the problem. When
the expression is not a symbol (,which is the case when it is Unknown) return
unconstrained value, instead of value constrained to “false”!
(Thankfully other callers of isNull have not been effected by the bug.)

llvm-svn: 178684
2013-04-03 19:28:12 +00:00
Jordan Rose bc74eb1c90 [analyzer] Better model for copying of array fields in implicit copy ctors.
- Find the correct region to represent the first array element when
  constructing a CXXConstructorCall.
- If the array is trivial, model the copy with a primitive load/store.
- Don't warn about the "uninitialized" subscript in the AST -- we don't use
  the helper variable that Sema provides.

<rdar://problem/13091608>

llvm-svn: 178602
2013-04-03 01:39:08 +00:00
Anton Yartsev 01acbcebbb [analyzer] Moving cplusplus.NewDelete to alpha.* for now.
llvm-svn: 178529
2013-04-02 05:59:24 +00:00
Anna Zaks 60bf5f45f7 [analyzer] Teach invalidateRegions that regions within LazyCompoundVal need to be invalidated
Refactor invalidateRegions to take SVals instead of Regions as input and teach RegionStore
about processing LazyCompoundVal as a top-level “escaping” value.

This addresses several false positives that get triggered by the NewDelete checker, but the
underlying issue is reproducible with other checkers as well (for example, MallocChecker).

llvm-svn: 178518
2013-04-02 01:28:24 +00:00
Jordan Rose e189b869c5 [analyzer] For now, don't inline [cd]tors of C++ containers.
This is a heuristic to make up for the fact that the analyzer doesn't
model C++ containers very well. One example is modeling that
'std::distance(I, E) == 0' implies 'I == E'. In the future, it would be
nice to model this explicitly, but for now it just results in a lot of
false positives.

The actual heuristic checks if the base type has a member named 'begin' or
'iterator'. If so, we treat the constructors and destructors of that type
as opaque, rather than inlining them.

This is intended to drastically reduce the number of false positives
reported with experimental destructor support turned on. We can tweak the
heuristic in the future, but we'd rather err on the side of false negatives
for now.

<rdar://problem/13497258>

llvm-svn: 178516
2013-04-02 00:26:35 +00:00
Jordan Rose d11ef1aaf7 [analyzer] Allow suppressing diagnostics reported within the 'std' namespace
This is controlled by the 'suppress-c++-stdlib' analyzer-config flag.
It is currently off by default.

This is more suppression than we'd like to do, since obviously there can
be user-caused issues within 'std', but it gives us the option to wield
a large hammer to suppress false positives the user likely can't work
around.

llvm-svn: 178513
2013-04-02 00:26:15 +00:00
Jordan Rose 8f6b4b043a [analyzer] Handle caching out while evaluating a C++ new expression.
Evaluating a C++ new expression now includes generating an intermediate
ExplodedNode, and this node could very well represent a previously-
reachable state in the ExplodedGraph. If so, we can short-circuit the
rest of the evaluation.

Caught by the assertion a few lines later.

<rdar://problem/13510065>

llvm-svn: 178401
2013-03-30 01:31:42 +00:00
Anton Yartsev 5bfcb2f0ef [analyzer] Garbage removed
llvm-svn: 178398
2013-03-30 01:24:21 +00:00
Anton Yartsev ae3630b011 [analyzer] Test added
llvm-svn: 178397
2013-03-30 01:22:45 +00:00
Anton Yartsev 3dfc33e3ac [analyzer] Enabled unix.Malloc checker.
+ Refactoring.

llvm-svn: 178388
2013-03-30 00:50:37 +00:00
Anton Yartsev fa637577f9 [analyzer] Tests for intersections with other checkers from MallocChecker.cpp factored out to NewDelete-intersections.mm
llvm-svn: 178387
2013-03-30 00:43:02 +00:00
Anna Zaks 8e492c2380 [analyzer] Address Jordan’s review of r178309 - do not register an extra visitor for nil receiver
We can check if the receiver is nil in the node that corresponds to the StmtPoint of the message send.
At that point, the receiver is guaranteed to be live. We will find at least one unreclaimed node due to
my previous commit (look for StmtPoint instead of PostStmt) and the fact that the nil receiver nodes are tagged.

+ a couple of extra tests.

llvm-svn: 178381
2013-03-29 22:32:38 +00:00
Ted Kremenek 1f8e65d88e [analyzer] Add static initializer test case (from <rdar://problem/13227740>).
llvm-svn: 178321
2013-03-29 00:32:36 +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
Anna Zaks 333481b90b [analyzer] Add support for escape of const pointers and use it to allow “newed” pointers to escape
Add a new callback that notifies checkers when a const pointer escapes. Currently, this only works
for const pointers passed as a top level parameter into a function. We need to differentiate the const
pointers escape from regular escape since the content pointed by const pointer will not change;
if it’s a file handle, a file cannot be closed; but delete is allowed on const pointers.

This should suppress several false positives reported by the NewDelete checker on llvm codebase.

llvm-svn: 178310
2013-03-28 23:15:29 +00:00
Anna Zaks 05fb371efc [analyzer] Apply the suppression rules to the nil receiver only if the value participates in the computation of the nil we warn about.
We should only suppress a bug report if the IDCed or null returned nil value is directly related to the value we are warning about. This was
not the case for nil receivers - we would suppress a bug report that had an IDCed nil receiver on the path regardless of how it’s
related to the warning.

1) Thread EnableNullFPSuppression parameter through the visitors to differentiate between tracking the value which
is directly responsible for the bug and other values that visitors are tracking (ex: general tracking of nil receivers).
2) in trackNullOrUndef specifically address the case when a value of the message send is nil due to the receiver being nil.

llvm-svn: 178309
2013-03-28 23:15:22 +00:00
Anton Yartsev 0578959981 [analyzer] These implements unix.MismatchedDeallocatorChecker checker.
+ Improved display names for allocators and deallocators

The checker checks if a deallocation function matches allocation one. ('free' for 'malloc', 'delete' for 'new' etc.)

llvm-svn: 178250
2013-03-28 17:05:19 +00:00