Commit Graph

67 Commits

Author SHA1 Message Date
Ted Kremenek a0fa5d6564 Fix another case where we should be using isBeforeInTranslationUnit().
llvm-svn: 163533
2012-09-10 19:07:56 +00:00
Ted Kremenek 54fd079265 Add a few more cases where we should be using isBeforeInTranslationUnit().
llvm-svn: 163531
2012-09-10 19:02:33 +00:00
Ted Kremenek 6c7a5eae6d Revert "Revert Ted's r163489 and r163490, due to breakage."
I need to see how this breaks on other platforms when I fix the issue
that Benjamin Kramer pointed out.

This includes r163489 and r163490, plus a two line change.

llvm-svn: 163512
2012-09-10 14:50:55 +00:00
NAKAMURA Takumi 6eb1399088 Revert Ted's r163489 and r163490, due to breakage.
r163489, "Take another crack at stabilizing the emission order of analyzer"
r163490, "Use isBeforeInTranslationUnitThan() instead of operator<."

llvm-svn: 163497
2012-09-10 09:17:27 +00:00
Ted Kremenek f1fc8ce65d Use isBeforeInTranslationUnitThan() instead of operator<.
llvm-svn: 163490
2012-09-10 06:56:07 +00:00
Ted Kremenek 3d92699d3c Take another crack at stabilizing the emission order of analyzer
diagnostics without using FoldingSetNodeIDs.  This is done
by doing a complete recursive comparison of the PathDiagnostics.

Note that the previous method of comparing FoldingSetNodeIDs did
not end up relying on unstable things such as pointer addresses, so
I suspect this may still have some issues on various buildbots because
I'm not sure if the true source of non-determinism has been eliminated.
The tests pass for me, so the only way to know is to commit this change
and see what happens.

llvm-svn: 163489
2012-09-10 06:20:06 +00:00
Ted Kremenek b0d1c70258 Attempt (again) to stabilize the order of the emission of diagnostics
of the analyzer by using the FullProfile() of a PathDiagnostic
for ordering them.

llvm-svn: 163455
2012-09-08 04:26:37 +00:00
Ted Kremenek 1fdcfcdf13 Revert "Attempt to make the PathDiagnostic emission order more deterministic by"
llvm-svn: 163446
2012-09-08 01:25:00 +00:00
Ted Kremenek af4cc7eab1 Revert "Further tweaks to hopefully make the PathDiagnostic emission more deterministic."
llvm-svn: 163445
2012-09-08 01:24:53 +00:00
Ted Kremenek a11a741e2f Further tweaks to hopefully make the PathDiagnostic emission more deterministic.
llvm-svn: 163430
2012-09-07 23:13:11 +00:00
Ted Kremenek 334ad6ac13 Attempt to make the PathDiagnostic emission order more deterministic by
looking at PathPieces.

llvm-svn: 163427
2012-09-07 22:24:24 +00:00
Jordan Rose cc0b1bfa56 [analyzer] Ensure that PathDiagnostics profile the same regardless of path.
PathDiagnostics are actually profiled and uniqued independently of the
path on which the bug occurred. This is used to merge diagnostics that
refer to the same issue along different paths, as well as by the plist
diagnostics to reference files created by the HTML diagnostics.

However, there are two problems with the current implementation:

1) The bug description is included in the profile, but some
   PathDiagnosticConsumers prefer abbreviated descriptions and some
   prefer verbose descriptions. Fixed by including both descriptions in
   the PathDiagnostic objects and always using the verbose one in the profile.

2) The "minimal" path generation scheme provides extra information about
   which events came from macros that the "extensive" scheme does not.
   This resulted not only in different locations for the plist and HTML
   diagnostics, but also in diagnostics being uniqued in the plist output
   but not in the HTML output. Fixed by storing the "end path" location
   explicitly in the PathDiagnostic object, rather than trying to find the
   last piece of the path when the diagnostic is requested.

This should hopefully finish unsticking our internal buildbot.

llvm-svn: 162965
2012-08-31 00:36:26 +00:00
Ted Kremenek 5bc38bad73 Rework how PathDiagnosticConsumers pass knowledge of what files they
generated for a given diagnostic to another.  Because PathDiagnostics
are specific to a give PathDiagnosticConsumer, store in
a FoldingSet a unique hash for a PathDiagnostic (that will be the same
for the same bug for different PathDiagnosticConsumers) that
stores a list of files generated.  This can then be read by the
other PathDiagnosticConsumers.

This fixes breakage in the PLIST-HTML output.

llvm-svn: 162580
2012-08-24 19:35:19 +00:00
Ted Kremenek 1e60273eed Remove "range_iterator" from PathDiagnosticPiece and just use ArrayRef<SourceRange> for ranges. This
removes conceptual clutter, and can allow us to easy migrate to C++11 style for-range loops if we
ever move to using C++11 in Clang.

llvm-svn: 162029
2012-08-16 17:45:29 +00:00
Ted Kremenek 9bf9af92a4 Allow multiple PathDiagnosticConsumers to be used with a BugReporter at the same time.
This fixes several issues:

- removes egregious hack where PlistDiagnosticConsumer would forward to HTMLDiagnosticConsumer,
but diagnostics wouldn't be generated consistently in the same way if PlistDiagnosticConsumer
was used by itself.

- emitting diagnostics to the terminal (using clang's diagnostic machinery) is no longer a special
case, just another PathDiagnosticConsumer.  This also magically resolved some duplicate warnings,
as we now use PathDiagnosticConsumer's diagnostic pruning, which has scope for the entire translation
unit, not just the scope of a BugReporter (which is limited to a particular ExprEngine).

As an interesting side-effect, diagnostics emitted to the terminal also have their trailing "." stripped,
just like with diagnostics emitted to plists and HTML.  This required some tests to be updated, but now
the tests have higher fidelity with what users will see.

There are some inefficiencies in this patch.  We currently generate the report graph (from the ExplodedGraph)
once per PathDiagnosticConsumer, which is a bit wasteful, but that could be pulled up higher in the
logic stack.  There is some intended duplication, however, as we now generate different PathDiagnostics (for the same issue)
for different PathDiagnosticConsumers.  This is necessary to produce the diagnostics that a particular
consumer expects.

llvm-svn: 162028
2012-08-16 17:45:23 +00:00
Jordan Rose 3eb3cd45b8 [analyzer] Flatten path diagnostics for text output like we do for HTML.
llvm-svn: 161279
2012-08-03 23:08:54 +00:00
Jordan Rose 80880ac7ee [analyzer] Provide useful PathDiagnosticLocations for CallEnter/Exit events.
llvm-svn: 161277
2012-08-03 23:08:44 +00:00
Anna Zaks 4bd96c4469 [analyzer] Fix a typo. Thanks Jordan.
llvm-svn: 161249
2012-08-03 18:30:20 +00:00
Anna Zaks 4c03dfd4b1 [analyzer] Solve another source of non-determinism in the diagnostic
engine.

The code that was supposed to split the tie in a deterministic way is
not deterministic. Most likely one of the profile methods uses a
pointer. After this change we do finally get the consistent diagnostic
output. Testing this requires running the analyzer on large code bases
and diffing the results.

llvm-svn: 161224
2012-08-02 23:41:05 +00:00
Jordan Rose 25bc20f846 [analyzer] Don't crash on implicit statements inside initializers.
Our BugReporter knows how to deal with implicit statements: it looks in
the ParentMap until it finds a parent with a valid location. However, since
initializers are not in the body of a constructor, their sub-expressions are
not in the ParentMap. That was easy enough to fix in AnalysisDeclContext.

...and then even once THAT was fixed, there's still an extra funny case
of Objective-C object pointer fields under ARC, which are initialized with
a top-level ImplicitValueInitExpr. To catch these cases,
PathDiagnosticLocation will now fall back to the start of the current
function if it can't find any other valid SourceLocations. This isn't great,
but it's miles better than a crash.

(All of this is only relevant when constructors and destructors are being
inlined, i.e. under -cfg-add-initializers and -cfg-add-implicit-dtors.)

llvm-svn: 160810
2012-07-26 20:04:30 +00:00
Jordan Rose b970505d0d [analyzer] Handle base class initializers and destructors.
Most of the logic here is fairly simple; the interesting thing is that
we now distinguish complete constructors from base or delegate constructors.
We also make sure to cast to the base class before evaluating a constructor
or destructor, since non-virtual base classes may behave differently.

This includes some refactoring of VisitCXXConstructExpr and VisitCXXDestructor
in order to keep ExprEngine.cpp as clean as possible (leaving the details for
ExprEngineCXX.cpp).

llvm-svn: 160806
2012-07-26 20:04:13 +00:00
Jordan Rose a4c0d21f42 [analyzer] Show paths for destructor calls.
This modifies BugReporter and friends to handle CallEnter and CallExitEnd
program points that came from implicit call CFG nodes (read: destructors).

This required some extra handling for nested implicit calls. For example,
the added multiple-inheritance test case has a call graph that looks like this:

testMultipleInheritance3
  ~MultipleInheritance
    ~SmartPointer
    ~Subclass
      ~SmartPointer
        ***bug here***

In this case we correctly notice that we started in an inlined function
when we reach the CallEnter program point for the second ~SmartPointer.
However, when we reach the next CallEnter (for ~Subclass), we were
accidentally re-using the inner ~SmartPointer call in the diagnostics.

Rather than guess if we saw the corresponding CallExitEnd based on the
contents of the active path, we now just ask the PathDiagnostic if there's
any known stack before popping off the top path.

(A similar issue could have occured without multiple inheritance, but there
wasn't a test case for it.)

llvm-svn: 160804
2012-07-26 20:04:05 +00:00
Jordan Rose fbe6dba15a [analyzer] Make CallEnter, CallExitBegin, and CallExitEnd not be StmtPoints
These ProgramPoints are used in inlining calls,
and not all calls have associated statements anymore.

llvm-svn: 160021
2012-07-10 22:07:52 +00:00
Anna Zaks 7e53bd6fb0 [analyzer] Run remove dead bindings right before leaving a function.
This is needed to ensure that we always report issues in the correct
function. For example, leaks are identified when we call remove dead
bindings. In order to make sure we report a callee's leak in the callee,
we have to run the operation in the callee's context.

This change required quite a bit of infrastructure work since:
 - We used to only run remove dead bindings before a given statement;
here we need to run it after the last statement in the function. For
this, we added additional Program Point and special mode in the
SymbolReaper to remove all symbols in context lower than the current
one.
 - The call exit operation turned into a sequence of nodes, which are
now guarded by CallExitBegin and CallExitEnd nodes for clarity and
convenience.

(Sorry for the long diff.)

llvm-svn: 155244
2012-04-20 21:59:08 +00:00
Ted Kremenek 5a10f08b52 Include the "issue context" (e.g. function or method) where a static analyzer issue occurred in the plist output.
Fixes <rdar://problem/11004527>

llvm-svn: 154030
2012-04-04 18:11:35 +00:00
Anna Zaks a7f457a5ea [analyzer] Shorten the stack hint diagnostic.
Do not display the standard "Returning from 'foo'", when a stack hint is
available.

llvm-svn: 152964
2012-03-16 23:44:28 +00:00
Anna Zaks cba4f298c6 [analyzer] Create symbol-aware stack hints (building upon r152837).
The symbol-aware stack hint combines the checker-provided message
with the information about how the symbol was passed to the callee: as
a parameter or a return value.

For malloc, the generated messages look like this :
"Returning from 'foo'; released memory via 1st parameter"
"Returning from 'foo'; allocated memory via 1st parameter"
"Returning from 'foo'; allocated memory returned"
"Returning from 'foo'; reallocation of 1st parameter failed"


(We are yet to handle cases when the symbol is a field in a struct or
an array element.)

llvm-svn: 152962
2012-03-16 23:24:20 +00:00
Anna Zaks 1ff57d57e8 [analyzer] Allow checkers to supply call stack diagnostic hints for the
BugVisitor DiagnosticPieces.

When checkers create a DiagnosticPieceEvent, they can supply an extra
string, which will be concatenated with the call exit message for every
call on the stack between the diagnostic event and the final bug report.
(This is a simple version, which could be/will be further enhanced.)

For example, this is used in Malloc checker to produce the ",
which allocated memory" in the following example:

static char *malloc_wrapper() { // 2. Entered call from 'use'
    return malloc(12);    // 3. Memory is allocated
}

void use() {
    char *v;
    v = malloc_wrapper(); // 1. Calling 'malloc_wrappers'
        // 4. Returning from 'malloc_wrapper', which allocated memory
}                         // 5. Memory is never released; potential
memory leak

llvm-svn: 152837
2012-03-15 21:13:02 +00:00
Anna Zaks d4e9059fe0 [analyzer] Diagnostics: Supply Caller information even if the bug occurs
in the callee.

llvm-svn: 152734
2012-03-14 18:58:28 +00:00
Anna Zaks 6e5b48a6b4 [analyzer] Call enter/exit diagnostic should refer to caller/callee,
respectively.

llvm-svn: 152676
2012-03-13 22:15:55 +00:00
Ted Kremenek 04e860df2c [analyzer] add a diagnostic event when entering a call via inlining, within the callee, and add an edge.
llvm-svn: 152086
2012-03-06 01:25:01 +00:00
Ted Kremenek 0f0cc35935 [analyzer] when scanning FIDs in a PathDiagnostic, correctly recurse calls and macros.
llvm-svn: 151774
2012-02-29 23:59:20 +00:00
Ted Kremenek 0f70a6f51e [analyzer diagnostics] Refactor filtration for PathDiagnosticConsumers that don't support cross-file diagnostics
into a common place.  Currently enable this filtration for Plist diagnostics as well.

llvm-svn: 151664
2012-02-28 23:27:39 +00:00
Ted Kremenek 60a7820ffe Reapply r151317, but when computing the PathDiagnostic profile and size keep into account the nested structure. Also fix a problem with how
inlining impacted Plist diagnostics, and adjust some ranges in the Plist output due to richer information.

llvm-svn: 151346
2012-02-24 06:00:00 +00:00
Chad Rosier c0ea158a2b Revert r151317 - Rework PathDiagnostics creation.. - to appease buildbots.
llvm-svn: 151338
2012-02-24 02:06:33 +00:00
Ted Kremenek f2131e7d95 Rework PathDiagnostic creation so that call stacks are captured by a nested PathDiagnosticCallPiece.
llvm-svn: 151317
2012-02-24 00:38:56 +00:00
Anna Zaks 95308d3798 [analyzer] Diagnostics: Ensure that the default end of diagnostic path
piece can always be generated.

The default end of diagnostic path piece was failing to generate on a
BlockEdge that was outgoing from a basic block without a terminator,
resulting in a very simple diagnostic being rendered (ex: no path
highlighting or custom visitors). Reuse another function, which is
essentially doing the same thing and correct it not to fail when a block
has no terminator.

llvm-svn: 150659
2012-02-16 03:41:01 +00:00
Ted Kremenek afa6e249cb Change PathDiagnosticPieces to be reference counted (simplifying their management), and introduce 'PathPieces' as a common container for PathDiagnosticPieces.
llvm-svn: 150054
2012-02-08 04:32:34 +00:00
Ted Kremenek 3116c4e5cd Refactor pieces of PathDiagnostic into its own data structure. No functionality change.
llvm-svn: 150053
2012-02-08 04:32:27 +00:00
Ted Kremenek 0298834e46 Create PathDiagnosticCallEnter and PathDiagnosticCallExit, to remark calls in PathDiagnostics from other events. This will
have potential uses later.

llvm-svn: 149960
2012-02-07 02:27:37 +00:00
Ted Kremenek 8e4c4266de Rework flushing of diagnostics to PathDiagnosticConsumer. Now all the reports are batched up before being flushed
to the underlying consumer implementation.  This allows us to unique reports across analyses to multiple functions (which
shows up with inlining).

llvm-svn: 148997
2012-01-25 23:47:14 +00:00
Ted Kremenek c07e34ceed Make PathDiagnosticLocation more resilient to null Stmt pointers.
llvm-svn: 147854
2012-01-10 15:26:13 +00:00
David Blaikie 68e081d606 Unweaken vtables as per http://llvm.org/docs/CodingStandards.html#ll_virtual_anch
llvm-svn: 146959
2011-12-20 02:48:34 +00:00
Douglas Gregor 07216d174e Fix various minor issues find via unreachable code warnings, from
Ahmed Charles!

llvm-svn: 143569
2011-11-02 20:52:01 +00:00
Ted Kremenek 81ce1c8a99 Rename AnalysisContext to AnalysisDeclContext. Not only is this name more accurate, but it frees up the name AnalysisContext for other uses.
llvm-svn: 142782
2011-10-24 01:32:45 +00:00
David Blaikie 53c125d063 Rename PathDiagnosticClient to PathDiagnosticConsumer as per issue 5397
llvm-svn: 140492
2011-09-26 00:51:36 +00:00
Anna Zaks 15ca5e7a21 [analyzer] Fix a bug where PathDiagnosticLocation did not generate a valid range and add asserts to check validity of locations early on. Ignore invalid ranges in PathDiagnosticPiece (they could be added by checker writers).
Addresses radar://10124836 and radar://radar10102244.

llvm-svn: 140218
2011-09-21 00:35:58 +00:00
Anna Zaks d70da08160 [analyzer] Refactor PathDiagnosticLocation: Remove SourceRange member from PathDiagnosticLocation - FullSourceLoc Loc and PathDiagnosticRange Range are sufficient.
llvm-svn: 140206
2011-09-20 23:27:32 +00:00
Anna Zaks 6800ab437c [analyzer] Remove dead code. (This code is trying to implement the idea that PathDiagnosticClient could implement DiagnosticClient and has been dead for a while).
llvm-svn: 140198
2011-09-20 22:30:48 +00:00
Anna Zaks c29bed3989 [analyzer] Refactor PathDiagnosticLocation: Make PathDiagnosticLocation(SourceLocation...) private. Most of the effort here goes to making BugReport refer to a PathDiagnosticLocation instead of FullSourceLocation.
(Another step closer to the goal of having Diagnostics which can recover from invalid SourceLocations.)

llvm-svn: 140182
2011-09-20 21:38:35 +00:00