172 Commits

Author SHA1 Message Date
Martin Braenne
8c0acbf837 [clang][dataflow] Avoid -Wunused-variable. 2023-07-28 07:57:50 +00:00
Martin Braenne
e95134b9cb [clang][dataflow] Reverse course on getValue() deprecation.
In the [value categories RFC](https://discourse.llvm.org/t/70086), I proposed that the end state of the migration should be that `getValue()` should only be legal to call on prvalues.

As a stepping stone, to allow migrating off existing calls to `getValue()`, I proposed introducing `getValueStrict()`, which would already have the new semantics.

However, I've now reconsidered this. Any expression, whether prvalue or glvalue, has a value, so really there isn't any reason to forbid calling `getValue()` on glvalues. I'm therefore removing the deprecation from `getValue()` and transitioning existing `getValueStrict()` calls back to `getValue()`.

The other "strict" accessors are a different case. `setValueStrict()` should only be called on prvalues because glvalues need to have a storage location associated with them; it doesn't make sense to only set a value for them. And, of course, `getStorageLocationStrict()` and `setStorageLocationStrict()` should obviously only be called on glvalues because prvalues don't have storage locations.

Reviewed By: ymandel, xazax.hun

Differential Revision: https://reviews.llvm.org/D155921
2023-07-27 13:14:49 +00:00
Martin Braenne
1b334a2ae7 [clang][dataflow] Eliminate ReferenceValue.
There are no remaining uses of this class in the framework.

This patch is part of the ongoing migration to strict handling of value categories (see https://discourse.llvm.org/t/70086 for details).

Reviewed By: ymandel, xazax.hun, gribozavr2

Differential Revision: https://reviews.llvm.org/D155922
2023-07-27 13:14:47 +00:00
Jie Fu
e71bae94b0 [clang][dataflow] Fix build failure due to -Wunused-variable in DataflowEnvironment.cpp (NFC)
/data/llvm-project/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp:125:11: error: unused variable 'StructVal2' [-Werror,-Wunused-variable]
    auto *StructVal2 = cast<StructValue>(&Val2);
          ^
1 error generated.
2023-07-24 21:35:52 +08:00
Martin Braenne
44f98d0101 [clang][dataflow] Eliminate duplication between AggregateStorageLocation and StructValue.
After this change, `StructValue` is just a wrapper for an `AggregateStorageLocation`. For the wider context, see https://discourse.llvm.org/t/70086.

## How to review

- Start by looking at the comments added / changed in Value.h, StorageLocation.h,
  and DataflowEnvironment.h. This will give you a good overview of the semantic
  changes.

- Look at the corresponding .cpp files that implement the semantic changes.

- Transfer.cpp, TypeErasedDataflowAnalysis.cpp, and RecordOps.cpp show how the
  core of the framework is affected by the semantic changes.

- UncheckedOptionalAccessModel.cpp shows how this complex model is affected by
  the changes.

- Many of the changes in the rest of the patch are mechanical in nature.

Reviewed By: ymandel, xazax.hun

Differential Revision: https://reviews.llvm.org/D155446
2023-07-24 13:20:01 +00:00
Martin Braenne
0f6cf55567 [clang][dataflow] Bugfix for refreshStructValue().
In the case where the expression was not yet associated with a storage location, we created a new storage location but failed to associate it with the expression.

The newly added test fails without the fix.

Reviewed By: xazax.hun

Differential Revision: https://reviews.llvm.org/D155465
2023-07-17 18:56:25 +00:00
Martin Braenne
d17f455a63 [clang][dataflow] Add refreshStructValue().
Besides being a useful abstraction, this function will help insulate existing clients of the framework from upcoming changes to the API of `StructValue` and `AggregateStorageLocation`.

Depends On D155202

Reviewed By: ymandel, xazax.hun

Differential Revision: https://reviews.llvm.org/D155204
2023-07-17 07:26:13 +00:00
Martin Braenne
6d768548ec [clang][dataflow] Add DataflowEnvironment::createObject().
This consolidates the code used in various places to initialize objects (usually for variables) into one central location.

It will also help reduce the number of changes needed when we make the upcoming API changes to `AggregateStorageLocation` and `StructValue`.

Depends On D155074

Reviewed By: ymandel, xazax.hun

Differential Revision: https://reviews.llvm.org/D155075
2023-07-17 07:26:10 +00:00
Sam McCall
6272226b9f [dataflow] Remove deprecated BoolValue flow condition accessors
Use the Formula versions instead, now.

Differential Revision: https://reviews.llvm.org/D155152
2023-07-13 09:39:23 +02:00
Sam McCall
7d935d0836 [dataflow] improve determinism of generated SAT system
Fixes two places where we relied on map iteration order when processing
values, which leaked nondeterminism into the generated SAT formulas.
Adds a couple of tests that directly assert that the SAT system is
equivalent on each run.

It's desirable that the formulas are deterministic based on the input:

 - our SAT solver is naive and perfermance is sensitive to even simple
   semantics-preserving transformations like A|B to B|A.
   (e.g. it's likely to choose a different variable to split on).
   Timeout failures are bad, but *flaky* ones are terrible to debug.
 - similarly when debugging, it's important to have a consistent
   understanding of what e.g. "V23" means across runs.

---

Both changes in this patch were isolated from a nullability analysis of
real-world code which was extremely slow, spending ages in the SAT
solver at "random" points that varied on each run.
I've included a reduced version of the code as a regression test.

One of the changes shows up directly as flow-condition nondeterminism
with a no-op analysis, the other relied on bits of the nullability
analysis but I found a synthetic example to show the problem.

Differential Revision: https://reviews.llvm.org/D154948
2023-07-12 08:09:10 +02:00
Martin Braenne
b47bdcbc72 [clang][dataflow] Include fields initialized in an InitListExpr in getModeledFields().
Previously, we were including these fields only in the specific instance that was initialized by the `InitListExpr`, but not in other instances of the same type. This is inconsistent and error-prone.

Depends On D154952

Reviewed By: xazax.hun, gribozavr2

Differential Revision: https://reviews.llvm.org/D154961
2023-07-12 04:52:29 +00:00
Martin Braenne
e53da3eab4 [clang][dataflow][NFC] Expand a comment.
Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D154834
2023-07-11 06:32:08 +00:00
Martin Braenne
e8a1560d1d [clang][dataflow] Various changes to handling of modeled fields.
- Rename `getReferencedFields()` to `getModeledFields()`. Move the logic that
  returns all object fields when doing a context-sensitive analysis to here from
  `DataflowAnalysisContext::createStorageLocation()`. I think all callers of
  the previous `getReferencedFields()` should use this logic; the fact that they
  were not doing so looks like a bug.

- Make `getModeledFields()` public. I have an upcoming patch that will need to
  use this function from Transfer.cpp, and there doesn't seem to be any reason
  why this function should not be public.

- Use a `SmallSetVector` to get deterministic iteration order. I have a pending
  patch where I'm getting flaky tests because
  `Environment::createValueUnlessSelfReferential()` is non-deterministically
  populating different fields depending on the iteration order. This change
  fixes those flaky tests.

Reviewed By: gribozavr2

Differential Revision: https://reviews.llvm.org/D154586
2023-07-10 06:45:53 +00:00
Sam McCall
fc9821a877 Reland "[dataflow] Add dedicated representation of boolean formulas"
This reverts commit 7a72ce98224be76d9328e65eee472381f7c8e7fe.

Test problems were due to unspecified order of function arg evaluation.

Reland "[dataflow] Replace most BoolValue subclasses with references to Formula (and AtomicBoolValue => Atom and BoolValue => Formula where appropriate)"

This properly frees the Value hierarchy from managing boolean formulas.

We still distinguish AtomicBoolValue; this type is used in client code.
However we expect to convert such uses to BoolValue (where the
distinction is not needed) or Atom (where atomic identity is intended),
and then fold AtomicBoolValue into FormulaBoolValue.

We also distinguish TopBoolValue; this has distinct rules for
widen/join/equivalence, and top-ness is not represented in Formula.
It'd be nice to find a cleaner representation (e.g. the absence of a
formula), but no immediate plans.

For now, BoolValues with the same Formula are deduplicated. This doesn't
seem desirable, as Values are mutable by their creators (properties).
We can probably drop this for FormulaBoolValue immediately (not in this
patch, to isolate changes). For AtomicBoolValue we first need to update
clients to stop using value pointers for atom identity.

The data structures around flow conditions are updated:
- flow condition tokens are Atom, rather than AtomicBoolValue*
- conditions are Formula, rather than BoolValue
Most APIs were changed directly, some with many clients had a
new version added and the existing one deprecated.

The factories for BoolValues in Environment keep their existing
signatures for now (e.g. makeOr(BoolValue, BoolValue) => BoolValue)
and are not deprecated. These have very many clients and finding the
most ergonomic API & migration path still needs some thought.

Differential Revision: https://reviews.llvm.org/D153469
2023-07-07 11:58:33 +02:00
Sam McCall
2d8cd19512 Revert "Reland "[dataflow] Add dedicated representation of boolean formulas" and followups
These changes are OK, but they break downstream stuff that needs more time to adapt :-(

This reverts commit 71579569f4399d3cf6bc618dcd449b5388d749cc.
This reverts commit 5e4ad816bf100b0325ed45ab1cfea18deb3ab3d1.
This reverts commit 1c3ac8dfa16c42a631968aadd0396cfe7f7778e0.
2023-07-05 14:32:25 +02:00
Sam McCall
5e4ad816bf [dataflow] Replace most BoolValue subclasses with references to Formula (and AtomicBoolValue => Atom and BoolValue => Formula where appropriate)
This properly frees the Value hierarchy from managing boolean formulas.

We still distinguish AtomicBoolValue; this type is used in client code.
However we expect to convert such uses to BoolValue (where the
distinction is not needed) or Atom (where atomic identity is intended),
and then fold AtomicBoolValue into FormulaBoolValue.

We also distinguish TopBoolValue; this has distinct rules for
widen/join/equivalence, and top-ness is not represented in Formula.
It'd be nice to find a cleaner representation (e.g. the absence of a
formula), but no immediate plans.

For now, BoolValues with the same Formula are deduplicated. This doesn't
seem desirable, as Values are mutable by their creators (properties).
We can probably drop this for FormulaBoolValue immediately (not in this
patch, to isolate changes). For AtomicBoolValue we first need to update
clients to stop using value pointers for atom identity.

The data structures around flow conditions are updated:
- flow condition tokens are Atom, rather than AtomicBoolValue*
- conditions are Formula, rather than BoolValue
Most APIs were changed directly, some with many clients had a
new version added and the existing one deprecated.

The factories for BoolValues in Environment keep their existing
signatures for now (e.g. makeOr(BoolValue, BoolValue) => BoolValue)
and are not deprecated. These have very many clients and finding the
most ergonomic API & migration path still needs some thought.

Differential Revision: https://reviews.llvm.org/D153469
2023-07-05 13:54:32 +02:00
Martin Braenne
1e7329cd79 [clang][dataflow] Model variables / fields / funcs used in default initializers.
The newly added test fails without the other changes in this patch.

Reviewed By: sammccall, gribozavr2

Differential Revision: https://reviews.llvm.org/D154420
2023-07-04 12:06:10 +00:00
Martin Braenne
74d8455ba6 [clang][dataflow] Make getThisPointeeStorageLocation() return an AggregateStorageLocation.
This avoids the need for casts at callsites.

Depends On D153852

Reviewed By: sammccall, xazax.hun, gribozavr2

Differential Revision: https://reviews.llvm.org/D153854
2023-06-29 04:07:08 +00:00
Martin Braenne
d36324866e [clang][dataflow] Initialize fields of anonymous records correctly.
Previously, the newly added test would crash.

Depends On D153851

Reviewed By: gribozavr2

Differential Revision: https://reviews.llvm.org/D153852
2023-06-29 04:07:04 +00:00
Sam McCall
6f22de67c5 [dataflow] Use consistent, symmetrical, non-mutating erased signature for join()
Mutating join() isn't used and so appears to be an anti-optimization.
Having Lattice vs Environment inconsistent is awkward, particularly when trying
to minimize copies while joining.

This patch eliminates the difference, but doesn't actually change the signature
of join on concrete lattice types (as that's a breaking change).

Differential Revision: https://reviews.llvm.org/D153908
2023-06-28 11:30:16 +02:00
Sam McCall
1e010c5c4f Reland "[dataflow] avoid more accidental copies of Environment"
This reverts commit fb13d027eae405a7be96fd7da0d72422e48a0719.
2023-06-27 20:31:40 +02:00
Sam McCall
fb13d027ea Revert "[dataflow] avoid more accidental copies of Environment"
This reverts commit ae54f01dd8c53d18c276420b23f0d0ab7afefff1.

Accidentally committed without review :-(
2023-06-26 18:41:24 +02:00
Sam McCall
ae54f01dd8 [dataflow] avoid more accidental copies of Environment
This is clunky but greatly improves debugging of flow conditions - each
copy adds more indirections in the form of flow condition tokens.

(LatticeEffect presumably once did something here, but it's now both
unused and untested.)

For the exit flow condition of:
```
void target(base::Optional<int*> opt) {
  if (opt.value_or(nullptr) != nullptr) {
    opt.value();
  } else {
    opt.value(); // unsafe
  }
}
```

Before:
```
(B0:1 = V15)
(B1:1 = V8)
(B2:1 = V10)
(B3:1 = (V4 & (!V7 => V6)))
(V10 = (B3:1 & !V7))
(V12 = B1:1)
(V13 = B2:1)
(V15 = (V12 | V13))
(V3 = V2)
(V4 = V3)
(V8 = (B3:1 & !!V7))
B0:1
V2
```

After D153491:
```
(B0:1 = (V9 | V10))
(B1:1 = (B3:1 & !!V6))
(B2:1 = (B3:1 & !V6))
(B3:1 = (V3 & (!V6 => V5)))
(V10 = B2:1)
(V3 = V2)
(V9 = B1:1)
B0:1
V2
```

After this patch, we can finally see the relations between the flow
conditions directly:

```
(B0:1 = (B2:1 | B1:1))
(B1:1 = (B3:1 & !!V6))
(B2:1 = (B3:1 & !V6))
(B3:1 = (V3 & (!V6 => V5)))
(V3 = V2)
B0:1
V2
```

(I believe V2 is the FC for the InitEnv, and V3 is introduced when
computing the input state for B3 - not sure how to eliminate it)

Differential Revision: https://reviews.llvm.org/D153493
2023-06-26 15:58:23 +02:00
Martin Braenne
f2123af1e7 [clang][dataflow] Perform deep copies in copy and move operations.
This serves two purposes:

- Because, today, we only copy the `StructValue`, modifying the destination of
  the copy also modifies the source. This is demonstrated by the new checks
  added to `CopyConstructor` and `MoveConstructor`, which fail without the
  deep copy.

- It lays the groundwork for eliminating the redundancy between
  `AggregateStorageLocation` and `StructValue`, which will happen as part of the
  ongoing migration to strict handling of value categories (seeo
  https://discourse.llvm.org/t/70086 for details). This will involve turning
  `StructValue` into essentially just a wrapper for `AggregateStorageLocation`;
  under this scheme, the current "shallow" copy (copying a `StructValue` from
  one `AggregateStorageLocation` to another) will no longer be possible.

Because we now perform deep copies, tests need to perform a deep equality
comparison instead of just comparing for equal identity of the `StructValue`s.
The new function `recordsEqual()` provides such a deep equality comparison.

Reviewed By: xazax.hun

Differential Revision: https://reviews.llvm.org/D153006
2023-06-26 13:52:56 +00:00
Sam McCall
c2bb68078e [dataflow] Disallow implicit copy of Environment, use fork() instead
Environments are heavyweight, and copies are observably different from the
original: they introduce new SAT variables, which degrade performance &
debugging. Copies should only be done deliberately, where justified.

Empirically there are several places in the framework where we perform dubious
copies, sometimes entirely accidentally. (see e.g. D153491). Making these
explicit makes this mistake harder.

This patch forces copies to go through fork(), the copy-constructor is private.
This requires changes to existing callsites: some are correct and call fork(),
some are incorrect and are fixed, others are difficult and I left a FIXME.

Differential Revision: https://reviews.llvm.org/D153674
2023-06-26 15:26:02 +02:00
Kazu Hirata
583371be4d [FlowSensitive] Use {DenseMapBase,StringMap}::lookup (NFC) 2023-06-12 08:11:01 -07:00
Martin Braenne
64413584da [clang][dataflow] Add support for return values of reference type.
This patch changes the way `Environment::ReturnLoc` is set: Whereas previously it was set by the caller, it is now set by the callee (obviously, as we otherwise would not be able to return references).

The patch also introduces `Environment::ReturnVal`, which is used for non-reference-type return values. This allows these to be handled with the correct value category semantics; see also https://discourse.llvm.org/t/70086, which describes the ongoing migration to strict value category semantics.

Depends On D150776

Reviewed By: ymandel, xazax.hun

Differential Revision: https://reviews.llvm.org/D151194
2023-05-25 08:38:33 +00:00
Martin Braenne
080ee850c6 [clang][dataflow] Add Strict versions of Value and StorageLocation accessors.
This is part of the gradual migration to strict handling of value categories, as described in the RFC at https://discourse.llvm.org/t/70086.

This patch migrates some representative calls of the newly deprecated accessors to the new `Strict` functions. Followup patches will migrate the remaining callers.  (There are a large number of callers, with some subtlety involved in some of them, so it makes sense to split this up into multiple patches rather than migrating all callers in one go.)

The `Strict` accessors as implemented here have some differences in semantics compared to the semantics originally proposed in the RFC; specifically:

*  `setStorageLocationStrict()`: The RFC proposes to create an intermediate
   `ReferenceValue` that then refers to the `StorageLocation` for the glvalue.
   It turns out though that, even today, most places in the code are not doing
   this but are instead associating glvalues directly with their
   `StorageLocation`. It therefore didn't seem to make sense to introduce new
   `ReferenceValue`s where there were none previously, so I have chosen to
   instead make `setStorageLocationStrict()` simply call through to
   `setStorageLocation(const Expr &, StorageLocation &)` and merely add the
   assertion that the expression must be a glvalue.

*  `getStorageLocationStrict()`: The RFC proposes that this should assert that
   the storage location for the glvalue expression is associated with an
   intermediate `ReferenceValue`, but, as explained, this is often not true.
   The current state is inconsistent: Sometimes the intermediate
   `ReferenceValue` is there, sometimes it isn't. For this reason,
   `getStorageLocationStrict()` skips past a `ReferenceValue` if it is there but
   otherwise directly returns the storage location associated with the
   expression. This behavior is equivalent to the existing behavior of
   `SkipPast::Reference`.

*  `setValueStrict()`: The RFC proposes that this should always create the same
   `StorageLocation` for a given `Value`, but, in fact, the transfer functions
   that exist today don't guarantee this; almost all transfer functions
   unconditionally create a new `StorageLocation` when associating an expression
   with a `Value`.

   There appears to be one special case:
   `TerminatorVisitor::extendFlowCondition()` checks whether the expression is
   already associated with a `StorageLocation` and, if so, reuses the existing
   `StorageLocation` instead of creating a new one.

   For this reason, `setValueStrict()` implements this logic (preserve an
   existing `StorageLocation`) but makes no attempt to always associate the same
   `StorageLocation` with a given `Value`, as nothing in the framework appers to
   require this.

   As `TerminatorVisitor::extendFlowCondition()` is an interesting special case,
   the `setValue()` call there is among the ones that this patch migrates to
   `setValueStrict()`.

Reviewed By: sammccall, ymandel, xazax.hun

Differential Revision: https://reviews.llvm.org/D150653
2023-05-17 09:30:47 +00:00
Martin Braenne
48bc71505e [clang][dataflow] Eliminate SkipPast::ReferenceThenPointer.
As a replacement, we provide the accessors `getImplicitObjectLocation()` and
`getBaseObjectLocation()`, which are higher-level constructs that cover the use
cases in which `SkipPast::ReferenceThenPointer` was typically used.

Unfortunately, it isn't possible to use these accessors in
UncheckedOptionalAccessModel.cpp; I've added a FIXME to the code explaining the
details. I initially attempted to resolve the issue as part of this patch, but
it turned out to be non-trivial to fix. Instead, I have therefore added a
lower-level replacement for `SkipPast::ReferenceThenPointer` that is used only
within this file.

The wider context of this change is that `SkipPast` will be going away entirely.
See also the RFC at https://discourse.llvm.org/t/70086.

Reviewed By: ymandel, gribozavr2

Differential Revision: https://reviews.llvm.org/D149838
2023-05-15 04:33:29 +00:00
Martin Braenne
0c852dc88e [clang][dataflow][NFC] Remove SkipPast param from getValue(const ValueDecl &).
This parameter was already a no-op, so removing it doesn't change behavior.

Reviewed By: ymandel

Differential Revision: https://reviews.llvm.org/D150137
2023-05-09 07:42:20 +00:00
Martin Braenne
9940fac753 [clang][dataflow][NFC] Remove SkipPast parameter from `getStorageLocation(const ValueDecl &).
This parameter was already a no-op, so removing it doesn't change behavior.

Depends On D149144

Reviewed By: ymandel, xazax.hun, gribozavr2

Differential Revision: https://reviews.llvm.org/D149151
2023-05-08 07:10:44 +00:00
Martin Braenne
bfbe137888 [clang][dataflow] Eliminate intermediate ReferenceValues from Environment::DeclToLoc.
For the wider context of this change, see the RFC at
https://discourse.llvm.org/t/70086.

After this change, global and local variables of reference type are associated
directly with the `StorageLocation` of the referenced object instead of the
`StorageLocation` of a `ReferenceValue`.

Some tests that explicitly check for an existence of `ReferenceValue` for a
variable of reference type have been modified accordingly.

As discussed in the RFC, I have added an assertion to `Environment::join()` to
check that if both environments contain an entry for the same declaration in
`DeclToLoc`, they both map to the same `StorageLocation`. As discussed in
https://discourse.llvm.org/t/70086/5, this also necessitates removing
declarations from `DeclToLoc` when they go out of scope.

In the RFC, I proposed a gradual migration for this change, but it appears
that all of the callers of `Environment::setStorageLocation(const ValueDecl &,
SkipPast` are in the dataflow framework itself, and that there are only a few of
them.

As this is the function whose semantics are changing in a way that callers
potentially need to adapt to, I've decided to change the semantics of the
function directly.

The semantics of `getStorageLocation(const ValueDecl &, SkipPast SP` now no
longer depend on the behavior of the `SP` parameter. (There don't appear to be
any callers that use `SkipPast::ReferenceThenPointer`, so I've added an
assertion that forbids this usage.)

This patch adds a default argument for the `SP` parameter and removes the
explicit `SP` argument at the callsites that are touched by this change. A
followup patch will remove the argument from the remaining callsites,
allowing the `SkipPast` parameter to be removed entirely. (I don't want to do
that in this patch so that semantics-changing changes can be reviewed separately
from semantics-neutral changes.)

Reviewed By: ymandel, xazax.hun, gribozavr2

Differential Revision: https://reviews.llvm.org/D149144
2023-05-04 20:57:30 +00:00
Samira Bazuzi
2cdb6b84c1 [clang][dataflow] Expose DataflowAnalysisContext from DataflowEnvironment.
This will eliminate the need for more pass-through APIs. Also replace pass-through usages with this exposure.

Reviewed By: ymandel, gribozavr2, xazax.hun

Differential Revision: https://reviews.llvm.org/D149464
2023-05-02 11:32:19 +00:00
Sam McCall
fa2a8c2e1c [dataflow] Don't crash in Environment::dump when decls have weird names 2023-04-21 21:08:26 +02:00
Sam McCall
bf47c1ed85 [dataflow] Extract arena for Value/StorageLocation out of DataflowAnalysisContext
DataflowAnalysisContext has a few too many responsibilities, this narrows them.

It also allows the Arena to be shared with analysis steps, which need to create
Values, without exposing the whole DACtx API (flow conditions etc).
This means Environment no longer needs to proxy all these methods.
(For now it still does, because there are many callsites to update, and maybe
if we separate bool formulas from values we can avoid churning them twice)

In future, if we untangle the concepts of Values from boolean formulas/atoms,
Arena would also be responsible for creating formulas and managing atom IDs.

Differential Revision: https://reviews.llvm.org/D148554
2023-04-19 14:32:13 +02:00
Martin Braenne
d9e717338f [clang][dataflow] Associate FunctionToPointerDecay nodes with a value.
To ensure that we have a pointee for the `PointerValue`, we also create
storage locations for `FunctionDecl`s referenced in the function under analysis.

Reviewed By: gribozavr2

Differential Revision: https://reviews.llvm.org/D148006
2023-04-18 07:15:29 +00:00
Martin Braenne
991c7e1172 [clang][dataflow][NFC] Remove unused parameter from insertIfGlobal().
Reviewed By: gribozavr2

Differential Revision: https://reviews.llvm.org/D148004
2023-04-11 11:31:56 +00:00
Martin Braenne
effdfa7d5f [clang][dataflow] Use isRecordType() where appropriate.
This is less verbose than checking for class, struct, and union individually,
and I believe it's also more efficient (not that that should be the overriding
concern).

Reviewed By: sammccall, xazax.hun

Differential Revision: https://reviews.llvm.org/D147603
2023-04-06 07:26:24 +00:00
Martin Braenne
3c8ead2662 [clang][dataflow] Eliminate code duplication in Environment::createValueUnlessSelfReferential().
Reviewed By: sammccall

Differential Revision: https://reviews.llvm.org/D147601
2023-04-06 07:01:44 +00:00
Martin Braenne
745a957f9d [clang][dataflow] Add create<T>() methods to Environment and DataflowAnalysisContext.
These methods provide a less verbose way of allocating `StorageLocation`s and
`Value`s than the existing `takeOwnership(make_unique(...))` pattern.

In addition, because allocation of `StorageLocation`s and `Value`s now happens
within the `DataflowAnalysisContext`, the `create<T>()` open up the possibility
of using `BumpPtrAllocator` to allocate these objects if it turns out this
helps performance.

Reviewed By: ymandel, xazax.hun, gribozavr2

Differential Revision: https://reviews.llvm.org/D147302
2023-04-04 07:13:44 +00:00
Martin Braenne
ce0ab9d11c [clang][dataflow][NFC] Share code between Environment ctor and pushCallInternal().
The deduplicated code is moved into initVars().

As an added bonus, pushCallInternal() now also gets the "Add all fields
mentioned in default member initializers" behavior, which apparently had been
added to the Environment ctor but not pushCallInternal().

Reviewed By: xazax.hun, ymandel

Differential Revision: https://reviews.llvm.org/D147326
2023-04-03 08:25:10 +00:00
Sam McCall
ee2cd606ab [dataflow] Log flow condition to the correct stream.
Differential Revision: https://reviews.llvm.org/D146527
2023-03-22 10:57:21 +01:00
Kazu Hirata
7eaa7b0553 [clang] Use *{Map,Set}::contains (NFC) 2023-03-15 18:06:34 -07:00
Yitzhak Mandelbaum
73c98831f6 [clang][dataflow] Fix missed fields in field set construction.
When building the set of referenced fields for the `DataflowAnalysisContext`,
include fields referenced only in default member initializers. These
initializers are visited in the CFGs of constructors and so the fields must be
included when analysing constructor bodies.

Differential Revision: https://reviews.llvm.org/D144987
2023-02-28 18:56:54 +00:00
Yitzhak Mandelbaum
daa316bcaf [clang][dataflow] Fix bug in joining bool values.
Currently, the code assumes that all boolean-typed values are an instance of
`BoolValue` (or its subclasses). Yet, lvalues violate this assumption. This
patch drops the assumption and strengthens the check to confirm the shape of
both values being joined.

The patch also notes as FIXMES a number of problems discovered fixing this bug.

Differential Revision: https://reviews.llvm.org/D141709
2023-01-19 15:59:06 +00:00
Yitzhak Mandelbaum
c441f65f91 [clang][dataflow] Add (initial) debug printing for Value and Environment.
Also adds uses of the new printing in analysis inner loop.

Differential Revision: https://reviews.llvm.org/D141716
2023-01-19 14:33:32 +00:00
Yitzhak Mandelbaum
3ce03c42db [clang][dataflow] Fix 2 bugs in MemberExpr interpretation.
There were two (small) bugs causing crashes in the analysis.  This patch fixes both of them.

1. An enum value was accessed as a class member. Now, the engine gracefully
ignores such member expressions.

2. Field access in `MemberExpr` of struct/class-typed global variables. Analysis
didn't interpret fields of global vars, because the vars were initialized before
the fields were added to the "allowlist". Now, the allowlist is set _before_
init of globals.

Differential Revision: https://reviews.llvm.org/D141384
2023-01-10 15:48:00 +00:00
Yitzhak Mandelbaum
089a54469f [clang][dataflow][NFC] Refine names and comments for field filtering.
Tweaks elements of the new API for filtering the set of modeled fields.

Differential Revision: https://reviews.llvm.org/D141319
2023-01-10 14:28:45 +00:00
Yitzhak Mandelbaum
01ccf7b3ce Revert "Revert "[clang][dataflow] Only model struct fields that are used in the function being analyzed.""
This reverts commit 2b1a517a92bfdfa3b692a660e19a2bb22513a567. It's a fix forward
with two memory errors fixed, one of which was the cause of the build breakage
in the buildbots.

Original message:

Previously, the model for structs modeled all fields in a struct when
`createValue` was called for that type. This patch adds a prepass on the
function under analysis to discover the fields referenced in the scope and then
limits modeling to only those fields. This reduces wasted memory usage
(modeling unused fields) which can be important for programs that use large
structs.

Note: This patch obviates the need for https://reviews.llvm.org/D123032.
2023-01-09 19:32:10 +00:00
serge-sans-paille
a3c248db87
Move from llvm::makeArrayRef to ArrayRef deduction guides - clang/ part
This is a follow-up to https://reviews.llvm.org/D140896, split into
several parts as it touches a lot of files.

Differential Revision: https://reviews.llvm.org/D141139
2023-01-09 12:15:24 +01:00