Commit Graph

2035 Commits

Author SHA1 Message Date
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