80 Commits

Author SHA1 Message Date
Kazu Hirata
a9bf16d961
[StaticAnalyzer] Migrate away from PointerUnion::{is,get} (NFC) (#118421)
Note that PointerUnion::{is,get} have been soft deprecated in
PointerUnion.h:

  // FIXME: Replace the uses of is(), get() and dyn_cast() with
  //        isa<T>, cast<T> and the llvm::dyn_cast<T>

I'm not touching PointerUnion::dyn_cast for now because it's a bit
complicated; we could blindly migrate it to dyn_cast_if_present, but
we should probably use dyn_cast when the operand is known to be
non-null.
2024-12-03 13:53:20 -08:00
Arseniy Zaostrovnykh
dddeec4bec
[analyzer] Avoid out-of-order node traversal on void return (#117863)
The motivating example: https://compiler-explorer.com/z/WjsxYfs43
```C++
#include <stdlib.h>
void inf_loop_break_callee() {
  void* data = malloc(10);
  while (1) {
    (void)data; // line 3
    break; // -> execution continues on line 3 ?!!
  }
}
```

To correct the flow steps in this example (see the fixed version in the
added test case) I changed two things in the engine:
- Make `processCallExit` create a new StmtPoint only for return
  statements. If the last non-jump statement is not a return statement,
  e.g. `(void)data;`, it is no longer inserted in the exploded graph after
  the function exit.
- Skip the purge program points. In the example above, purge
  points are still inserted after the `break;` executes. Now, when the bug
  reporter is looking for the next statement executed after the function
  execution is finished, it will ignore the purge program points, so it
  won't confusingly pick the `(void)data;` statement.

CPP-5778
2024-11-27 14:27:31 +01:00
Arseniy Zaostrovnykh
190449a5d2
[analyzer] Detect leaks of stack addresses via output params, indirect globals 3/3 (#105648)
Fix some false negatives of StackAddrEscapeChecker:
- Output parameters
  ```
  void top(int **out) {
    int local = 42;
    *out = &local; // Noncompliant
  }
  ```
- Indirect global pointers
  ```
  int **global;

  void top() {
    int local = 42;
    *global = &local; // Noncompliant
  }
  ```

Note that now StackAddrEscapeChecker produces a diagnostic if a function
with an output parameter is analyzed as top-level or as a callee. I took
special care to make sure the reports point to the same primary location
and, in many cases, feature the same primary message. That is the
motivation to modify Core/BugReporter.cpp and Core/ExplodedGraph.cpp

To avoid false positive reports when a global indirect pointer is
assigned a local address, invalidated, and then reset, I rely on the
fact that the invalidation symbol will be a DerivedSymbol of a
ConjuredSymbol that refers to the same memory region.

The checker still has a false negative for non-trivial escaping via a
returned value. It requires a more sophisticated traversal akin to
scanReachableSymbols, which out of the scope of this change.

CPP-4734

---------

This is the last of the 3 stacked PRs, it must not be merged before
https://github.com/llvm/llvm-project/pull/105652 and
https://github.com/llvm/llvm-project/pull/105653
2024-08-28 08:36:59 +02:00
Balazs Benics
5c23e27ba1 [analyzer][NFC] Move away from using raw-for loops inside StaticAnalyzer
I'm involved with the Static Analyzer for the most part.
I think we should embrace newer language standard features and gradually
move forward.

Differential Revision: https://reviews.llvm.org/D154325
2023-07-05 08:56:13 +02:00
Dmitri Gribenko
7ebf64f7e9 [clang][analyzer][NFC] Use the operator new directly with the BumpPtrAllocator
Reviewed By: xazax.hun

Differential Revision: https://reviews.llvm.org/D151818
2023-05-31 20:18:30 +02:00
Dmitri Gribenko
0da99ffe1a [clang][analyzer][NFC] Remove unnecessary casts around Allocate function calls
Reviewed By: steakhal

Differential Revision: https://reviews.llvm.org/D151726
2023-05-30 18:10:15 +02:00
Kazu Hirata
ea9d404032 [clang] Use *{Set,Map}::contains (NFC) 2023-03-14 19:17:18 -07:00
Kazu Hirata
2d861436a9 [clang] Remove remaining uses of llvm::Optional (NFC)
This patch removes several "using" declarations and #include
"llvm/ADT/Optional.h".

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-14 13:37:25 -08:00
Kazu Hirata
6ad0788c33 [clang] Use std::optional instead of llvm::Optional (NFC)
This patch replaces (llvm::|)Optional< with std::optional<.  I'll post
a separate patch to remove #include "llvm/ADT/Optional.h".

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-14 12:31:01 -08:00
Kazu Hirata
a1580d7b59 [clang] Add #include <optional> (NFC)
This patch adds #include <optional> to those files containing
llvm::Optional<...> or Optional<...>.

I'll post a separate patch to actually replace llvm::Optional with
std::optional.

This is part of an effort to migrate from llvm::Optional to
std::optional:

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-14 11:07:21 -08:00
Balazs Benics
16be17ad4b [analyzer][NFC] Refactor llvm::isa<> usages in the StaticAnalyzer
It turns out llvm::isa<> is variadic, and we could have used this at a
lot of places.

The following patterns:
  x && isa<T1>(x) || isa<T2>(x) ...
Will be replaced by:
  isa_and_non_null<T1, T2, ...>(x)

Sometimes it caused further simplifications, when it would cause even
more code smell.

Aside from this, keep in mind that within `assert()` or any macro
functions, we need to wrap the isa<> expression within a parenthesis,
due to the parsing of the comma.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D111982
2021-10-20 17:43:31 +02:00
Valeriy Savchenko
a88025672f [analyzer] Consider array subscripts to be interesting lvalues.
Static analyzer has a mechanism of clearing redundant nodes when
analysis hits a certain threshold with a number of nodes in exploded
graph (default is 1000). It is similar to GC and aims removing nodes
not useful for analysis. Unfortunately nodes corresponding to array
subscript expressions (that actively participate in data propagation)
get removed during the cleanup. This might prevent the analyzer from
generating useful notes about where it thinks the data came from.

This fix is pretty much consistent with the way analysis works
already. Lvalue "interestingness" stands for the analyzer's
possibility of tracking values through them.

Differential Revision: https://reviews.llvm.org/D78638
2020-04-23 19:52:45 +03:00
Artem Dergachev
14e9eb3d7c [analyzer] Assign truly stable identifiers to exploded nodes.
ExplodedGraph nodes will now have a numeric identifier stored in them
which will keep track of the order in which the nodes were created
and it will be fully deterministic both accross runs and across machines.

This is extremely useful for debugging as it allows reliably setting
conditional breakpoints by node IDs.

llvm-svn: 375186
2019-10-17 23:10:09 +00:00
Artem Dergachev
6b85f8e99b [analyzer] NFC: Move getStmt() and createEndOfPath() out of PathDiagnostic.
These static functions deal with ExplodedNodes which is something we don't want
the PathDiagnostic interface to know anything about, as it's planned to be
moved out of libStaticAnalyzerCore.

Differential Revision: https://reviews.llvm.org/D67382

llvm-svn: 371659
2019-09-11 20:54:21 +00:00
Kristof Umann
dd53bdbfde [analyzer][CFG] Don't track the condition of asserts
Well, what is says on the tin I guess!

Some more changes:

* Move isInevitablySinking() from BugReporter.cpp to CFGBlock's interface
* Rename and move findBlockForNode() from BugReporter.cpp to
ExplodedNode::getCFGBlock()

Differential Revision: https://reviews.llvm.org/D65287

llvm-svn: 368836
2019-08-14 12:20:08 +00:00
Kristof Umann
fc76d8551f [analyzer][NFC] Refactoring BugReporter.cpp P4.: If it can be const, make it const
When I'm new to a file/codebase, I personally find C++'s strong static type
system to be a great aid. BugReporter.cpp is still painful to read however:
function calls are made with mile long parameter lists, seemingly all of them
taken with a non-const reference/pointer. This patch fixes nothing but this:
make a few things const, and hammer it until it compiles.

Differential Revision: https://reviews.llvm.org/D65382

llvm-svn: 368735
2019-08-13 18:48:08 +00:00
Chandler Carruth
2946cd7010 Update the file headers across all of the LLVM projects in the monorepo
to reflect the new license.

We understand that people may be surprised that we're moving the header
entirely to discuss the new license. We checked this carefully with the
Foundation's lawyer and we believe this is the correct approach.

Essentially, all code in the project is now made available by the LLVM
project under our new license, so you will see that the license headers
include that license only. Some of our contributors have contributed
code under our old license, and accordingly, we have retained a copy of
our old license notice in the top-level files in each project and
repository.

llvm-svn: 351636
2019-01-19 08:50:56 +00:00
Artem Dergachev
057647d878 [AST] [analyzer] NFC: Reuse code in stable ID dumping methods.
Use the new fancy method introduced in r348197 to simplify some code.

Differential Revision: https://reviews.llvm.org/D54488

llvm-svn: 348199
2018-12-03 22:19:05 +00:00
George Karpenkov
ff6df778c6 [analyzer] Fix a bug in "collapsed" graph viewer
Nodes which have only one predecessor and only one successor can not
always be hidden, even if all states are the same.
An additional condition is needed: the predecessor may have only one successor.
This can be seen on this example:

```
  A
 / \
B   C
 \ /
  D
```

Nodes B and C can not be hidden even if all nodes in the graph have the
same state.

Differential Revision: https://reviews.llvm.org/D53735

llvm-svn: 345341
2018-10-25 23:38:58 +00:00
George Karpenkov
98bee02297 [analyzer] Skip printing trivial nodes in exploded graph
A node is considered to be trivial if it only has one successor, one
predecessor, and a state equal to the predecessor.
Can drastically (> 2x) reduce the size of the generated exploded
graph.

Differential Revision: https://reviews.llvm.org/D51665

llvm-svn: 341616
2018-09-07 00:42:32 +00:00
George Karpenkov
84a2b30ba3 [analyzer] Dump stable identifiers for exploded nodes
Differential Revision: https://reviews.llvm.org/D51667

llvm-svn: 341602
2018-09-06 23:08:07 +00:00
George Karpenkov
95363e378a [analyzer] Remove traces of ubigraph visualization
Ubigraph project has been dead since about 2008, and to the best of my
knowledge, no one was using it.
Previously, I wasn't able to launch the existing binary at all.

Differential Revision: https://reviews.llvm.org/D51655

llvm-svn: 341601
2018-09-06 23:07:47 +00:00
Eugene Zelenko
e580d8317e [StaticAnalyzer] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).
llvm-svn: 326146
2018-02-26 23:15:52 +00:00
Mehdi Amini
9670f847b8 [NFC] Header cleanup
Summary: Removed unused headers, replaced some headers with forward class declarations

Patch by: Eugene <claprix@yandex.ru>

Differential Revision: https://reviews.llvm.org/D20100

llvm-svn: 275882
2016-07-18 19:02:11 +00:00
Ben Craig
4067e35fae [Analyzer] Don't cache report generation ExplodedNodes
During the core analysis, ExplodedNodes are added to the
ExplodedGraph, and those nodes are cached for deduplication purposes.

After core analysis, reports are generated. Here, trimmed copies of
the ExplodedGraph are made. Since the ExplodedGraph has already been
deduplicated, there is no need to deduplicate again.

This change makes it possible to add ExplodedNodes to an
ExplodedGraph without the overhead of deduplication. "Uncached" nodes
also cannot be iterated over, but none of the report generation code
attempts to iterate over all nodes. This change reduces the analysis
time of a large .C file from 3m43.941s to 3m40.256s (~1.6% speedup).
It should slightly reduce memory consumption. Gains should be roughly
proportional to the number (and path length) of static analysis
warnings.

This patch enables future work that should remove the need for an
InterExplodedGraphMap inverse map. I plan on using the (now unused)
ExplodedNode link to connect new nodes to the original nodes.

http://reviews.llvm.org/D21229

llvm-svn: 273572
2016-06-23 15:47:12 +00:00
Angel Garcia Gomez
637d1e6694 Roll-back r250822.
Summary: It breaks the build for the ASTMatchers

Subscribers: klimek, cfe-commits

Differential Revision: http://reviews.llvm.org/D13893

llvm-svn: 250827
2015-10-20 13:23:58 +00:00
Angel Garcia Gomez
b5250d3448 Apply modernize-use-default to clang.
Summary: Replace empty bodies of default constructors and destructors with '= default'.

Reviewers: bkramer, klimek

Subscribers: klimek, alexfh, cfe-commits

Differential Revision: http://reviews.llvm.org/D13890

llvm-svn: 250822
2015-10-20 12:52:55 +00:00
Ted Kremenek
3a0678e33c [analyzer] Apply whitespace cleanups by Honggyu Kim.
llvm-svn: 246978
2015-09-08 03:50:52 +00:00
Benjamin Kramer
ad8e079c61 Reduce double set lookups. NFC.
llvm-svn: 219504
2014-10-10 15:32:48 +00:00
David Blaikie
b564d1fb43 unique_ptrify ExplodedGraph::trim
llvm-svn: 217208
2014-09-05 00:04:19 +00:00
Craig Topper
0dbb783c7b [C++11] Use 'nullptr'. StaticAnalyzer edition.
llvm-svn: 209642
2014-05-27 02:45:47 +00:00
Anton Yartsev
68a172ca16 [analyzer] Fix for PR18394.
Additional conditions that prevent useful nodes before call from being reclaimed.

llvm-svn: 202553
2014-02-28 22:29:48 +00:00
Robert Wilhelm
25284cc95b Use pop_back_val() instead of both back() and pop_back().
No functionality change intended.

llvm-svn: 189112
2013-08-23 16:11:15 +00:00
Anna Zaks
54417f6d68 [analyzer] Cleanup: only get the PostStmt when we need the underlying Stmt + comment
llvm-svn: 178153
2013-03-27 17:36:01 +00:00
Jordan Rose
25fac2f6dc Revert "[analyzer] Break cycles (optionally) when trimming an ExplodedGraph."
The algorithm used here was ridiculously slow when a potential back-edge
pointed to a node that already had a lot of successors. The previous commit
makes this feature unnecessary anyway.

This reverts r177468 / f4cf6b10f863b9bc716a09b2b2a8c497dcc6aa9b.

Conflicts:

	lib/StaticAnalyzer/Core/BugReporter.cpp

llvm-svn: 177765
2013-03-22 21:15:33 +00:00
Jordan Rose
34e19a1d1d [analyzer] Break cycles (optionally) when trimming an ExplodedGraph.
Having a trimmed graph with no cycles (a DAG) is much more convenient for
trying to find shortest paths, which is exactly what BugReporter needs to do.

Part of the performance work for <rdar://problem/13433687>.

llvm-svn: 177468
2013-03-20 00:35:31 +00:00
Jordan Rose
0833c84a50 [analyzer] Eliminate InterExplodedGraphMap class and NodeBackMap typedef.
...in favor of this typedef:

  typedef llvm::DenseMap<const ExplodedNode *, const ExplodedNode *>
          InterExplodedGraphMap;

Use this everywhere the previous class and typedef were used.

Took the opportunity to ArrayRef-ize ExplodedGraph::trim while I'm at it.

No functionality change.

llvm-svn: 177215
2013-03-16 01:07:53 +00:00
Ted Kremenek
f352d8c7ec [analyzer] Add stop-gap patch to prevent assertion failure when analyzing LLVM codebase.
This potentially reduces a performance optimization of throwing away
PreStmtPurgeDeadSymbols nodes.  I'll investigate the performance impact
soon and see if we need something better.

llvm-svn: 176149
2013-02-27 01:26:58 +00:00
Ted Kremenek
8f5640588a [analyzer] Recover all PreStmtPurgeDeadSymbols nodes with a single successor or predecessor.
These nodes are never consulted by any analyzer client code, so they are
used only for machinery for removing dead bindings.  Once successor nodes
are generated they can be safely removed.

This greatly reduces the amount of nodes that are generated in some case,
lowering the memory regression when analyzing Sema.cpp introduced by
r176010 from 14% to 2%.

llvm-svn: 176050
2013-02-25 21:32:40 +00:00
Ted Kremenek
04fa9e3d80 [analyzer] add the notion of an "interesting" lvalue expression for ExplodedNode pruning.
r175988 modified the ExplodedGraph trimming algorithm to retain all
nodes for "lvalue" expressions.  This patch refines that notion to
only "interesting" expressions that would be used for diagnostics.

llvm-svn: 176010
2013-02-25 07:37:13 +00:00
Ted Kremenek
9625048278 [analyzer] tracking stores/constraints now works for ObjC ivars or struct fields.
This required more changes than I originally expected:

- ObjCIvarRegion implements "canPrintPretty" et al
- DereferenceChecker indicates the null pointer source is an ivar
- bugreporter::trackNullOrUndefValue() uses an alternate algorithm
  to compute the location region to track by scouring the ExplodedGraph.
  This allows us to get the actual MemRegion for variables, ivars,
  fields, etc.  We only hand construct a VarRegion for C++ references.
- ExplodedGraph no longer drops nodes for expressions that are marked
  'lvalue'.  This is to facilitate the logic in the previous bullet.
  This may lead to a slight increase in size in the ExplodedGraph,
  which I have not measured, but it is likely not to be a big deal.

I have validated each of the changed plist output.

Fixes <rdar://problem/12114812>

llvm-svn: 175988
2013-02-24 07:21:01 +00:00
David Blaikie
87396b9b08 Replace ProgramPoint llvm::cast support to be well-defined.
See r175462 for another example/more details.

llvm-svn: 175812
2013-02-21 22:23:56 +00:00
Jordan Rose
b10aae3fec [analyzer] Remove isa<> followed by dyn_cast<>.
llvm-svn: 169530
2012-12-06 18:58:29 +00:00
Chandler Carruth
3a02247dc9 Sort all of Clang's files under 'lib', and fix up the broken headers
uncovered.

This required manually correcting all of the incorrect main-module
headers I could find, and running the new llvm/utils/sort_includes.py
script over the files.

I also manually added quite a few missing headers that were uncovered by
shuffling the order or moving headers up to be main-module-headers.

llvm-svn: 169237
2012-12-04 09:13:33 +00:00
Jordan Rose
199fdd825f [analyzer] Use the CallEnter node to get a value for tracked null arguments.
Additionally, don't collect PostStore nodes -- they are often used in
path diagnostics.

Previously, we tried to track null arguments in the same way as any other
null values, but in many cases the necessary nodes had already been
collected (a memory optimization in ExplodedGraph). Now, we fall back to
using the value of the argument at the time of the call, which may not
always match the actual contents of the region, but often will.

This is a precursor to improving our suppression heuristic.
<rdar://problem/12350829>

llvm-svn: 166940
2012-10-29 17:31:53 +00:00
Jordan Rose
746c06d0bc [analyzer] Replace -analyzer-no-eagerly-trim-egraph with graph-trim-interval.
After every 1000 CFGElements processed, the ExplodedGraph trims out nodes
that satisfy a number of criteria for being "boring" (single predecessor,
single successor, and more). Rather than controlling this with a cc1 option,
which can only disable this behavior, we now have an analyzer-config option,
'graph-trim-interval', which can change this interval from 1000 to something
else. Setting the value to 0 disables reclamation.

The next commit relies on this behavior to actually test anything.

llvm-svn: 166528
2012-10-23 23:59:05 +00:00
Jordan Rose
5a751b993f [analyzer] Allow a BugReport to be marked "invalid" during path generation.
This is intended to allow visitors to make decisions about whether a
BugReport is likely a false positive. Currently there are no visitors
making use of this feature, so there are no tests.

When a BugReport is marked invalid, the invalidator must provide a key
that identifies the invaliation (intended to be the visitor type and a
context pointer of some kind). This allows us to reverse the decision
later on. Being able to reverse a decision about invalidation gives us more
flexibility, and allows us to formulate conditions like "this report is
invalid UNLESS the original argument is 'foo'". We can use this to
fine-tune our false-positive suppression (coming soon).

llvm-svn: 164446
2012-09-22 01:24:53 +00:00
Anna Zaks
67e0062b7c [analyzer] Explain why we need condition 8.
llvm-svn: 163394
2012-09-07 16:22:09 +00:00
Ted Kremenek
891bcdb644 ExplodedGraph::shouldCollectNode() should not collect nodes for non-Expr Stmts
(as this previously was the case before this was refactored).  We also shouldn't
need to specially handle BinaryOperators since the eagerly-assume heuristic tags
such nodes.

llvm-svn: 163374
2012-09-07 06:56:18 +00:00
Jordan Rose
e537cc05f5 [analyzer] Rename CallEvent::mayBeInlined to CallEvent::isCallStmt.
The two callers are using this in order to be conservative, so let's just
clarify the information that's actually being provided here. This is not
related to inlining decisions in any way.

No functionality change.

llvm-svn: 162717
2012-08-28 00:50:38 +00:00