Commit Graph

2687 Commits

Author SHA1 Message Date
Gabor Marton 01c9700aaa [analyzer][solver] Remove reference to RangedConstraintManager
We no longer need a reference to RangedConstraintManager, we call top
level `State->assume` functions.

Differential Revision: https://reviews.llvm.org/D113261
2021-11-12 11:44:49 +01:00
Gabor Marton 806329da07 [analyzer][solver] Iterate to a fixpoint during symbol simplification with constants
D103314 introduced symbol simplification when a new constant constraint is
added. Currently, we simplify existing equivalence classes by iterating over
all existing members of them and trying to simplify each member symbol with
simplifySVal.

At the end of such a simplification round we may end up introducing a
new constant constraint. Example:
```
  if (a + b + c != d)
    return;
  if (c + b != 0)
    return;
  // Simplification starts here.
  if (b != 0)
    return;
```
The `c == 0` constraint is the result of the first simplification iteration.
However, we could do another round of simplification to reach the conclusion
that `a == d`. Generally, we could do as many new iterations until we reach a
fixpoint.

We can reach to a fixpoint by recursively calling `State->assume` on the
newly simplified symbol. By calling `State->assume` we re-ignite the
whole assume machinery (along e.g with adjustment handling).

Why should we do this? By reaching a fixpoint in simplification we are capable
of discovering infeasible states at the moment of the introduction of the
**first** constant constraint.
Let's modify the previous example just a bit, and consider what happens without
the fixpoint iteration.
```
  if (a + b + c != d)
    return;
  if (c + b != 0)
    return;
  // Adding a new constraint.
  if (a == d)
    return;
  // This brings in a contradiction.
  if (b != 0)
    return;
  clang_analyzer_warnIfReached(); // This produces a warning.
              // The path is already infeasible...
  if (c == 0) // ...but we realize that only when we evaluate `c == 0`.
    return;
```
What happens currently, without the fixpoint iteration? As the inline comments
suggest, without the fixpoint iteration we are doomed to realize that we are on
an infeasible path only after we are already walking on that. With fixpoint
iteration we can detect that before stepping on that. With fixpoint iteration,
the `clang_analyzer_warnIfReached` does not warn in the above example b/c
during the evaluation of `b == 0` we realize the contradiction. The engine and
the checkers do rely on that either `assume(Cond)` or `assume(!Cond)` should be
feasible. This is in fact assured by the so called expensive checks
(LLVM_ENABLE_EXPENSIVE_CHECKS). The StdLibraryFuncionsChecker is notably one of
the checkers that has a very similar assertion.

Before this patch, we simply added the simplified symbol to the equivalence
class. In this patch, after we have added the simplified symbol, we remove the
old (more complex) symbol from the members of the equivalence class
(`ClassMembers`). Removing the old symbol is beneficial because during the next
iteration of the simplification we don't have to consider again the old symbol.

Contrary to how we handle `ClassMembers`, we don't remove the old Sym->Class
relation from the `ClassMap`. This is important for two reasons: The
constraints of the old symbol can still be found via it's equivalence class
that it used to be the member of (1). We can spare one removal and thus one
additional tree in the forest of `ClassMap` (2).

Performance and complexity: Let us assume that in a State we have N non-trivial
equivalence classes and that all constraints and disequality info is related to
non-trivial classes. In the worst case, we can simplify only one symbol of one
class in each iteration. The number of symbols in one class cannot grow b/c we
replace the old symbol with the simplified one. Also, the number of the
equivalence classes can decrease only, b/c the algorithm does a merge operation
optionally. We need N iterations in this case to reach the fixpoint. Thus, the
steps needed to be done in the worst case is proportional to `N*N`. Empirical
results (attached) show that there is some hardly noticeable run-time and peak
memory discrepancy compared to the baseline. In my opinion, these differences
could be the result of measurement error.
This worst case scenario can be extended to that cases when we have trivial
classes in the constraints and in the disequality map are transforming to such
a State where there are only non-trivial classes, b/c the algorithm does merge
operations. A merge operation on two trivial classes results in one non-trivial
class.

Differential Revision: https://reviews.llvm.org/D106823
2021-11-12 11:44:49 +01:00
Denys Petrov a12bfac292 [analyzer] Retrieve a value from list initialization of multi-dimensional array declaration.
Summary: Add support of multi-dimensional arrays in `RegionStoreManager::getBindingForElement`. Handle nested ElementRegion's getting offsets and checking for being in bounds. Get values from the nested initialization lists using obtained offsets.

Differential Revision: https://reviews.llvm.org/D111654
2021-11-08 16:17:55 +02:00
Balazs Benics 9b5c9c469d [analyzer] Dump checker name if multiple checkers evaluate the same call
Previously, if accidentally multiple checkers `eval::Call`-ed the same
`CallEvent`, in debug builds the analyzer detected this and crashed
with the message stating this. Unfortunately, the message did not state
the offending checkers violating this invariant.
This revision addresses this by printing a more descriptive message
before aborting.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D112889
2021-11-02 14:42:14 +01:00
Zarko Todorovski 8659b241ae [clang][NFC] Inclusive terms: Replace uses of whitelist in clang/lib/StaticAnalyzer
Replace variable and functions names, as well as comments that contain whitelist with
more inclusive terms.

Reviewed By: aaron.ballman, martong

Differential Revision: https://reviews.llvm.org/D112642
2021-10-29 16:51:36 -04:00
Denys Petrov 1deccd05ba [analyzer] Retrieve a character from StringLiteral as an initializer for constant arrays.
Summary: Assuming that values of constant arrays never change, we can retrieve values for specific position(index) right from the initializer, if presented. Retrieve a character code by index from StringLiteral which is an initializer of constant arrays in global scope.

This patch has a known issue of getting access to characters past the end of the literal. The declaration, in which the literal is used, is an implicit cast of kind `array-to-pointer`. The offset should be in literal length's bounds. This should be distinguished from the states in the Standard C++20 [dcl.init.string] 9.4.2.3. Example:
  const char arr[42] = "123";
  char c = arr[41]; // OK
  const char * const str = "123";
  char c = str[41]; // NOK

Differential Revision: https://reviews.llvm.org/D107339
2021-10-29 19:44:37 +03:00
Mike Rice 6f9c25167d [OpenMP] Initial parsing/sema for the 'omp loop' construct
Adds basic parsing/sema/serialization support for the #pragma omp loop
directive.

Differential Revision: https://reviews.llvm.org/D112499
2021-10-28 08:26:43 -07:00
Gabor Marton a8297ed994 [Analyzer][solver] Handle adjustments in constraint assignor remainder
We can reuse the "adjustment" handling logic in the higher level
of the solver by calling `State->assume`.

Differential Revision: https://reviews.llvm.org/D112296
2021-10-27 17:14:34 +02:00
Gabor Marton 888af47095 [Analyzer][solver] Simplification: reorganize equalities with adjustment
Initiate the reorganization of the equality information during symbol
simplification. E.g., if we bump into `c + 1 == 0` during simplification
then we'd like to express that `c == -1`. It makes sense to do this only
with `SymIntExpr`s.

Reviewed By: steakhal

Differential Revision: https://reviews.llvm.org/D111642
2021-10-27 16:48:55 +02:00
Denys Petrov 3b1165ba3d [analyzer] Retrieve incomplete array extent from its redeclaration.
Summary: Fix a case when the extent can not be retrieved correctly from incomplete array declaration. Use redeclaration to get the array extent.

Differential Revision: https://reviews.llvm.org/D111542
2021-10-25 15:14:10 +03:00
Denys Petrov 44e803ef6d [analyzer][NFCI] Move a block from `getBindingForElement` to separate functions
Summary:
1. Improve readability by moving deeply nested block of code from RegionStoreManager::getBindingForElement to new separate functions:
- getConstantValFromConstArrayInitializer;
- getSValFromInitListExpr.
2. Handle the case when index is a symbolic value. Write specific test cases.
3. Add test cases when there is no initialization expression presented.
This patch implies to make next patches clearer and easier for review process.

Differential Revision: https://reviews.llvm.org/D106681
2021-10-25 15:14:10 +03:00
Balazs Benics f9db6a44eb Revert "[analyzer][solver] Introduce reasoning for not equal to operator"
This reverts commit cac8808f15.

 #5 0x00007f28ec629859 abort (/lib/x86_64-linux-gnu/libc.so.6+0x25859)
 #6 0x00007f28ec629729 (/lib/x86_64-linux-gnu/libc.so.6+0x25729)
 #7 0x00007f28ec63af36 (/lib/x86_64-linux-gnu/libc.so.6+0x36f36)
 #8 0x00007f28ecc2cc46 llvm::APInt::compareSigned(llvm::APInt const&) const (libLLVMSupport.so.14git+0xeac46)
 #9 0x00007f28e7bbf957 (anonymous namespace)::SymbolicRangeInferrer::VisitBinaryOperator(clang::ento::RangeSet, clang::BinaryOperatorKind, clang::ento::RangeSet, clang::QualType) (libclangStaticAnalyzerCore.so.14git+0x1df957)
 #10 0x00007f28e7bbf2db (anonymous namespace)::SymbolicRangeInferrer::infer(clang::ento::SymExpr const*) (libclangStaticAnalyzerCore.so.14git+0x1df2db)
 #11 0x00007f28e7bb2b5e (anonymous namespace)::RangeConstraintManager::assumeSymNE(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::SymExpr const*, llvm::APSInt const&, llvm::APSInt const&) (libclangStaticAnalyzerCore.so.14git+0x1d2b5e)
 #12 0x00007f28e7bc67af clang::ento::RangedConstraintManager::assumeSymUnsupported(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::SymExpr const*, bool) (libclangStaticAnalyzerCore.so.14git+0x1e67af)
 #13 0x00007f28e7be3578 clang::ento::SimpleConstraintManager::assumeAux(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::NonLoc, bool) (libclangStaticAnalyzerCore.so.14git+0x203578)
 #14 0x00007f28e7be33d8 clang::ento::SimpleConstraintManager::assume(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::NonLoc, bool) (libclangStaticAnalyzerCore.so.14git+0x2033d8)
 #15 0x00007f28e7be32fb clang::ento::SimpleConstraintManager::assume(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::DefinedSVal, bool) (libclangStaticAnalyzerCore.so.14git+0x2032fb)
 #16 0x00007f28e7b15dbc clang::ento::ConstraintManager::assumeDual(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::ento::DefinedSVal) (libclangStaticAnalyzerCore.so.14git+0x135dbc)
 #17 0x00007f28e7b4780f clang::ento::ExprEngine::evalEagerlyAssumeBinOpBifurcation(clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet&, clang::Expr const*) (libclangStaticAnalyzerCore.so.14git+0x16780f)

This is known to be triggered on curl, tinyxml2, tmux, twin and on xerces.
But @bjope also reported similar crashes.
So, I'm reverting it to make our internal bots happy again.

Differential Revision: https://reviews.llvm.org/D106102
2021-10-23 21:01:59 +02:00
Manas cac8808f15 [analyzer][solver] Introduce reasoning for not equal to operator
Prior to this, the solver was only able to verify whether two symbols
are equal/unequal, only when constants were involved. This patch allows
the solver to work over ranges as well.

Reviewed By: steakhal, martong

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

Patch by: @manas (Manas Gupta)
2021-10-22 12:00:08 +02:00
Gabor Marton 5f8dca0235 [Analyzer] Extend ConstraintAssignor to handle remainder op
Summary:
`a % b != 0` implies that `a != 0` for any `a` and `b`. This patch
extends the ConstraintAssignor to do just that. In fact, we could do
something similar with division and in case of multiplications we could
have some other inferences, but I'd like to keep these for future
patches.

Fixes https://bugs.llvm.org/show_bug.cgi?id=51940

Reviewers: noq, vsavchenko, steakhal, szelethus, asdenyspetrov

Subscribers:

Differential Revision: https://reviews.llvm.org/D110357
2021-10-22 10:47:25 +02:00
Gabor Marton e2a2c8328f [Analyzer][NFC] Add RangedConstraintManager to ConstraintAssignor
In this patch we store a reference to `RangedConstraintManager` in the
`ConstraintAssignor`. This way it is possible to call back and reuse some
functions of it. This patch is exclusively needed for its child patches,
it is not intended to be a standalone patch.

Differential Revision: https://reviews.llvm.org/D111640
2021-10-22 10:46:28 +02:00
Gabor Marton 01b4ddbfbb [Analyzer][NFC] Move RangeConstraintManager's def before ConstraintAssignor's def
In this patch we simply move the definition of RangeConstraintManager before
the definition of ConstraintAssignor. This patch is exclusively needed for it's
child patch, so in the child the diff would be clean and the review would be
easier.

Differential Revision: https://reviews.llvm.org/D110387
2021-10-22 10:46:28 +02: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
Kazu Hirata 0abb5d293c [Sema, StaticAnalyzer] Use StringRef::contains (NFC) 2021-10-20 08:02:36 -07:00
Balazs Benics 72d04d7b2b [analyzer] Allow matching non-CallExprs using CallDescriptions
Fallback to stringification and string comparison if we cannot compare
the `IdentifierInfo`s, which is the case for C++ overloaded operators,
constructors, destructors, etc.

Examples:
  { "std", "basic_string", "basic_string", 2} // match the 2 param std::string constructor
  { "std", "basic_string", "~basic_string" }  // match the std::string destructor
  { "aaa", "bbb", "operator int" } // matches the struct bbb conversion operator to int

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D111535
2021-10-18 14:57:24 +02:00
Balazs Benics 3ec7b91141 [analyzer][NFC] Refactor CallEvent::isCalled()
Refactor the code to make it more readable.

It will set up further changes, and improvements to this code in
subsequent patches.
This is a non-functional change.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D111534
2021-10-18 14:57:24 +02:00
Artem Dergachev 12cbc8cbf0 [analyzer] Fix property access kind detection inside parentheses.
'(self.prop)' produces a surprising AST where ParenExpr
resides inside `PseudoObjectExpr.

This breaks ObjCMethodCall::getMessageKind() which in turn causes us
to perform unnecessary dynamic dispatch bifurcation when evaluating
body-farmed property accessors, which in turn causes us
to explore infeasible paths.
2021-10-14 21:07:19 -07:00
Gabor Marton ac3edc5af0 [analyzer][solver] Handle simplification to ConcreteInt
The solver's symbol simplification mechanism was not able to handle cases
when a symbol is simplified to a concrete integer. This patch adds the
capability.

E.g., in the attached lit test case, the original symbol is `c + 1` and
it has a `[0, 0]` range associated with it. Then, a new condition `c == 0`
is assumed, so a new range constraint `[0, 0]` comes in for `c` and
simplification kicks in. `c + 1` becomes `0 + 1`, but the associated
range is `[0, 0]`, so now we are able to realize the contradiction.

Differential Revision: https://reviews.llvm.org/D110913
2021-10-14 17:53:29 +02:00
Kazu Hirata e567f37dab [clang] Use llvm::is_contained (NFC) 2021-10-13 20:41:55 -07:00
Gabor Marton b8f6c85a83 [analyzer][NFC] Add RangeSet::dump
This tiny change improves the debugging experience of the solver a lot!

Differential Revision: https://reviews.llvm.org/D110911
2021-10-06 18:45:07 +02:00
Gabor Marton 792be5df92 [analyzer][solver] Fix CmpOpTable handling bug
There is an error in the implementation of the logic of reaching the `Unknonw` tristate in CmpOpTable.

```
void cmp_op_table_unknownX2(int x, int y, int z) {
  if (x >= y) {
                    // x >= y    [1, 1]
    if (x + z < y)
      return;
                    // x + z < y [0, 0]
    if (z != 0)
      return;
                    // x < y     [0, 0]
    clang_analyzer_eval(x > y);  // expected-warning{{TRUE}} expected-warning{{FALSE}}
  }
}
```
We miss the `FALSE` warning because the false branch is infeasible.

We have to exploit simplification to discover the bug. If we had `x < y`
as the second condition then the analyzer would return the parent state
on the false path and the new constraint would not be part of the State.
But adding `z` to the condition makes both paths feasible.

The root cause of the bug is that we reach the `Unknown` tristate
twice, but in both occasions we reach the same `Op` that is `>=` in the
test case. So, we reached `>=` twice, but we never reached `!=`, thus
querying the `Unknonw2x` column with `getCmpOpStateForUnknownX2` is
wrong.

The solution is to ensure that we reached both **different** `Op`s once.

Differential Revision: https://reviews.llvm.org/D110910
2021-10-06 18:28:03 +02:00
Vince Bridgers b29186c08a [analyzer] canonicalize special case of structure/pointer deref
This simple change addresses a special case of structure/pointer
aliasing that produced different symbolvals, leading to false positives
during analysis.

The reproducer is as simple as this.

```lang=C++
struct s {
  int v;
};

void foo(struct s *ps) {
  struct s ss = *ps;
  clang_analyzer_dump(ss.v); // reg_$1<int Element{SymRegion{reg_$0<struct s *ps>},0 S64b,struct s}.v>
  clang_analyzer_dump(ps->v); //reg_$3<int SymRegion{reg_$0<struct s *ps>}.v>
  clang_analyzer_eval(ss.v == ps->v); // UNKNOWN
}
```

Acks: Many thanks to @steakhal and @martong for the group debug session.

Reviewed By: steakhal, martong

Differential Revision: https://reviews.llvm.org/D110625
2021-10-06 05:18:27 -05:00
Jay Foad d933adeaca [APInt] Stop using soft-deprecated constructors and methods in clang. NFC.
Stop using APInt constructors and methods that were soft-deprecated in
D109483. This fixes all the uses I found in clang.

Differential Revision: https://reviews.llvm.org/D110808
2021-10-04 09:38:11 +01:00
Denys Petrov 98a95d4844 [analyzer] Retrieve a value from list initialization of constant array declaration in a global scope.
Summary: Fix the point that we didn't take into account array's dimension. Retrieve a value of global constant array by iterating through its initializer list.

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

Fixes: https://bugs.llvm.org/show_bug.cgi?id=50604
2021-09-24 12:37:58 +03:00
alokmishra.besu 000875c127 OpenMP 5.0 metadirective
This patch supports OpenMP 5.0 metadirective features.
It is implemented keeping the OpenMP 5.1 features like dynamic user condition in mind.

A new function, getBestWhenMatchForContext, is defined in llvm/Frontend/OpenMP/OMPContext.h

Currently this function return the index of the when clause with the highest score from the ones applicable in the Context.
But this function is declared with an array which can be used in OpenMP 5.1 implementation to select all the valid when clauses which can be resolved in runtime. Currently this array is set to null by default and its implementation is left for future.

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D91944
2021-09-18 13:40:44 -05:00
Nico Weber 31cca21565 Revert "OpenMP 5.0 metadirective"
This reverts commit c7d7b98e52.
Breaks tests on macOS, see comment on https://reviews.llvm.org/D91944
2021-09-18 09:10:37 -04:00
alokmishra.besu 347f3c186d OpenMP 5.0 metadirective
This patch supports OpenMP 5.0 metadirective features.
It is implemented keeping the OpenMP 5.1 features like dynamic user condition in mind.

A new function, getBestWhenMatchForContext, is defined in llvm/Frontend/OpenMP/OMPContext.h

Currently this function return the index of the when clause with the highest score from the ones applicable in the Context.
But this function is declared with an array which can be used in OpenMP 5.1 implementation to select all the valid when clauses which can be resolved in runtime. Currently this array is set to null by default and its implementation is left for future.

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D91944
2021-09-17 16:30:06 -05:00
cchen 7efb825382 Revert "OpenMP 5.0 metadirective"
This reverts commit c7d7b98e52.
2021-09-17 16:14:16 -05:00
cchen c7d7b98e52 OpenMP 5.0 metadirective
This patch supports OpenMP 5.0 metadirective features.
It is implemented keeping the OpenMP 5.1 features like dynamic user condition in mind.

A new function, getBestWhenMatchForContext, is defined in llvm/Frontend/OpenMP/OMPContext.h

Currently this function return the index of the when clause with the highest score from the ones applicable in the Context.
But this function is declared with an array which can be used in OpenMP 5.1 implementation to select all the valid when clauses which can be resolved in runtime. Currently this array is set to null by default and its implementation is left for future.

Reviewed By: jdoerfert

Differential Revision: https://reviews.llvm.org/D91944
2021-09-17 16:03:13 -05:00
Kristóf Umann 0213d7ec0c [analyzer][NFCI] Allow clients of NoStateChangeFuncVisitor to check entire function calls, rather than each ExplodedNode in it
Fix a compilation error due to a missing 'template' keyword.

Differential Revision: https://reviews.llvm.org/D108695
2021-09-13 13:50:01 +02:00
Chris Lattner 735f46715d [APInt] Normalize naming on keep constructors / predicate methods.
This renames the primary methods for creating a zero value to `getZero`
instead of `getNullValue` and renames predicates like `isAllOnesValue`
to simply `isAllOnes`.  This achieves two things:

1) This starts standardizing predicates across the LLVM codebase,
   following (in this case) ConstantInt.  The word "Value" doesn't
   convey anything of merit, and is missing in some of the other things.

2) Calling an integer "null" doesn't make any sense.  The original sin
   here is mine and I've regretted it for years.  This moves us to calling
   it "zero" instead, which is correct!

APInt is widely used and I don't think anyone is keen to take massive source
breakage on anything so core, at least not all in one go.  As such, this
doesn't actually delete any entrypoints, it "soft deprecates" them with a
comment.

Included in this patch are changes to a bunch of the codebase, but there are
more.  We should normalize SelectionDAG and other APIs as well, which would
make the API change more mechanical.

Differential Revision: https://reviews.llvm.org/D109483
2021-09-09 09:50:24 -07:00
Balazs Benics b97a96400a [analyzer] SValBuilder should have an easy access to AnalyzerOptions
`SVB.getStateManager().getOwningEngine().getAnalysisManager().getAnalyzerOptions()`
is quite a mouthful and might involve a few pointer indirections to get
such a simple thing like an analyzer option.

This patch introduces an `AnalyzerOptions` reference to the `SValBuilder`
abstract class, while refactors a few cases to use this /simpler/ accessor.

Reviewed By: martong, Szelethus

Differential Revision: https://reviews.llvm.org/D108824
2021-09-04 10:19:57 +02:00
Balazs Benics 91c07eb8ee [analyzer] Ignore single element arrays in getStaticSize() conditionally
Quoting https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html:
> In the absence of the zero-length array extension, in ISO C90 the contents
> array in the example above would typically be declared to have a single
> element.

We should not assume that the size of the //flexible array member// field has
a single element, because in some cases they use it as a fallback for not
having the //zero-length array// language extension.
In this case, the analyzer should return `Unknown` as the extent of the field
instead.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D108230
2021-09-04 10:19:57 +02:00
Jessica Paquette b9e57e0305 Revert "[analyzer][NFCI] Allow clients of NoStateChangeFuncVisitor to check entire function calls, rather than each ExplodedNode in it"
This reverts commit a375bfb5b7.

This was causing a bot to crash:

https://green.lab.llvm.org/green/job/clang-stage1-cmake-RA-incremental/23380/
2021-09-03 10:28:07 -07:00
Kristóf Umann a375bfb5b7 [analyzer][NFCI] Allow clients of NoStateChangeFuncVisitor to check entire function calls, rather than each ExplodedNode in it
D105553 added NoStateChangeFuncVisitor, an abstract class to aid in creating
notes such as "Returning without writing to 'x'", or "Returning without changing
the ownership status of allocated memory". Its clients need to define, among
other things, what a change of state is.

For code like this:

f() {
  g();
}

foo() {
  f();
  h();
}

We'd have a path in the ExplodedGraph that looks like this:

             -- <g> -->
            /          \
         ---     <f>    -------->        --- <h> --->
        /                        \      /            \
--------        <foo>             ------    <foo>     -->

When we're interested in whether f neglected to change some property,
NoStateChangeFuncVisitor asks these questions:

                       ÷×~
                -- <g> -->
           ß   /          \$    @&#*
            ---     <f>    -------->        --- <h> --->
           /                        \      /            \
   --------        <foo>             ------    <foo>     -->

Has anything changed in between # and *?
Has anything changed in between & and *?
Has anything changed in between @ and *?
...
Has anything changed in between $ and *?
Has anything changed in between × and ~?
Has anything changed in between ÷ and ~?
...
Has anything changed in between ß and *?
...
This is a rather thorough line of questioning, which is why in D105819, I was
only interested in whether state *right before* and *right after* a function
call changed, and early returned to the CallEnter location:

if (!CurrN->getLocationAs<CallEnter>())
  return;
Except that I made a typo, and forgot to negate the condition. So, in this
patch, I'm fixing that, and under the same hood allow all clients to decide to
do this whole-function check instead of the thorough one.

Differential Revision: https://reviews.llvm.org/D108695
2021-09-03 13:50:18 +02:00
Kristóf Umann 3891b45a06 Revert "[analyzer][NFCI] Allow clients of NoStateChangeFuncVisitor to check entire function calls, rather than each ExplodedNode in it"
This reverts commit 7d0e62bfb7.
2021-09-02 17:19:49 +02:00
Kristóf Umann 7d0e62bfb7 [analyzer][NFCI] Allow clients of NoStateChangeFuncVisitor to check entire function calls, rather than each ExplodedNode in it
D105553 added NoStateChangeFuncVisitor, an abstract class to aid in creating
notes such as "Returning without writing to 'x'", or "Returning without changing
the ownership status of allocated memory". Its clients need to define, among
other things, what a change of state is.

For code like this:

f() {
  g();
}

foo() {
  f();
  h();
}

We'd have a path in the ExplodedGraph that looks like this:

             -- <g> -->
            /          \
         ---     <f>    -------->        --- <h> --->
        /                        \      /            \
--------        <foo>             ------    <foo>     -->

When we're interested in whether f neglected to change some property,
NoStateChangeFuncVisitor asks these questions:

                       ÷×~
                -- <g> -->
           ß   /          \$    @&#*
            ---     <f>    -------->        --- <h> --->
           /                        \      /            \
   --------        <foo>             ------    <foo>     -->

Has anything changed in between # and *?
Has anything changed in between & and *?
Has anything changed in between @ and *?
...
Has anything changed in between $ and *?
Has anything changed in between × and ~?
Has anything changed in between ÷ and ~?
...
Has anything changed in between ß and *?
...
This is a rather thorough line of questioning, which is why in D105819, I was
only interested in whether state *right before* and *right after* a function
call changed, and early returned to the CallEnter location:

if (!CurrN->getLocationAs<CallEnter>())
  return;
Except that I made a typo, and forgot to negate the condition. So, in this
patch, I'm fixing that, and under the same hood allow all clients to decide to
do this whole-function check instead of the thorough one.

Differential Revision: https://reviews.llvm.org/D108695
2021-09-02 16:56:32 +02:00
Fanbo Meng ae206db2d6 [SystemZ][z/OS] Create html report file with text flag
Change OF_None to OF_Text flag in file creation, same reasoning as https://reviews.llvm.org/D97785

Reviewed By: abhina.sreeskantharajan

Differential Revision: https://reviews.llvm.org/D108998
2021-08-31 11:52:04 -04:00
Artem Dergachev 7309359928 [analyzer] Fix scan-build report deduplication.
The previous behavior was to deduplicate reports based on md5 of the
html file. This algorithm might have worked originally but right now
HTML reports contain information rich enough to make them virtually
always distinct which breaks deduplication entirely.

The new strategy is to (finally) take advantage of IssueHash - the
stable report identifier provided by clang that is the same if and only if
the reports are duplicates of each other.

Additionally, scan-build no longer performs deduplication on its own.
Instead, the report file name is now based on the issue hash,
and clang instances will silently refuse to produce a new html file
when a duplicate already exists. This eliminates the problem entirely.

The '-analyzer-config stable-report-filename' option is deprecated
because report filenames are no longer unstable. A new option is
introduced, '-analyzer-config verbose-report-filename', to produce
verbose file names that look similar to the old "stable" file names.
The old option acts as an alias to the new option.

Differential Revision: https://reviews.llvm.org/D105167
2021-08-26 13:34:29 -07:00
Balazs Benics e5646b9254 Revert "Revert "[analyzer] Ignore IncompleteArrayTypes in getStaticSize() for FAMs""
This reverts commit df1f4e0cc6.

Now the test case explicitly specifies the target triple.
I decided to use x86_64 for that matter, to have a fixed
bitwidth for `size_t`.

Aside from that, relanding the original changes of:
https://reviews.llvm.org/D105184
2021-08-25 17:19:06 +02:00
Balazs Benics df1f4e0cc6 Revert "[analyzer] Ignore IncompleteArrayTypes in getStaticSize() for FAMs"
This reverts commit 360ced3b8f.
2021-08-25 16:43:25 +02:00
Balazs Benics 360ced3b8f [analyzer] Ignore IncompleteArrayTypes in getStaticSize() for FAMs
Currently only `ConstantArrayType` is considered for flexible array
members (FAMs) in `getStaticSize()`.
However, `IncompleteArrayType` also shows up in practice as FAMs.

This patch will ignore the `IncompleteArrayType` and return Unknown
for that case as well. This way it will be at least consistent with
the current behavior until we start modeling them accurately.

I'm expecting that this will resolve a bunch of false-positives
internally, caused by the `ArrayBoundV2`.

Reviewed By: ASDenysPetrov

Differential Revision: https://reviews.llvm.org/D105184
2021-08-25 16:12:17 +02:00
Simon Pilgrim ae691648b4 Fix unknown parameter Wdocumentation warning. NFC. 2021-08-19 15:40:10 +01:00
Denys Petrov 9dabacd09f [analyzer] Adjust JS code of analyzer's HTML report for IE support.
Summary: Change and replace some functions which IE does not support. This patch is made as a continuation of D92928 revision. Also improve hot keys behavior.

Differential Revision: https://reviews.llvm.org/D107366
2021-08-17 19:32:34 +03:00
Kristóf Umann c019142a89 [analyzer][NFC] Split the main logic of NoStoreFuncVisitor to an abstract NoStateChangeVisitor class
Preceding discussion on cfe-dev: https://lists.llvm.org/pipermail/cfe-dev/2021-June/068450.html

NoStoreFuncVisitor is a rather unique visitor. As VisitNode is invoked on most
other visitors, they are looking for the point where something changed -- change
on a value, some checker-specific GDM trait, a new constraint.
NoStoreFuncVisitor, however, looks specifically for functions that *didn't*
write to a MemRegion of interesting. Quoting from its comments:

/// Put a diagnostic on return statement of all inlined functions
/// for which  the region of interest \p RegionOfInterest was passed into,
/// but not written inside, and it has caused an undefined read or a null
/// pointer dereference outside.

It so happens that there are a number of other similar properties that are
worth checking. For instance, if some memory leaks, it might be interesting why
a function didn't take ownership of said memory:

void sink(int *P) {} // no notes

void f() {
  sink(new int(5)); // note: Memory is allocated
                    // Well hold on, sink() was supposed to deal with
                    // that, this must be a false positive...
} // warning: Potential memory leak [cplusplus.NewDeleteLeaks]

In here, the entity of interest isn't a MemRegion, but a symbol. The property
that changed here isn't a change of value, but rather liveness and GDM traits
managed by MalloChecker.

This patch moves some of the logic of NoStoreFuncVisitor to a new abstract
class, NoStateChangeFuncVisitor. This is mostly calculating and caching the
stack frames in which the entity of interest wasn't changed.

Descendants of this interface have to define 3 things:

* What constitutes as a change to an entity (this is done by overriding
wasModifiedBeforeCallExit)
* What the diagnostic message should be (this is done by overriding
maybeEmitNoteFor.*)
* What constitutes as the entity of interest being passed into the function (this
is also done by overriding maybeEmitNoteFor.*)

Differential Revision: https://reviews.llvm.org/D105553
2021-08-16 15:03:22 +02:00
Christopher Di Bella c874dd5362 [llvm][clang][NFC] updates inline licence info
Some files still contained the old University of Illinois Open Source
Licence header. This patch replaces that with the Apache 2 with LLVM
Exception licence.

Differential Revision: https://reviews.llvm.org/D107528
2021-08-11 02:48:53 +00:00