Commit Graph

259 Commits

Author SHA1 Message Date
Kazu Hirata 35b4fbb559 [clang] Use std::nullopt instead of None in comments (NFC)
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
2022-12-04 15:57:24 -08:00
Kazu Hirata 180600660b [StaticAnalyzer] Use std::nullopt instead of None (NFC)
This patch mechanically replaces None with std::nullopt where the
compiler would warn if None were deprecated.  The intent is to reduce
the amount of manual work required in migrating from Optional to
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
2022-12-03 11:34:24 -08:00
Balazs Benics 93b98eb399 [analyzer] getBinding should auto-detect type only if it was not given
Casting a pointer to a suitably large integral type by reinterpret-cast
should result in the same value as by using the `__builtin_bit_cast()`.
The compiler exploits this: https://godbolt.org/z/zMP3sG683

However, the analyzer does not bind the same symbolic value to these
expressions, resulting in weird situations, such as failing equality
checks and even results in crashes: https://godbolt.org/z/oeMP7cj8q

Previously, in the `RegionStoreManager::getBinding()` even if `T` was
non-null, we replaced it with `TVR->getValueType()` in case the `MR` was
`TypedValueRegion`.
It doesn't make much sense to auto-detect the type if the type is
already given. By not doing the auto-detection, we would just do the
right thing and perform the load by that type.
This means that we will cast the value to that type.

So, in this patch, I'm proposing to do auto-detection only if the type
was null.

Here is a snippet of code, annotated by the previous and new dump values.
`LocAsInteger` should wrap the `SymRegion`, since we want to load the
address as if it was an integer.
In none of the following cases should type auto-detection be triggered,
hence we should eventually reach an `evalCast()` to lazily cast the loaded
value into that type.

```lang=C++
void LValueToRValueBitCast_dumps(void *p, char (*array)[8]) {
  clang_analyzer_dump(p);     // remained: &SymRegion{reg_$0<void * p>}
  clang_analyzer_dump(array); // remained: {{&SymRegion{reg_$1<char (*)[8] array>}
  clang_analyzer_dump((unsigned long)p);
  // remained: {{&SymRegion{reg_$0<void * p>} [as 64 bit integer]}}
  clang_analyzer_dump(__builtin_bit_cast(unsigned long, p));     <--------- change #1
  // previously: {{&SymRegion{reg_$0<void * p>}}}
  // now:        {{&SymRegion{reg_$0<void * p>} [as 64 bit integer]}}
  clang_analyzer_dump((unsigned long)array); // remained: {{&SymRegion{reg_$1<char (*)[8] array>} [as 64 bit integer]}}
  clang_analyzer_dump(__builtin_bit_cast(unsigned long, array)); <--------- change #2
  // previously: {{&SymRegion{reg_$1<char (*)[8] array>}}}
  // now:        {{&SymRegion{reg_$1<char (*)[8] array>} [as 64 bit integer]}}
}
```

Reviewed By: xazax.hun

Differential Revision: https://reviews.llvm.org/D136603
2022-11-23 15:52:11 +01:00
Tomasz Kamiński 6194229c62 [analyzer] Make directly bounded LazyCompoundVal as lazily copied
Previously, `LazyCompoundVal` bindings to subregions referred by
`LazyCopoundVals`, were not marked as //lazily copied//.

This change returns `LazyCompoundVals` from `getInterestingValues()`,
so their regions can be marked as //lazily copied// in `RemoveDeadBindingsWorker::VisitBinding()`.

Depends on D134947

Authored by: Tomasz Kamiński <tomasz.kamiński@sonarsource.com>

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D135136
2022-10-19 16:06:32 +02:00
Tomasz Kamiński a6b42040ad [analyzer] Fix the liveness of Symbols for values in regions referred by LazyCompoundVal
To illustrate our current understanding, let's start with the following program:
https://godbolt.org/z/33f6vheh1
```lang=c++
void clang_analyzer_printState();

struct C {
   int x;
   int y;
   int more_padding;
};

struct D {
   C c;
   int z;
};

C foo(D d, int new_x, int new_y) {
   d.c.x = new_x;       // B1
   assert(d.c.x < 13);  // C1

   C c = d.c;           // L

   assert(d.c.y < 10);  // C2
   assert(d.z < 5);     // C3

   d.c.y = new_y;       // B2

   assert(d.c.y < 10);  // C4

   return c;  // R
}
```
In the code, we create a few bindings to subregions of root region `d` (`B1`, `B2`), a constrain on the values  (`C1`, `C2`, ….), and create a `lazyCompoundVal` for the part of the region `d` at point `L`, which is returned at point `R`.

Now, the question is which of these should remain live as long the return value of the `foo` call is live. In perfect a word we should preserve:

  # only the bindings of the subregions of `d.c`, which were created before the copy at `L`. In our example, this includes `B1`, and not `B2`.  In other words, `new_x` should be live but `new_y` shouldn’t.

  # constraints on the values of `d.c`, that are reachable through `c`. This can be created both before the point of making the copy (`L`) or after. In our case, that would be `C1` and `C2`. But not `C3` (`d.z` value is not reachable through `c`) and `C4` (the original value of`d.c.y` was overridden at `B2` after the creation of `c`).

The current code in the `RegionStore` covers the use case (1), by using the `getInterestingValues()` to extract bindings to parts of the referred region present in the store at the point of copy. This also partially covers point (2), in case when constraints are applied to a location that has binding at the point of the copy (in our case `d.c.x` in `C1` that has value `new_x`), but it fails to preserve the constraints that require creating a new symbol for location (`d.c.y` in `C2`).

We introduce the concept of //lazily copied// locations (regions) to the `SymbolReaper`, i.e. for which a program can access the value stored at that location, but not its address. These locations are constructed as a set of regions referred to by `lazyCompoundVal`. A //readable// location (region) is a location that //live// or //lazily copied// . And symbols that refer to values in regions are alive if the region is //readable//.

For simplicity, we follow the current approach to live regions and mark the base region as //lazily copied//, and consider any subregions as //readable//. This makes some symbols falsy live (`d.z` in our example) and keeps the corresponding constraints alive.

The rename `Regions` to `LiveRegions` inside  `RegionStore` is NFC change, that was done to make it clear, what is difference between regions stored in this two sets.

Regression Test: https://reviews.llvm.org/D134941
Co-authored-by: Balazs Benics <benicsbalazs@gmail.com>

Reviewed By: martong, xazax.hun

Differential Revision: https://reviews.llvm.org/D134947
2022-10-19 16:06:32 +02:00
Balazs Benics afcd862b2e [analyzer] LazyCompoundVals should be always bound as default bindings
`LazyCompoundVals` should only appear as `default` bindings in the
store. This fixes the second case in this patch-stack.

Depends on: D132142

Reviewed By: xazax.hun

Differential Revision: https://reviews.llvm.org/D132143
2022-09-13 08:58:46 +02:00
Balazs Benics f8643a9b31 [analyzer] Prefer wrapping SymbolicRegions by ElementRegions
It turns out that in certain cases `SymbolRegions` are wrapped by
`ElementRegions`; in others, it's not. This discrepancy can cause the
analyzer not to recognize if the two regions are actually referring to
the same entity, which then can lead to unreachable paths discovered.

Consider this example:

```lang=C++
struct Node { int* ptr; };
void with_structs(Node* n1) {
  Node c = *n1; // copy
  Node* n2 = &c;
  clang_analyzer_dump(*n1); // lazy...
  clang_analyzer_dump(*n2); // lazy...
  clang_analyzer_dump(n1->ptr); // rval(n1->ptr): reg_$2<int * SymRegion{reg_$0<struct Node * n1>}.ptr>
  clang_analyzer_dump(n2->ptr); // rval(n2->ptr): reg_$1<int * Element{SymRegion{reg_$0<struct Node * n1>},0 S64b,struct Node}.ptr>
  clang_analyzer_eval(n1->ptr != n2->ptr); // UNKNOWN, bad!
  (void)(*n1);
  (void)(*n2);
}
```

The copy of `n1` will insert a new binding to the store; but for doing
that it actually must create a `TypedValueRegion` which it could pass to
the `LazyCompoundVal`. Since the memregion in question is a
`SymbolicRegion` - which is untyped, it needs to first wrap it into an
`ElementRegion` basically implementing this untyped -> typed conversion
for the sake of passing it to the `LazyCompoundVal`.
So, this is why we have `Element{SymRegion{.}, 0,struct Node}` for `n1`.

The problem appears if the analyzer evaluates a read from the expression
`n1->ptr`. The same logic won't apply for `SymbolRegionValues`, since
they accept raw `SubRegions`, hence the `SymbolicRegion` won't be
wrapped into an `ElementRegion` in that case.

Later when we arrive at the equality comparison, we cannot prove that
they are equal.

For more details check the corresponding thread on discourse:
https://discourse.llvm.org/t/are-symbolicregions-really-untyped/64406

---

In this patch, I'm eagerly wrapping each `SymbolicRegion` by an
`ElementRegion`; basically canonicalizing to this form.
It seems reasonable to do so since any object can be thought of as a single
array of that object; so this should not make much of a difference.

The tests also underpin this assumption, as only a few were broken by
this change; and actually fixed a FIXME along the way.

About the second example, which does the same copy operation - but on
the heap - it will be fixed by the next patch.

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D132142
2022-09-13 08:58:46 +02:00
isuckatcs e3e9082b01 [analyzer] Fix for incorrect handling of 0 length non-POD array construction
Prior to this patch when the analyzer encountered a non-POD 0 length array,
it still invoked the constructor for 1 element, which lead to false positives.
This patch makes sure that we no longer construct any elements when we see a
0 length array.

Differential Revision: https://reviews.llvm.org/D131501
2022-08-25 12:42:02 +02:00
Fangrui Song 3f18f7c007 [clang] LLVM_FALLTHROUGH => [[fallthrough]]. NFC
With C++17 there is no Clang pedantic warning or MSVC C5051.

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D131346
2022-08-08 09:12:46 -07:00
Balazs Benics a80418eec0 [analyzer] Improve loads from reinterpret-cast fields
Consider this example:

```lang=C++
struct header {
  unsigned a : 1;
  unsigned b : 1;
};
struct parse_t {
  unsigned bits0 : 1;
  unsigned bits2 : 2; // <-- header
  unsigned bits4 : 4;
};
int parse(parse_t *p) {
  unsigned copy = p->bits2;
  clang_analyzer_dump(copy);
  // expected-warning@-1 {{reg_$1<unsigned int SymRegion{reg_$0<struct Bug_55934::parse_t * p>}.bits2>}}

  header *bits = (header *)&copy;
  clang_analyzer_dump(bits->b); // <--- Was UndefinedVal previously.
  // expected-warning@-1 {{derived_$2{reg_$1<unsigned int SymRegion{reg_$0<struct Bug_55934::parse_t * p>}.bits2>,Element{copy,0 S64b,struct Bug_55934::header}.b}}}
  return bits->b; // no-warning: it's not UndefinedVal
}
```

`bits->b` should have the same content as the second bit of `p->bits2`
(assuming that the bitfields are in spelling order).

---

The `Store` has the correct bindings. The problem is with the load of `bits->b`.
It will eventually reach `RegionStoreManager::getBindingForField()` with
`Element{copy,0 S64b,struct header}.b`, which is a `FieldRegion`.
It did not find any direct bindings, so the `getBindingForFieldOrElementCommon()`
gets called. That won't find any bindings, but it sees that the variable
is on the //stack//, thus it must be an uninitialized local variable;
thus it returns `UndefinedVal`.

Instead of doing this, it should have created a //derived symbol//
representing the slice of the region corresponding to the member.
So, if the value of `copy` is `reg1`, then the value of `bits->b` should
be `derived{reg1, elem{copy,0, header}.b}`.

Actually, the `getBindingForElement()` already does exactly this for
reinterpret-casts, so I decided to hoist that and reuse the logic.

Fixes #55934

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D128535
2022-07-26 12:31:21 +02:00
Kazu Hirata ca4af13e48 [clang] Don't use Optional::getValue (NFC) 2022-06-20 22:59:26 -07:00
Kazu Hirata 0916d96d12 Don't use Optional::hasValue (NFC) 2022-06-20 20:17:57 -07:00
Kazu Hirata 452db157c9 [clang] Don't use Optional::hasValue (NFC) 2022-06-20 10:51:34 -07:00
isuckatcs 92bf652d40 [Static Analyzer] Small array binding policy
If a lazyCompoundVal to a struct is bound to the store, there is a policy which decides
whether a copy gets created instead.

This patch introduces a similar policy for arrays, which is required to model structured
binding to arrays without false negatives.

Differential Revision: https://reviews.llvm.org/D128064
2022-06-17 18:56:13 +02:00
Balazs Benics 96ccb690a0 [analyzer][NFC] Prefer using isa<> instead getAs<> in conditions
Depends on D125709

Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D127742
2022-06-15 16:58:13 +02:00
Balazs Benics b73c2280f5 [analyzer][NFC] Remove unused RegionStoreFeatures
Reviewed By: martong

Differential Revision: https://reviews.llvm.org/D126216
2022-06-10 13:02:26 +02:00
einvbri df5801806d [analyzer] Get direct binding for specific punned case
Region store was not able to see through this case to the actual
initialized value of STRUCT ff. This change addresses this case by
getting the direct binding. This was found and debugged in a downstream
compiler, with debug guidance from @steakhal. A positive and negative
test case is added.

The specific case where this issue was exposed.

  typedef struct {
    int a:1;
    int b[2];
  } STRUCT;

  int main() {
    STRUCT ff = {0};
    STRUCT* pff = &ff;
    int a = ((int)pff + 1);
    return a;
  }

Reviewed By: steakhal, martong

Differential Revision: https://reviews.llvm.org/D124349
2022-05-05 04:53:45 -05:00
Marco Antognini 68ee5ec07d [Analyzer] Fix assumptions about const field with member-initializer
Essentially, having a default member initializer for a constant member
does not necessarily imply the member will have the given default value.

Remove part of a2e053638b ([analyzer] Treat more const variables and
fields as known contants., 2018-05-04).

Fix #47878

Reviewed By: r.stahl, steakhal

Differential Revision: https://reviews.llvm.org/D124621
2022-05-03 11:27:45 +02:00
Vince Bridgers 985888411d [analyzer] Refactor makeNull to makeNullWithWidth (NFC)
Usages of makeNull need to be deprecated in favor of makeNullWithWidth
for architectures where the pointer size should not be assumed. This can
occur when pointer sizes can be of different sizes, depending on address
space for example. See https://reviews.llvm.org/D118050 as an example.

This was uncovered initially in a downstream compiler project, and
tested through those systems tests.

steakhal performed systems testing across a large set of open source
projects.

Co-authored-by: steakhal
Resolves: https://github.com/llvm/llvm-project/issues/53664

Reviewed By: NoQ, steakhal

Differential Revision: https://reviews.llvm.org/D119601
2022-03-22 07:35:13 -05:00
Sylvestre Ledru f2c2e924e7 Fix a typo (occured => occurred)
Reported:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1005195
2022-02-08 21:35:26 +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
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
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 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
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
Denys Petrov 7736b08c28 [analyzer] Replace StoreManager::CastRetrievedVal with SValBuilder::evalCast
Summary: Move logic from CastRetrievedVal to evalCast and replace CastRetrievedVal with evalCast. Also move guts from SimpleSValBuilder::dispatchCast inside evalCast.
evalCast intends to substitute dispatchCast, evalCastFromNonLoc and evalCastFromLoc in the future. OriginalTy provides additional information for casting, which is useful for some cases and useless for others.  If `OriginalTy.isNull()` is true, then cast performs based on CastTy only. Now evalCast operates in two ways. It retains all previous behavior and take over dispatchCast behavior. dispatchCast, evalCastFromNonLoc and evalCastFromLoc is considered as buggy since it doesn't take into account OriginalTy of the SVal and should be improved.

From this patch use evalCast instead of dispatchCast, evalCastFromNonLoc and evalCastFromLoc functions. dispatchCast redirects to evalCast.

This patch shall not change any behavior.

Differential Revision: https://reviews.llvm.org/D96090
2021-04-13 18:10:06 +03:00
Charusso 9b3df78b4c [analyzer] DynamicSize: Rename 'size' to 'extent' 2021-04-05 19:20:43 +02:00
Valeriy Savchenko bd06c417e6 [analyzer] Allow bindings of the CompoundLiteralRegion
Summary:
CompoundLiteralRegions have been properly modeled before, but
'getBindingForElement` was not changed to accommodate this change
properly.

rdar://problem/46144644

Differential Revision: https://reviews.llvm.org/D78990
2020-05-28 14:11:57 +03:00
Adam Balogh d70ec366c9 [Analyzer][NFC] Remove the SubEngine interface
The `SubEngine` interface is an interface with only one implementation
`EpxrEngine`. Adding other implementations are difficult and very
unlikely in the near future. Currently, if anything from `ExprEngine` is
to be exposed to other classes it is moved to `SubEngine` which
restricts the alternative implementations. The virtual methods are have
a slight perofrmance impact. Furthermore, instead of the `LLVM`-style
inheritance a native inheritance is used here, which renders `LLVM`
functions like e.g. `cast<T>()` unusable here. This patch removes this
interface and allows usage of `ExprEngine` directly.

Differential Revision: https://reviews.llvm.org/D80548
2020-05-26 19:56:55 +02:00
Charusso af3d0d1628 [analyzer] DynamicSize: Remove 'getSizeInElements()' from store
Summary:
This patch uses the new `DynamicSize.cpp` to serve dynamic information.
Previously it was static and probably imprecise data.

Reviewed By: NoQ

Differential Revision: https://reviews.llvm.org/D69599
2020-01-30 16:51:48 +01:00
Charusso 601687bf73 [analyzer] DynamicSize: Remove 'getExtent()' from regions
Summary:
This patch introduces a placeholder for representing the dynamic size of
regions. It also moves the `getExtent()` method of `SubRegions` to the
`MemRegionManager` as `getStaticSize()`.

Reviewed By: NoQ

Differential Revision: https://reviews.llvm.org/D69540
2020-01-30 16:05:18 +01:00
Artem Dergachev 040c39d50f [analyzer] Fix false positive on introspection of a block's internal layout.
When implementation of the block runtime is available, we should not
warn that block layout fields are uninitialized simply because they're
on the stack.
2019-12-06 13:24:20 -08:00
Artem Dergachev 630f7daf80 [analyzer] Fix analyzer warnings on analyzer.
Write tests for the actual crash that was found. Write comments and refactor
code around 17 style bugs and suppress 3 false positives.

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

llvm-svn: 370246
2019-08-28 18:44:38 +00:00
Artem Dergachev 8b2a39e937 [analyzer] Trust global initializers when analyzing main().
If the global variable has an initializer, we'll ignore it because we're usually
not analyzing the program from the beginning, which means that the global
variable may have changed before we start our analysis.

However when we're analyzing main() as the top-level function, we can rely
on global initializers to still be valid. At least in C; in C++ we have global
constructors that can still break this logic.

This patch allows the Static Analyzer to load constant initializers from
global variables if the top-level function of the current analysis is main().

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

llvm-svn: 370244
2019-08-28 18:44:32 +00:00
Jonas Devlieghere 2b3d49b610 [Clang] Migrate llvm::make_unique to std::make_unique
Now that we've moved to C++14, we no longer need the llvm::make_unique
implementation from STLExtras.h. This patch is a mechanical replacement
of (hopefully) all the llvm::make_unique instances across the monorepo.

Differential revision: https://reviews.llvm.org/D66259

llvm-svn: 368942
2019-08-14 23:04:18 +00:00
Fangrui Song 1a1af4392a [analyzer] Fix -Wunused-function in NDEBUG builds with #ifdef LLVM_DUMP_METHOD
llvm-svn: 366663
2019-07-22 04:14:09 +00:00
Rui Ueyama 49a3ad21d6 Fix parameter name comments using clang-tidy. NFC.
This patch applies clang-tidy's bugprone-argument-comment tool
to LLVM, clang and lld source trees. Here is how I created this
patch:

$ git clone https://github.com/llvm/llvm-project.git
$ cd llvm-project
$ mkdir build
$ cd build
$ cmake -GNinja -DCMAKE_BUILD_TYPE=Debug \
    -DLLVM_ENABLE_PROJECTS='clang;lld;clang-tools-extra' \
    -DCMAKE_EXPORT_COMPILE_COMMANDS=On -DLLVM_ENABLE_LLD=On \
    -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ ../llvm
$ ninja
$ parallel clang-tidy -checks='-*,bugprone-argument-comment' \
    -config='{CheckOptions: [{key: StrictMode, value: 1}]}' -fix \
    ::: ../llvm/lib/**/*.{cpp,h} ../clang/lib/**/*.{cpp,h} ../lld/**/*.{cpp,h}

llvm-svn: 366177
2019-07-16 04:46:31 +00:00
Csaba Dabis 0cdd13c05a [analyzer] print() JSONify: Create pointers
Summary: -

Reviewers: NoQ

Reviewed By: NoQ

Subscribers: xazax.hun, baloghadamsoftware, szepet, a.sidorin,
             mikhail.ramalho, Szelethus, donat.nagy, dkrupp, cfe-commits

Tags: #clang

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

llvm-svn: 364271
2019-06-25 03:17:55 +00:00
Artem Dergachev b50d167358 [analyzer] exploded-graph-rewriter: Fix escaping StringRegions.
Quotes around StringRegions are now escaped and unescaped correctly,
producing valid JSON.

Additionally, add a forgotten escape for Store values.

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

llvm-svn: 363897
2019-06-19 23:33:55 +00:00
Artem Dergachev 064c8c689a [analyzer] Fix JSON dumps for store clusters.
Include a unique pointer so that it was possible to figure out if it's
the same cluster in different program states. This allows comparing
dumps of different states against each other.

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

llvm-svn: 363896
2019-06-19 23:33:51 +00:00
Csaba Dabis 124cba0b81 [analyzer] print() JSONify: Store implementation
Summary: -

Reviewers: NoQ, xazax.hun, ravikandhadai, baloghadamsoftware, Szelethus

Reviewed By: NoQ

Subscribers: szepet, rnkovacs, a.sidorin, mikhail.ramalho, donat.nagy,
             dkrupp

Tags: #clang

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

llvm-svn: 361972
2019-05-29 15:25:19 +00:00
Artem Dergachev b591845f4b [analyzer] Fix crash when returning C++ objects from ObjC messages-to-nil.
the assertion is in fact incorrect: there is a cornercase in Objective-C++
in which a C++ object is not constructed with a constructor, but merely
zero-initialized. Namely, this happens when an Objective-C message is sent
to a nil and it is supposed to return a C++ object.

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

llvm-svn: 359262
2019-04-26 02:05:12 +00:00
Rafael Stahl 850361f6c1 [analyzer][CrossTU] Extend CTU to VarDecls with initializer
Summary:
The existing CTU mechanism imports `FunctionDecl`s where the definition is available in another TU. This patch extends that to VarDecls, to bind more constants.

- Add VarDecl importing functionality to CrossTranslationUnitContext
- Import Decls while traversing them in AnalysisConsumer
- Add VarDecls to CTU external mappings generator
- Name changes from "external function map" to "external definition map"

Reviewers: NoQ, dcoughlin, xazax.hun, george.karpenkov, martong

Reviewed By: xazax.hun

Subscribers: Charusso, baloghadamsoftware, mikhail.ramalho, Szelethus, donat.nagy, dkrupp, george.karpenkov, mgorny, whisperity, szepet, rnkovacs, a.sidorin, cfe-commits

Tags: #clang

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

llvm-svn: 358968
2019-04-23 11:04:41 +00:00
Artem Dergachev 9b02a9b401 [analyzer] Make default bindings to variables actually work.
Default RegionStore bindings represent values that can be obtained by loading
from anywhere within the region, not just the specific offset within the region
that they are said to be bound to. For example, default-binding a character \0
to an int (eg., via memset()) means that the whole int is 0, not just
that its lower byte is 0.

Even though memset and bzero were modeled this way, it didn't work correctly
when applied to simple variables. Eg., in

  int x;
  memset(x, 0, sizeof(x));

we did produce a default binding, but were unable to read it later, and 'x'
was perceived as an uninitialized variable even after memset.

At the same time, if we replace 'x' with a variable of a structure or array
type, accessing fields or elements of such variable was working correctly,
which was enough for most cases. So this was only a problem for variables of
simple integer/enumeration/floating-point/pointer types.

Fix loading default bindings from RegionStore for regions of simple variables.

Add a unit test to document the API contract as well.

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

llvm-svn: 358722
2019-04-18 23:35:56 +00:00
Artem Dergachev 06451368d2 [analyzer] Support C++17 aggregates with bases without constructors.
RegionStore now knows how to bind a nonloc::CompoundVal that represents the
value of an aggregate initializer when it has its initial segment of sub-values
correspond to base classes.

Additionally, fixes the crash from pr40022.

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

llvm-svn: 356222
2019-03-15 00:22:59 +00:00
Artem Dergachev b7e33f6404 Revert "[analyzer] Remove the "postponed" hack, deal with derived symbols..."
This reverts commit r341722.

The "postponed" mechanism turns out to be necessary in order to handle
situations when a symbolic region is only kept alive by implicit bindings
in the Store. Otherwise the region is never scanned by the Store's worklist
and the binding gets dropped despite being live, as demonstrated
by the newly added tests.

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

llvm-svn: 353350
2019-02-06 23:56:43 +00:00
Serge Guelton be88539b85 Replace llvm::isPodLike<...> by llvm::is_trivially_copyable<...>
As noted in https://bugs.llvm.org/show_bug.cgi?id=36651, the specialization for
isPodLike<std::pair<...>> did not match the expectation of
std::is_trivially_copyable which makes the memcpy optimization invalid.

This patch renames the llvm::isPodLike trait into llvm::is_trivially_copyable.
Unfortunately std::is_trivially_copyable is not portable across compiler / STL
versions. So a portable version is provided too.

Note that the following specialization were invalid:

    std::pair<T0, T1>
    llvm::Optional<T>

Tests have been added to assert that former specialization are respected by the
standard usage of llvm::is_trivially_copyable, and that when a decent version
of std::is_trivially_copyable is available, llvm::is_trivially_copyable is
compared to std::is_trivially_copyable.

As of this patch, llvm::Optional is no longer considered trivially copyable,
even if T is. This is to be fixed in a later patch, as it has impact on a
long-running bug (see r347004)

Note that GCC warns about this UB, but this got silented by https://reviews.llvm.org/D50296.

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

llvm-svn: 351701
2019-01-20 21:19:56 +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
Gabor Horvath 21aa8db606 [analyzer] Assume that we always have a SubEngine available
The removed codepath was dead.

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

llvm-svn: 349266
2018-12-15 13:20:33 +00:00