Commit Graph

66 Commits

Author SHA1 Message Date
Ted Kremenek aed4677a1c -Wuninitialized: fix insidious bug resulting from interplay of blocks and dead code. Fixes <rdar://problem/10060250>.
llvm-svn: 139027
2011-09-02 19:39:26 +00:00
Ted Kremenek adfb445466 Constify the result of CFGStmt::getStmt().
llvm-svn: 138408
2011-08-23 23:05:04 +00:00
Ted Kremenek 417d566775 Remove dead code.
llvm-svn: 138183
2011-08-20 01:15:28 +00:00
Chad Rosier 6fdf38bfbd Fix else style. No functionality change intended.
llvm-svn: 137896
2011-08-17 23:08:45 +00:00
Ted Kremenek 5ef32dbf2a Cleanup various declarations of 'Stmt*' to be 'Stmt *', etc. in libAnalyzer and libStaticAnalyzer[*]. It was highly inconsistent, and very ugly to look at.
llvm-svn: 137537
2011-08-12 23:37:29 +00:00
Ted Kremenek a0cdf58b0c Fix another -Wuninitialized assertion failure (this one involving bit casts) resulting from the recent -Wuninitialized changes.
llvm-svn: 137068
2011-08-08 21:43:08 +00:00
Ted Kremenek 75842e4946 Fix assertion failure in -Wuninitialized involving no-op casts. Fixes PR 10577.
llvm-svn: 136939
2011-08-04 22:40:57 +00:00
Chris Lattner 0e62c1cc0b remove unneeded llvm:: namespace qualifiers on some core types now that LLVM.h imports
them into the clang namespace.

llvm-svn: 135852
2011-07-23 10:55:15 +00:00
Chandler Carruth 4dd6c043ae Move duplicate uninitialized warning suppression into the
AnalysisBasedWarnings Sema layer and out of the Analysis library itself.
This returns the uninitialized values analysis to a more pure form,
allowing its original logic to correctly detect some categories of
definitely uninitialized values. Fixes PR10358 (again).

Thanks to Ted for reviewing and updating this patch after his rewrite of
several portions of this analysis.

llvm-svn: 135748
2011-07-22 05:27:52 +00:00
Ted Kremenek 81383c20e4 Fix -Wuninitialized regression involving functions invalidating parameters passed by reference.
llvm-svn: 135610
2011-07-20 19:49:47 +00:00
Ted Kremenek 65b3e0649c Fix false negative in -Wuninitialized involving a () wrapping an lvalue-to-rvalue conversion in a DeclStmt.
llvm-svn: 135525
2011-07-19 21:41:51 +00:00
Ted Kremenek 5d855bf7f2 Fix assertion failure in UninitializedValues.cpp where an lvalue to rvalue conversion is wrapped in a parenthesis.
llvm-svn: 135519
2011-07-19 20:33:49 +00:00
Ted Kremenek 9e100ea1a8 Reduce -Wuninitialized time by 22% (on sqlite) by removing the recursive AST crawl.
This is accomplished by forcing the needed expressions for -Wuninitialized to always be CFGElements in the CFG.
This allows us to remove a fair amount of the code for -Wuninitialized.

Some fallout:
- AnalysisBasedWarnings.cpp now specifically toggles the CFGBuilder to create a CFG that is suitable for -Wuninitialized.  This
is a layering violation, since the logic for -Wuninitialized is in libAnalysis.  This can be fixed with the proper refactoring.
- Some of the source locations for -Wunreachable-code warnings have shifted.  While not ideal, this is okay because that analysis
already needs some serious reworking.

llvm-svn: 135480
2011-07-19 14:18:48 +00:00
Chandler Carruth 7cf5a37605 Revert r135217, which wasn't the correct fix for PR10358. With this
patch, we actually move the state-machine for the value set backwards
one step. This can pretty easily lead to infinite loops where we
continually try to propagate a bit, succeed for one iteration, but then
back up because we find an uninitialized use.

A reduced test case from PR10379 is included.

llvm-svn: 135359
2011-07-16 22:27:02 +00:00
Ted Kremenek f0b28d7fe5 Fix false negative reported in PR 10358 by using 'Unknown' in -Wuninitialized to avoid cascading warnings. Patch by Kaelyn Uhrain.
llvm-svn: 135217
2011-07-14 23:43:06 +00:00
Chandler Carruth a532863131 Make the worklist in the uninitialized values checker actually a queue.
Previously, despite the names 'enqueue' and 'dequeue', it behaved as
a stack and visited blocks in a LIFO fashion. This interacts badly with
extremely broad CFGs *inside* of a loop (such as a large switch inside
a state machine) where every block updates a different variable.

When encountering such a CFG, the checker visited blocks in essentially
a "depth first" order due to the stack-like behavior of the work list.
Combined with each block updating a different variable, the saturation
logic of the checker caused it to re-traverse blocks [1,N-1] of the
broad CFG inside the loop after traversing block N. These re-traversals
were to propagate the variable values derived from block N. Assuming
approximately the same number of variables as inner blocks exist, the
end result is O(N^2) updates. By making this a queue, we also make the
traversal essentially "breadth-first" across each of the N inner blocks
of the loop. Then all of this state is propagated around to all N inner
blocks of the loop. The result is O(N) updates.

The truth is in the numbers:
Before, gcc.c:   96409 block visits  (max: 61546,   avg: 591)
After,  gcc.c:   69958 block visits  (max: 33090,   avg: 429)
Before, PR10183: 2540494 block vists (max: 2536495, avg: 37360)
After,  PR10183: 137803 block visits (max: 134406,  avg: 2026)

The nearly 20x reduction in work for PR10183 corresponds to a roughly
100x speedup in compile time.

I've tested it on all the code I can get my hands on, and I've seen no
slowdowns due to this change. Where I've collected stats, the ammount of
work done is on average less. I'll also commit shortly some synthetic
test cases useful in analyzing the performance of CFG-based warnings.

Submitting this based on Doug's feedback that post-commit review should
be good. Ted, please review! Hopefully this helps compile times until
then.

llvm-svn: 134697
2011-07-08 11:19:06 +00:00
Chandler Carruth b4836ea7a8 Build up statistics about the work done for analysis based warnings.
Special detail is added for uninitialized variable analysis as this has
serious performance problems than need to be tracked.

Computing some of this data is expensive, for example walking the CFG to
determine its size. To avoid doing that unless the stats data is going
to be used, we thread a bit into the Sema object to track whether
detailed stats should be collected or not. This bit is used to avoid
computations whereever the computations are likely to be more expensive
than checking the state of the flag. Thus, counters are in some cases
unconditionally updated, but the more expensive (and less frequent)
aggregation steps are skipped.

With this patch, we're able to see that for 'gcc.c':
*** Analysis Based Warnings Stats:
232 functions analyzed (0 w/o CFGs).
  7151 CFG blocks built.
  30 average CFG blocks per function.
  1167 max CFG blocks per function.
163 functions analyzed for uninitialiazed variables
  640 variables analyzed.
  3 average variables per function.
  94 max variables per function.
  96409 block visits.
  591 average block visits per function.
  61546 max block visits per function.

And for the reduced testcase in PR10183:
*** Analysis Based Warnings Stats:
98 functions analyzed (0 w/o CFGs).
  8526 CFG blocks built.
  87 average CFG blocks per function.
  7277 max CFG blocks per function.
68 functions analyzed for uninitialiazed variables
  1359 variables analyzed.
  19 average variables per function.
  1196 max variables per function.
  2540494 block visits.
  37360 average block visits per function.
  2536495 max block visits per function.

That last number is the somewhat scary one that indicates the problem in
PR10183.

llvm-svn: 134494
2011-07-06 16:21:37 +00:00
Argyrios Kyrtzidis b3483b3d91 Utilize PackedVector, introduced with llvm commit r132325.
llvm-svn: 132326
2011-05-31 03:56:09 +00:00
Ted Kremenek efdb7fe53b Fix crash in -Wuninitialized when using switch statments whose condition is a logical operation.
llvm-svn: 131158
2011-05-10 22:10:35 +00:00
Chandler Carruth 6e1f9babcd Silence more -Wnon-pod-memset given its current implementation. I may be
able to revert these based on a patch I'm working on, but no reason for
people to be spammed with warnings in the interim.

llvm-svn: 130394
2011-04-28 08:19:45 +00:00
Douglas Gregor 40965fa78a When we transform a C++ exception declaration (e.g., for template
instantiation), be sure to add the transformed declaration into the
current DeclContext. Also, remove the -Wuninitialized hack that works
around this bug. Fixes <rdar://problem/9200676>.

llvm-svn: 129544
2011-04-14 22:32:28 +00:00
Chandler Carruth 0a7aa3b60b Teach -Wuninitialized about C++'s typeid expression, including both the
evaluated and unevaluated contexts. Add some testing of sizeof and
typeid.

Both of the typeid tests added here were triggering warnings previously.
Now the one false positive is suppressed without suppressing the warning
on actually buggy code.

llvm-svn: 129431
2011-04-13 08:18:42 +00:00
Ted Kremenek 97c393807b Teach -Wuninitialized to not warn about variables declared in C++ catch statements.
llvm-svn: 129102
2011-04-07 20:02:56 +00:00
Chandler Carruth 78c7e34485 Commit a bit of a hack to fully handle the situation where variables are
marked explicitly as uninitialized through direct self initialization:

  int x = x;

With r128894 we prevented warnings about this code, and this patch
teaches the analysis engine to continue analyzing subsequent uses of
'x'. This should wrap up PR9624.

There is still an open question of whether we should suppress the
maybe-uninitialized warnings resulting from variables initialized in
this fashion. The definitely-uninitialized uses should always be warned.

llvm-svn: 128932
2011-04-05 21:36:30 +00:00
Ted Kremenek 378819342e Fix PR 9626 (duplicated self-init warnings under -Wuninitialized) with numerous CFG and UninitializedValues analysis changes:
1) Change the CFG to include the DeclStmt for conditional variables, instead of using the condition itself as a faux DeclStmt.
2) Update ExprEngine (the static analyzer) to understand (1), so not to regress.
3) Update UninitializedValues.cpp to initialize all tracked variables to Uninitialized at the start of the function/method.
4) Only use the SelfReferenceChecker (SemaDecl.cpp) on global variables, leaving the dataflow analysis to handle other cases.

The combination of (1) and (3) allows the dataflow-based -Wuninitialized to find self-init problems when the initializer
contained control-flow.

llvm-svn: 128858
2011-04-04 23:29:12 +00:00
Ted Kremenek 352a7081a8 -Wuninitialized: don't warn about uninitialized variables in unreachable code.
llvm-svn: 128840
2011-04-04 20:30:58 +00:00
Ted Kremenek 77361761fb -Wuninitialized should not warn about variables captured by blocks as byref.
Note this can potentially be enhanced to detect if the __block variable
is actually written by the block, or only when the block "escapes" or
is actually used, but that requires more analysis than it is probably worth
for this simple check.

llvm-svn: 128681
2011-03-31 22:32:41 +00:00
Ted Kremenek 03325c4be9 Add workaround for Sema issue found in <rdar://problem/9188004>, which leads to an assertion failure in the uninitialized variables analysis. The problem is that Sema isn't properly registering a variable in a DeclContext (which -Wuninitialized relies on), but
my expertise on the template instantiation logic isn't good enough to fix this problem for real.  This patch worksaround the
problem in -Wuninitialized, but we should fix it for real later.

llvm-svn: 128443
2011-03-29 01:40:00 +00:00
Benjamin Kramer 8aef596dec Make helpers static.
llvm-svn: 128339
2011-03-26 12:38:21 +00:00
Ted Kremenek c15a4e4b37 Extend -Wuninitialized to support vector types.
llvm-svn: 127794
2011-03-17 03:06:11 +00:00
Ted Kremenek e3ae0a4c47 Appease GCC. I'm surprised Clang accepted this.
llvm-svn: 127672
2011-03-15 05:30:12 +00:00
Ted Kremenek 1a47f366b7 Split warnings from -Wuninitialized-experimental into "must-be-initialized" and "may-be-initialized" warnings, each controlled by different flags.
llvm-svn: 127669
2011-03-15 05:22:28 +00:00
Ted Kremenek c8c4e5f371 Split warnings from -Wuninitialized-experimental into "must-be-initialized" and "may-be-initialized" warnings, each controlled by different flags.
llvm-svn: 127666
2011-03-15 04:57:38 +00:00
Ted Kremenek 9b15c962a9 UninitializedValues: introduce ValueVector:reference class to forward to llvm::BitVector. No real functionality change, but this is a stepping stone to moving to tri-state logic.
llvm-svn: 127665
2011-03-15 04:57:32 +00:00
Ted Kremenek d3def3841f UninitializedValues: wrap BitVector references in a new class ValueVector. No functionality change. This defines the minimum interface that ValueVector needs to support when we no longer base it strictly on a direct interpretation of BitVector.
llvm-svn: 127664
2011-03-15 04:57:29 +00:00
Ted Kremenek a895fe999d Substitue term "BitVector" with "ValueVector" to prep for further revisions. No functionality change.
llvm-svn: 127663
2011-03-15 04:57:27 +00:00
Ted Kremenek a0a5ca14d0 Rename UninitializedValuesV2 to UninitializedValues.
llvm-svn: 127657
2011-03-15 03:17:07 +00:00
Ted Kremenek 792798549f Remove old UninitializedValues analysis.
llvm-svn: 127656
2011-03-15 03:17:01 +00:00
John McCall c07a0c7e48 Change the representation of GNU ?: expressions to use a different expression
class and to bind the shared value using OpaqueValueExpr.  This fixes an
unnoticed problem with deserialization of these expressions where the
deserialized form would lose the vital pointer-equality trait;  or rather,
it fixes it because this patch also does the right thing for deserializing
OVEs.

Change OVEs to not be a "temporary object" in the sense that copy elision is
permitted.

This new representation is not totally unawkward to work with, but I think
that's really part and parcel with the semantics we're modelling here.  In
particular, it's much easier to fix things like the copy elision bug and to
make the CFG look right.

I've tried to update the analyzer to deal with this in at least some          
obvious cases, and I think we get a much better CFG out, but the printing
of OpaqueValueExprs probably needs some work.

llvm-svn: 125744
2011-02-17 10:25:35 +00:00
John McCall 8322c3a197 Give some convenient idiomatic accessors to Stmt::child_range and
Stmt::const_child_range, then make a bunch of places use them instead
of the individual iterator accessors.

llvm-svn: 125450
2011-02-13 04:07:26 +00:00
Ted Kremenek 9865d7f0e6 Don't report dead stores on unreachable code paths. Fixes <rdar://problem/8405222>.
llvm-svn: 125415
2011-02-11 23:24:26 +00:00
John McCall 1c9c3fd50a Death to blocks, or at least the word "block" in one particular obnoxiously
ambiguous context.

llvm-svn: 116567
2010-10-15 04:57:14 +00:00
John McCall e302792b61 GCC didn't care for my attempt at API compatibility, so brute-force everything
to the new constants.

llvm-svn: 112047
2010-08-25 11:45:40 +00:00
Ted Kremenek 5d2bb1b9b3 [CFG]
After discussion with Zhongxing, don't force the initializer of DeclStmts to be
block-level expressions.

This led to some interesting fallout:

[UninitializedValues]

Always visit the initializer of DeclStmts (do not assume they are block-level expressions).

[BasicStore]

With initializers of DeclStmts no longer block-level expressions, this causes self-referencing initializers (e.g. 'int x = x') to no longer cause the initialized variable to be live before the DeclStmt.  While this is correct, it caused BasicStore::RemoveDeadBindings() to prune off the values of these variables from the initial store (where they are set to uninitialized).  The fix is to back-port some (and only some) of the lazy-binding logic from RegionStore to
BasicStore.  Now the default values of local variables are determined lazily as opposed
to explicitly initialized.

llvm-svn: 97591
2010-03-02 21:43:54 +00:00
Ted Kremenek d6b8708643 Split libAnalysis into two libraries: libAnalysis and libChecker.
(1) libAnalysis is a generic analysis library that can be used by
    Sema.  It defines the CFG, basic dataflow analysis primitives, and
    inexpensive flow-sensitive analyses (e.g. LiveVariables).

(2) libChecker contains the guts of the static analyzer, incuding the
    path-sensitive analysis engine and domain-specific checks.

Now any clients that want to use the frontend to build their own tools
don't need to link in the entire static analyzer.

This change exposes various obvious cleanups that can be made to the
layout of files and headers in libChecker.  More changes pending.  :)

This change also exposed a layering violation between AnalysisContext
and MemRegion.  BlockInvocationContext shouldn't explicitly know about
BlockDataRegions.  For now I've removed the BlockDataRegion* from
BlockInvocationContext (removing context-sensitivity; although this
wasn't used yet).  We need to have a better way to extend
BlockInvocationContext (and any LocationContext) to add
context-sensitivty.

llvm-svn: 94406
2010-01-25 04:41:41 +00:00
Kovarththanan Rajaratnam 65c6566b5b lib/Analysis: Remove VISIBILITY_HIDDEN from definitions in anonymous namespace
llvm-svn: 90028
2009-11-28 06:07:30 +00:00
Mike Stump 11289f4280 Remove tabs, and whitespace cleanups.
llvm-svn: 81346
2009-09-09 15:08:12 +00:00
Chris Lattner 529efc74ad rename some methods.
llvm-svn: 67923
2009-03-28 06:33:19 +00:00
Chris Lattner 60f36223a9 move library-specific diagnostic headers into library private dirs. Reduce
redundant #includes.  Patch by Anders Johnsen!

llvm-svn: 63271
2009-01-29 05:15:15 +00:00
Chris Lattner 7368d581c1 Split the single monolithic DiagnosticKinds.def file into one
.def file for each library.  This means that adding a diagnostic
to sema doesn't require all the other libraries to be rebuilt.

Patch by Anders Johnsen!

llvm-svn: 63111
2009-01-27 18:30:58 +00:00