Commit Graph

174 Commits

Author SHA1 Message Date
Kazu Hirata cb2c8f694d [clang] Use value instead of getValue (NFC) 2022-07-13 23:39:33 -07:00
Wei Yi Tee b8d83e8004 [clang][dataflow] Generate readable form of input and output of satisfiability checking.
Differential Revision: https://reviews.llvm.org/D129548
2022-07-13 11:58:51 +00:00
Wei Yi Tee c9666d2339 [clang][dataflow] Generate readable form of boolean values.
Differential Revision: https://reviews.llvm.org/D129547
2022-07-13 10:35:17 +00:00
Wei Yi Tee 1e9cd04d7b [clang][dataflow] Refactor boolean creation as a test utility.
Differential Revision: https://reviews.llvm.org/D129546
2022-07-13 10:35:17 +00:00
Wei Yi Tee 632de855a0 [clang][dataflow] Refactor boolean creation as a test utility.
Differential Revision: https://reviews.llvm.org/D129546
2022-07-13 10:15:06 +00:00
Kazu Hirata 53daa177f8 [clang, clang-tools-extra] Use has_value instead of hasValue (NFC) 2022-07-12 22:47:41 -07:00
Wei Yi Tee 81e6400d8c [clang][dataflow] Return a solution from the solver when `Constraints` are `Satisfiable`.
Differential Revision: https://reviews.llvm.org/D129180
2022-07-07 20:21:19 +00:00
Dmitri Gribenko 63fac424e6 Revert "[clang][dataflow] Return a solution from the solver when `Constraints` are `Satisfiable`."
This reverts commit 19e21887eb. I
accidentally landed the non-final version of the patch that used
decomposition declarations (not yet usable in LLVM/Clang source).
2022-07-07 21:50:52 +02:00
Wei Yi Tee 19e21887eb [clang][dataflow] Return a solution from the solver when `Constraints` are `Satisfiable`.
A truth assignment to atomic boolean values which satisfy `Constraints` will be returned if found by the solver.
This gives us more information which can be helpful for debugging or constructing warning messages.

Reviewed By: hlopko, gribozavr2, sgatev

Differential Revision: https://reviews.llvm.org/D129180
2022-07-07 20:53:47 +02:00
Eric Li f10d271ae2 [clang][dataflow] Handle null pointers of type std::nullptr_t
Treat `std::nullptr_t` as a regular scalar type to avoid tripping
assertions when analyzing code that uses `std::nullptr_t`.

Differential Revision: https://reviews.llvm.org/D129097
2022-07-05 13:49:26 +00:00
Sam Estep 1d83a16bd3 [clang][dataflow] Replace TEST_F with TEST where possible
Many of our tests are currently written using `TEST_F` where the test fixture class doesn't have any `SetUp` or `TearDown` methods, and just one helper method. In those cases, this patch deletes the class and pulls its method out into a standalone function, using `TEST` instead of `TEST_F`.

There are still a few test files leftover in `clang/unittests/Analysis/FlowSensitive/` that use `TEST_F`:

- `DataflowAnalysisContextTest.cpp` because the class contains a `Context` field which is used
- `DataflowEnvironmentTest.cpp` because the class contains an `Environment` field which is used
- `SolverTest.cpp` because the class contains a `Vals` field which is used
- `TypeErasedDataflowAnalysisTest.cpp` because there are several different classes which all share the same method name

Reviewed By: ymandel, sgatev

Differential Revision: https://reviews.llvm.org/D128924
2022-06-30 16:03:33 +00:00
Stanislav Gatev 8207c2a660 [clang][dataflow] Handle `for` statements without conditions
Handle `for` statements without conditions.

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

Reviewed-by: xazax.hun, gribozavr2, li.zhe.hua
2022-06-30 07:00:35 +00:00
Sam Estep 6a97be27a1 [clang][dataflow] Delete SourceLocationsLattice
This patch deletes the now-unused `SourceLocationsLattice` class, along with its containing files and surrounding helper functions and tests.

Reviewed By: xazax.hun, ymandel, sgatev, gribozavr2

Differential Revision: https://reviews.llvm.org/D128448
2022-06-29 20:14:07 +00:00
Sam Estep cf1f978d31 [clang][dataflow] Use NoopLattice in optional model
Followup to D128352. This patch pulls the `NoopLattice` class out from the `NoopAnalysis.h` test file into its own `NoopLattice.h` source file, and uses it to replace usage of `SourceLocationsLattice` in `UncheckedOptionalAccessModel`.

Reviewed By: ymandel, sgatev, gribozavr2, xazax.hun

Differential Revision: https://reviews.llvm.org/D128356
2022-06-29 20:10:42 +00:00
Sam Estep 8361877b10 Revert "[clang][dataflow] Use NoopLattice in optional model"
This reverts commit 335c05f5d1.
2022-06-29 19:34:30 +00:00
Sam Estep 335c05f5d1 [clang][dataflow] Use NoopLattice in optional model
Followup to D128352. This patch pulls the `NoopLattice` class out from the `NoopAnalysis.h` test file into its own `NoopLattice.h` source file, and uses it to replace usage of `SourceLocationsLattice` in `UncheckedOptionalAccessModel`.

Reviewed By: ymandel, sgatev, gribozavr2, xazax.hun

Differential Revision: https://reviews.llvm.org/D128356
2022-06-29 19:20:58 +00:00
Sam Estep 58fe7f9683 [clang][dataflow] Add API to separate analysis from diagnosis
This patch adds an optional `PostVisitStmt` parameter to the `runTypeErasedDataflowAnalysis` function, which does one more pass over all statements in the CFG after a fixpoint is reached. It then defines a `diagnose` method for the optional model in a new `UncheckedOptionalAccessDiagnosis` class, but only integrates that into the tests and not the actual optional check for `clang-tidy`. That will be done in a followup patch.

The primary motivation is to separate the implementation of the unchecked optional access check into two parts, to allow for further refactoring of just the model part later, while leaving the checking part alone. Currently there is duplication between the `transferUnwrapCall` and `diagnoseUnwrapCall` functions, but that will be dealt with in the followup.

Because diagnostics are now all gathered into one collection rather than being populated at each program point like when computing a fixpoint, this patch removes the usage of `Pair` and `UnorderedElementsAre` from the optional model tests, and instead modifies all their expectations to simply check the stringified set of diagnostics against a single string, either `"safe"` or some concatenation of `"unsafe: input.cc:y:x"`. This is not ideal as it loses any connection to the `/*[[check]]*/` annotations in the source strings, but it does still retain the source locations from the diagnostic strings themselves.

Reviewed By: sgatev, gribozavr2, xazax.hun

Differential Revision: https://reviews.llvm.org/D127898
2022-06-29 19:18:39 +00:00
Wei Yi Tee fa34210fa6 [clang][dataflow] Do not allow substitution of true/false boolean literals in `buildAndSubstituteFlowCondition`
Reviewed By: gribozavr2, xazax.hun

Differential Revision: https://reviews.llvm.org/D128658
2022-06-27 21:04:52 +02:00
Wei Yi Tee b611376e7e [clang][dataflow] Singleton pointer values for null pointers.
When a `nullptr` is assigned to a pointer variable, it is wrapped in a `ImplicitCastExpr` with cast kind `CK_NullTo(Member)Pointer`. This patch assigns singleton pointer values representing null to these expressions.

For each pointee type, a singleton null `PointerValue` is created and stored in the `NullPointerVals` map of the `DataflowAnalysisContext` class. The pointee type is retrieved from the implicit cast expression, and used to initialise the `PointeeLoc` field of the `PointerValue`. The `PointeeLoc` created is not mapped to any `Value`, reflecting the absence of value indicated by null pointers.

Reviewed By: gribozavr2, sgatev, xazax.hun

Differential Revision: https://reviews.llvm.org/D128056
2022-06-27 14:17:34 +02:00
Wei Yi Tee bdfe556dd8 [clang][dataflow] Implement functionality for flow condition variable substitution.
This patch introduces `buildAndSubstituteFlowCondition` - given a flow condition token, this function returns the expression of constraints defining the flow condition, with values substituted where specified.

As an example:
Say we have tokens `FC1`, `FC2`, `FC3`:
```
FlowConditionConstraints: {
 FC1: C1,
 FC2: C2,
 FC3: (FC1 v FC2) ^ C3,
}
```
`buildAndSubstituteFlowCondition(FC3, /*Substitutions:*/{{C1 -> C1'}})`
returns a value corresponding to `(C1' v C2) ^ C3`.

Note:
This function returns the flow condition expressed directly as its constraints, which differs to how we currently represent the flow condition as a token bound to a set of constraints and dependencies. Making the representation consistent may be an option to consider in the future.

Depends On D128357

Reviewed By: gribozavr2, xazax.hun

Differential Revision: https://reviews.llvm.org/D128363
2022-06-27 11:37:46 +02:00
Kazu Hirata ca05cc2064 [clang] Don't use Optional::hasValue (NFC)
This patch replaces x.hasValue() with x where x is contextually
convertible to bool.
2022-06-26 18:51:54 -07:00
Kazu Hirata 3b7c3a654c Revert "Don't use Optional::hasValue (NFC)"
This reverts commit aa8feeefd3.
2022-06-25 11:56:50 -07:00
Kazu Hirata aa8feeefd3 Don't use Optional::hasValue (NFC) 2022-06-25 11:55:57 -07:00
Kazu Hirata b8df4093e4 [clang, clang-tools-extra] Don't use Optional::{hasValue,getValue} (NFC) 2022-06-25 11:55:33 -07:00
Wei Yi Tee 0f65a3e610 [clang][dataflow] Implement functionality to compare if two boolean values are equivalent.
`equivalentBoolValues` compares equivalence between two booleans. The current implementation does not consider constraints imposed by flow conditions on the booleans and its subvalues.

Depends On D128520

Reviewed By: gribozavr2, xazax.hun

Differential Revision: https://reviews.llvm.org/D128521
2022-06-25 00:10:35 +02:00
Wei Yi Tee 00e9d53453 [clang][dataflow] Move logic for creating implication and iff expressions into `DataflowAnalysisContext` from `DataflowEnvironment`.
To keep functionality of creating boolean expressions in a consistent location.

Depends On D128357

Reviewed By: gribozavr2, sgatev, xazax.hun

Differential Revision: https://reviews.llvm.org/D128519
2022-06-24 23:16:44 +02:00
Sam Estep 8c278a2781 [clang][dataflow] Allow MatchSwitch to return a value
Reland of D128467. This version replaces `return {};` with `return Result();`, since the former failed on GCC with `Result = void`.

Reviewed By: gribozavr2

Differential Revision: https://reviews.llvm.org/D128533
2022-06-24 14:38:00 +00:00
Sam Estep 7b326b946a Revert "[clang][dataflow] Allow MatchSwitch to return a value"
This reverts commit 4eecd194b0.
2022-06-24 13:52:11 +00:00
Sam Estep 4eecd194b0 [clang][dataflow] Allow MatchSwitch to return a value
This patch adds another `typename` parameter to `MatchSwitch` class: `Result` (defaults to `void`), corresponding to the return type of the function. This necessitates a couple minor changes to the `MatchSwitchBuilder` class, and is tested via a new `ReturnNonVoid` test in `clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp`.

Reviewed By: gribozavr2, sgatev, xazax.hun

Differential Revision: https://reviews.llvm.org/D128467
2022-06-24 13:32:47 +00:00
Stanislav Gatev e363c5963d [clang][dataflow] Extend flow condition in the body of a do/while loop
Extend flow condition in the body of a do/while loop.

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

Reviewed-by: gribozavr2, xazax.hun
2022-06-20 17:31:00 +00:00
Stanislav Gatev 83232099cb [clang][dataflow] Extend flow condition in the body of a for loop
Extend flow condition in the body of a for loop.

Differential Revision: https://reviews.llvm.org/D128060
2022-06-20 05:48:45 +00:00
Stanislav Gatev ba53906cef [clang][dataflow] Add support for comma binary operator
Add support for comma binary operator.

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

Reviewed-by: ymandel, xazax.hun
2022-06-17 17:48:21 +00:00
Stanislav Gatev 8fcdd62585 [clang][dataflow] Add support for correlated branches to optional model
Add support for correlated branches to the std::optional dataflow model.

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

Reviewed-by: ymandel, xazax.hun
2022-06-15 10:00:44 +00:00
Wei Yi Tee 97d69cdaf3 [clang][dataflow] Rename `getPointeeLoc` to `getReferentLoc` for ReferenceValue.
We distinguish between the referent location for `ReferenceValue` and pointee location for `PointerValue`. The former must be non-empty but the latter may be empty in the case of a `nullptr`

Reviewed By: gribozavr2, sgatev

Differential Revision: https://reviews.llvm.org/D127745
2022-06-15 00:53:30 +02:00
Sam Estep cd0d52610d [clang][dataflow] In `optional` model, match call return via hasType
Currently the unchecked-optional-access model fails on this example:

    #include <memory>
    #include <optional>

    void foo() {
      std::unique_ptr<std::optional<float>> x;
      *x = std::nullopt;
    }

You can verify the failure by saving the file as `foo.cpp` and running this command:

    clang-tidy -checks='-*,bugprone-unchecked-optional-access' foo.cpp -- -std=c++17

The failing `assert` is in the `transferAssignment` function of the `UncheckedOptionalAccessModel.cpp` file:

    assert(OptionalLoc != nullptr);

The symptom can be treated by replacing that `assert` with an early `return`:

    if (OptionalLoc == nullptr)
      return;

That would be better anyway since we cannot expect to always cover all possible LHS expressions, but it is out of scope for this patch and left as a followup.

Note that the failure did not occur on this very similar example:

    #include <optional>

    template <typename T>
    struct smart_ptr {
      T& operator*() &;
      T* operator->();
    };

    void foo() {
      smart_ptr<std::optional<float>> x;
      *x = std::nullopt;
    }

The difference is caused by the `isCallReturningOptional` matcher, which was previously checking the `functionDecl` of the `callee`. This patch changes it to instead use `hasType` directly on the call expression, fixing the failure for the `std::unique_ptr` example above.

Reviewed By: sgatev

Differential Revision: https://reviews.llvm.org/D127434
2022-06-10 14:52:05 +00:00
Yitzhak Mandelbaum dd38caf3b5 [clang][dataflow] Track `optional` contents in `optional` model.
This patch adds partial support for tracking (i.e. modeling) the contents of an
optional value. Specifically, it supports tracking the value after it is
accessed. We leave tracking constructed/assigned contents to a future patch.

Differential Revision: https://reviews.llvm.org/D124932
2022-06-09 14:17:39 +00:00
Wei Yi Tee a1b2b7d979 [clang][dataflow] Remove IndirectionValue class, moving PointeeLoc field into PointerValue and ReferenceValue
This patch precedes a future patch to make PointeeLoc for PointerValue possibly empty (for nullptr), by using a pointer instead of a reference type.
ReferenceValue should maintain a non-empty PointeeLoc reference.

Reviewed By: gribozavr2

Differential Revision: https://reviews.llvm.org/D127312
2022-06-09 01:29:16 +02:00
Wei Yi Tee 49ed5bf519 [clang][dataflow] Enable use of synthetic properties on all Value instances.
This patch moves the implementation of synthetic properties from the StructValue class into the Value base class so that it can be used across all Value instances.

Reviewed By: gribozavr2, ymandel, sgatev, xazax.hun

Differential Revision: https://reviews.llvm.org/D127196
2022-06-08 20:20:26 +02:00
Sam Estep dcb4950d5b [clang][dataflow][NFC] Fix filename typos in tests
Reviewed By: ymandel

Differential Revision: https://reviews.llvm.org/D127008
2022-06-07 19:20:20 +00:00
Yitzhak Mandelbaum 6adfc64e70 [clang][dataflow] Modify `optional` model to handle type aliases.
Previously, type aliases were not handled (and resulted in an assertion
firing). This patch generalizes the model to consider aliases everywhere (a
previous patch already considered aliases for optional-returning functions).

Differential Revision: https://reviews.llvm.org/D126972
2022-06-03 18:57:43 +00:00
Stanislav Gatev 65e710c3fc [clang][dataflow] Model calls returning optionals
Model calls returning optionals

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

Reviewed-by: ymandel, xazax.hun
2022-06-03 13:38:22 +00:00
Stanislav Gatev 0e286b77cf [clang][dataflow] Add transfer functions for structured bindings
This is part of the implementation of the dataflow analysis framework.
See "[RFC] A dataflow analysis framework for Clang AST" on cfe-dev.

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

Reviewed-by: ymandel, xazax.hun
2022-06-02 08:02:26 +00:00
Yitzhak Mandelbaum 3682e22ef4 [clang][dataflow] Improve handling of constructor initializers.
Currently, we assert that `CXXCtorInitializer`s are field initializers. Replace
the assertion with an early return. Otherwise, we crash every time we process a
constructor with a non-field (e.g. base class) initializer.

Differential Revision: https://reviews.llvm.org/D126419
2022-05-27 13:54:11 +00:00
Yitzhak Mandelbaum 67136d0e8f [clang][dataflow] Remove private-field filtering from `StorageLocation` creation.
The API for `AggregateStorageLocation` does not allow for missing fields (it asserts). Therefore, it is incorrect to filter out any fields at location-creation time which may be accessed by the code. Currently, we limit filtering to private, base-calss fields on the assumption that those can never be accessed. However, `friend` declarations can invalidate that assumption, thereby breaking our invariants.

This patch removes said field filtering to avoid violating the invariant of "no missing fields" for `AggregateStorageLocation`.

Differential Revision: https://reviews.llvm.org/D126420
2022-05-27 13:39:53 +00:00
Eric Li 5520c58390 [clang][dataflow] Fix incorrect CXXThisExpr pointee for lambdas
When constructing the `Environment`, the `this` pointee is established
for a `CXXMethodDecl` by looking at its parent. However, inside of
lambdas, a `CXXThisExpr` refers to the captured `this` coming from the
enclosing member function.

When establishing the `this` pointee for a function, we check whether
the function is a lambda, and check for an enclosing member function
to establish the `this` pointee storage location.

Differential Revision: https://reviews.llvm.org/D126413
2022-05-25 20:58:02 +00:00
Eric Li 33b598a808 [clang][dataflow] Relax assert on existence of `this` pointee storage
Support for unions is incomplete (per 99f7d55e) and the `this` pointee
storage location is not set for unions. The assert in
`VisitCXXThisExpr` is then guaranteed to trigger when analyzing member
functions of a union.

This commit changes the assert to an early-return. Any expression may
be undefined, and so having a value for the `CXXThisExpr` is not a
postcondition of the transfer function.

Differential Revision: https://reviews.llvm.org/D126405
2022-05-25 20:58:02 +00:00
Yitzhak Mandelbaum 2f93bbb9cd [clang][dataflow] Relax `Environment` comparison operation.
Ignore `MemberLocToStruct` in environment comparison. As an ancillary data
structure, including it is redundant. We also can generate environments which
differ in their `MemberLocToStruct` but are otherwise equivalent.

Differential Revision: https://reviews.llvm.org/D126314
2022-05-24 20:58:18 +00:00
Eric Li 5bbef2e3ff [clang][dataflow] Fix double visitation of nested logical operators
Sub-expressions that are logical operators are not spelled out
separately in basic blocks, so we need to manually visit them when we
encounter them. We do this in both the `TerminatorVisitor`
(conditionally) and the `TransferVisitor` (unconditionally), which can
cause cause an expression to be visited twice when the binary
operators are nested 2+ times.

This changes the visit in `TransferVisitor` to check if it has been
evaluated before trying to visit the sub-expression.

Differential Revision: https://reviews.llvm.org/D125821
2022-05-17 20:28:48 +00:00
Eric Li 58abe36ae7 [clang][dataflow] Add flowConditionIsTautology function
Provide a way for users to check if a flow condition is
unconditionally true.

Differential Revision: https://reviews.llvm.org/D124943
2022-05-05 03:57:43 +00:00
Eric Li 62b2a47a9f [clang][dataflow] Only skip ExprWithCleanups when visiting terminators
`IgnoreParenImpCasts` will remove implicit casts to bool
(e.g. `PointerToBoolean`), such that the resulting expression may not
be of the `bool` type. The `cast_or_null<BoolValue>` in
`extendFlowCondition` will then trigger an assert, as the pointer
expression will not have a `BoolValue`.

Instead, we only skip `ExprWithCleanups` and `ParenExpr` nodes, as the
CFG does not emit them.

Differential Revision: https://reviews.llvm.org/D124807
2022-05-04 15:31:49 +00:00