200 Commits

Author SHA1 Message Date
Yitzhak Mandelbaum
6b991ba486 [clang][dataflow] Change transfer API to take a reference.
The provided `CFGElement` is never null, so a reference is a more precise type.

Differential Revision: https://reviews.llvm.org/D143920
2023-02-15 15:37:21 +00:00
Yitzhak Mandelbaum
d4fb829b71 [clang][dataflow] Relax validity assumptions in UncheckedOptionalAccessModel.
Currently, the interpretation of `swap` calls in the optional model assumes the
optional arguments are modeled (and therefore have valid storage locations and
values). This assumption is incorrect, for example, in the case of unmodeled
optional fields (which can be missing either value or location). This patch
relaxes these assumptions, to return rather than assert when either argument is
not modeled.

Differential Revision: https://reviews.llvm.org/D142710
2023-02-01 15:57:09 +00:00
Yitzhak Mandelbaum
02562804d0 [clang][dataflow] Fix handling of DeclRefExprs to BindingDecls.
The invariants around `ReferenceValues` are subtle (arguably, too much so). That
includes that we need to take care not to double wrap them -- in cases where we
wrap a loc in an `ReferenceValue` we need to be sure that the pointee isn't
already a `ReferenceValue`.  `BindingDecl` introduces another situation in which
this can arise. Previously, the code did not properly handle `BindingDecl`,
resulting in double-wrapped values, which broke other invariants (at least, that
struct values have an `AggregateStorageLocation`).

This patch adjusts the interpretation of `DeclRefExpr` to take `BindingDecl`'s
peculiarities into account. It also fixes the two tests which should have caught
this issue but were themselves (subtly) buggy.

Differential Revision: https://reviews.llvm.org/D140897
2023-02-01 13:23:23 +00:00
Kazu Hirata
5c9013e266 Use std::optional instead of llvm::Optional (NFC) 2023-01-28 00:45:19 -08:00
Yitzhak Mandelbaum
b84ac96a35 [clang][dataflow] Fix bug in handling of reference-typed fields.
This patch fixes a subtle bug in how we create lvalues to reference-typed
fields. In the rare case that the field is umodeled because of the depth limit
on field modeling, the lvalue created can be malformed. This patch prevents that
and adds some related assertions to other code dealing with lvalues for
references.

Differential Revision: https://reviews.llvm.org/D142468
2023-01-24 16:10:50 +00:00
Dmitri Gribenko
c8b31da1ef [clang][dataflow] Allow analyzing multiple functions in unit tests
In unit tests for concrete dataflow analyses we typically use the
testonly `checkDataflow()` helper to analyse a free function called
"target". This pattern allows our tests to be uniform and focused on
specific statement- or expression-level C++ features.

As we expand our feature coverage, we want to analyze functions whose
names we don't fully control, like constructors, destructors, operators
etc. In such tests it is often convenient to analyze all functions
defined in the input code, to avoid having to carefully craft an AST
matcher that finds the exact function we're interested in. That can be
easily done by providing `checkDataflow()` with a catch-all matcher like
`functionDecl()`.

It is also often convenient to define multiple special member functions
in a single unit test, for example, multiple constructors, and share the
rest of the class definition code between constructors. As a result, it
makes sense to analyze multiple functions in one unit test.

This change allows `checkDataflow()` to correctly handle AST matchers
that match more than one function. Previously, it would only ever
analyze the first matched function, and silently ignore the rest. Now it
runs dataflow analysis in a loop, and calls `VerifyResults` for each
function that was found in the input and analyzed.

Reviewed By: ymandel, sgatev

Differential Revision: https://reviews.llvm.org/D140859
2023-01-21 01:28:03 +01: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
Kazu Hirata
2d861436a9 [clang] Remove remaining uses of llvm::Optional (NFC)
This patch removes several "using" declarations and #include
"llvm/ADT/Optional.h".

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

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

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

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

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

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

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-01-14 11:07:21 -08:00
Jordan Rupprecht
3432f4bf86 [test] Split out Annotations from TestingSupport
The Annotations helper class does not have a gtest or gmock dependency, but because it's bundled with the rest of TestingSupport, it gets one. By splitting it out, a target can use it without being forced to use LLVM's copy of gtest.

Reviewed By: GMNGeoffrey, sammccall, gribozavr2

Differential Revision: https://reviews.llvm.org/D141175
2023-01-12 13:40:47 -08:00
Yitzhak Mandelbaum
d34fbf2d9b [clang][dataflow] In optional model, implement widen and make compare sound.
This patch includes two related changes:

1. Rewrite `compare` operation to be sound. Current version checks for equality
of `isNonEmptyOptional` on both values, judging the values `Same` when the
results are equal. While that works when both are true, it is problematic when
they are both false, because there are four cases in which that's can occur:
both empty, one empty and one unknown (which is two cases), and both unknown. In
the latter three cases, it is unsound to judge them `Same`. This patch changes
`compare` to explicitly check for case of `both empty` and then judge any other
case `Different`.

2. With the change to `compare`, a number of common cases will no longer
terminate. So, we also implement widening to properly handle those cases and
recover termination.

Drive-by: improve performance of `merge` operation.

Of the new tests, the code before the patch fails
* ReassignValueInLoopToSetUnsafe, and
* ReassignValueInLoopToUnknownUnsafe.

Differential Revision: https://reviews.llvm.org/D140344
2023-01-12 20:36:37 +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
264976d98e [clang][dataflow] Unify TransferOptions and DataflowAnalysisContext::Options.
Merges `TransferOptions` into the newly-introduced
`DataflowAnalysisContext::Options` and removes explicit parameter for
`TransferOptions`, relying instead on the common options carried by the analysis
context. Given that there was no intent to allow different options between calls
to `transfer`, a common value for the options is preferable.

Differential Revision: https://reviews.llvm.org/D140703
2023-01-10 14:17:25 +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
Yitzhak Mandelbaum
2b1a517a92 Revert "[clang][dataflow] Only model struct fields that are used in the function being analyzed."
This reverts commit 5e8f597c2fedc740b71f07dfdb1ef3c2d348b193. It caused msan and ubsan breakages.
2023-01-06 01:07:28 +00:00
Yitzhak Mandelbaum
5e8f597c2f [clang][dataflow] Only model struct fields that are used in the function being analyzed.
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 programss that use large
structs.

Note: This patch obviates the need for https://reviews.llvm.org/D123032.

Differential Revision: https://reviews.llvm.org/D140694
2023-01-05 21:46:39 +00:00
Yitzhak Mandelbaum
0086a3555a [clang][dataflow] Fix bug in optional-checker's handling of nullopt constructor.
Currently, the checker only recognizes the nullopt constructor when it is called
without sugar, resulting in a crash in the (rare) case where it has been wrapped
in sugar. This relaxes the constraint by checking the constructor decl directly
(which always contains the same, desugared form) rather than the construct
expression (where the spelling depends on the context).

Differential Revision: https://reviews.llvm.org/D140921
2023-01-03 21:57:39 +00:00
Dani Ferreira Franco Moura
d862f66221 [clang][dataflow] Treat unions as structs.
This is a straightfoward way to handle unions in dataflow analysis. Without this change, nullability verification crashes on files that contain unions.

Reviewed By: gribozavr2, ymandel

Differential Revision: https://reviews.llvm.org/D140696
2023-01-03 18:36:24 +00:00
Dmitri Gribenko
5674385577 [clang][dataflow] Remove unused includes 2023-01-02 23:34:24 +01:00
Jun Zhang
eda2eaabf2
[clang][dataflow] Fix crash when having boolean-to-integral casts.
Since now we just ignore all (implicit) integral casts, treating the
resulting value as the same as the underlying value, it could cause
inconsistency between values after `Join` if in some paths the type
doesn't strictly match. This could cause intermittent crashes.

std::optional<bool> o;
int x;
if (o.has_value()) {
  x = o.value();
}

Fixes: https://github.com/llvm/llvm-project/issues/59728

Signed-off-by: Jun Zhang <jun@junz.org>

Differential Revision: https://reviews.llvm.org/D140753
2022-12-30 13:14:44 +08:00
Dmitri Gribenko
3a39b0ac1a [clang] Migrate away from a deprecated Clang CFG factory function
Reviewed By: merrymeerkat

Differential Revision: https://reviews.llvm.org/D140620
2022-12-23 14:36:52 +01:00
Yitzhak Mandelbaum
38404df9d8 [clang][dataflow] Fix bug in handling of return statements.
The handling of return statements, added in support of context-sensitive
analysis, has a bug relating to functions that return reference
types. Specifically, interpretation of such functions can result in a crash from
a bad cast. This patch fixes the bug and guards all of that code with the
context-sensitive option, since there's no reason to execute at all when
context-sensitive analysis is off.

Differential Revision: https://reviews.llvm.org/D140430
2022-12-22 14:42:17 +00:00
Yitzhak Mandelbaum
f3700bdb7f [clang][dataflow] Account for global variables in constructor initializers.
Previously, the analysis modeled global variables appearing in the _body_ of
any function (including constructors). But, that misses those appearing in
constructor _initializers_. This patch adds the initializers to the set of
expressions used to determine which globals to model.

Differential Revision: https://reviews.llvm.org/D140501
2022-12-22 14:20:50 +00:00
Yitzhak Mandelbaum
0e8d4a6df9 [clang][dataflow] Simplify handling of nullopt-optionals.
Previously, in the case of an optional constructed from `nullopt`, we relied on
the value constructed for the `nullopt`. This complicates the implementation and
exposes it to bugs (indeed, one such was found), yet doesn't improve the
engine. Instead, this patch constructs a fresh optional representation, rather
than relying on the underlying nullopt representation.

Differential Revision: https://reviews.llvm.org/D140506
2022-12-22 14:19:49 +00:00
Benjamin Kramer
854c10f8d1 [Clang] Prepare for llvm::Optional becoming std::optional.
The needed tweaks are mostly trivial, the one nasty bit is Clang's usage
of OptionalStorage. To keep this working old Optional stays around as
clang::CustomizableOptional, with the default Storage removed.
Optional<File/DirectoryEntryRef> is replaced with a typedef.

I tested this with GCC 7.5, the oldest supported GCC I had around.

Differential Revision: https://reviews.llvm.org/D140332
2022-12-20 00:41:40 +01:00
Yitzhak Mandelbaum
5d22d1f548 [clang][dataflow] Improve optional model's support for ignoring smart pointers.
The optional model has an option to ignore optionals accessed through smart
pointer types (other than optional itself). This patch improves this feature in
two ways:

1. We extend support to optionals accessed directly through the smart pointer,
like `ptr->value()`. Previously, support was limited to cases that went through
an intermediate field.

2. We clean up the implementation by removing the option from the analysis,
leaving it only in the diagnostic phase (where it is relevant).

3. Adjusts a test which was misleading in what it was testing.

Differential Revision: https://reviews.llvm.org/D140020
2022-12-15 15:39:52 +00:00
Dani Ferreira Franco Moura
4ca1ae580b [clang][dataflow] Remove old diagnoser API
This is a clean up following the revision D139868 (https://reviews.llvm.org/D139868).

Reviewed By: gribozavr2, ymandel

Differential Revision: https://reviews.llvm.org/D140037
2022-12-14 20:45:48 +01:00
Dani Ferreira Franco Moura
82d50fef9b [clang][dataflow] Change the diagnoser API to receive a correctly typed lattice element
Previously, the diagnoser could only receive the Environment at a given program point. Now, it receives the complete dataflow state: the environment and lattice element.

This change does not contain any tests because we modify the checkDataflow function to rely on the newly introduced lattice element in PostVisitCFG, and existing tests that verify lattice elements depend on this overload of checkDataflow.

Reviewed By: gribozavr2, ymandel

Differential Revision: https://reviews.llvm.org/D139868
2022-12-13 14:49:07 +01:00
Kazu Hirata
f7dffc28b3 Don't include None.h (NFC)
I've converted all known uses of None to std::nullopt, so we no longer
need to include None.h.

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

https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-10 11:24:26 -08:00
Yitzhak Mandelbaum
ef4635452f [clang][dataflow] Add support for structured bindings of tuple-like types.
This patch adds interpretation of binding declarations resulting from a
structured binding (`DecompositionDecl`) to a tuple-like type. Currently, the
framework only supports binding to a struct.

Fixes issue #57252.

Differential Revision: https://reviews.llvm.org/D139544
2022-12-09 18:58:00 +00:00
Yitzhak Mandelbaum
390029be89 [clang][dataflow] Support (in)equality operators in optional model.
This patch adds interpretation of the overloaded equality and inequality
operators available for the optional types.

Fixes issue #57253.

Differential Revision: https://reviews.llvm.org/D139360
2022-12-07 16:24:49 +00:00
Fangrui Song
a996cc217c Remove unused #include "llvm/ADT/Optional.h" 2022-12-05 06:31:11 +00:00
Kazu Hirata
a41fbb1fc2 [clang/unittests] 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 12:14:19 -08:00
Yitzhak Mandelbaum
84dd12b290 [clang][dataflow] Add widening API and implement it for built-in boolean model.
* Adds API support for widening of lattice elements and environments,
* Updates the algorithm to apply widening where appropriate,
* Implements widening for boolean values. In the process, moves the unsoundness
  of comparison from the default implementation of
  `Environment::ValueModel::compare` to model-specific handling inside
  `DataflowEnvironment::equivalentTo`. This change is intended to clarify
  the source and location of unsoundess.

This patch is a replacement for, and was based substantially on, https://reviews.llvm.org/D131645.

Differential Revision: https://reviews.llvm.org/D137948
2022-11-22 16:09:28 +00:00
Yitzhak Mandelbaum
c0725865b1 [clang][dataflow] Generalize custom comparison to return tri-value result.
Currently, the API for a model's custom value comparison returns a
boolean. Therefore, models cannot distinguish between situations where the
values are recognized by the model and different and those where the values are
just not recognized.  This patch changes the return value to a tri-valued enum,
allowing models to express "don't know".

This patch is essentially a NFC -- no practical differences result from this
change in this patch. But, it prepares for future patches (particularly,
upcoming patches for widening) which will take advantage of the new flexibility.

Differential Revision: https://reviews.llvm.org/D137334
2022-11-03 23:31:20 +00:00
Gabor Marton
bb72d0dde2 [clang][dataflow] Implement transferBranch
This patch introduces `transferBranch`, which Applies the analysis
transfer function for a given edge from a CFG block of a conditional
statement.

RFC:
https://discourse.llvm.org/t/rfc-clang-dataflow-signanalysis-edgetransfer-branchtransfer/65220

Differential Revision: https://reviews.llvm.org/D133698
2022-10-26 15:24:55 +02:00
Gabor Marton
93ce23adb5 [clang][dataflow] Add initial sign analysis
This patch adds an initial implementation for sign analysis, with the
following lattice (T: top, N: negative, Z: zero, P: positive, B: bottom):
  T
/ | \
N Z P
\ | /
  B
The lattice is implemented with `BoolValue` properties attached to other
`Value`s.

Differential Revision: https://reviews.llvm.org/D136668
2022-10-26 15:13:22 +02:00
Yitzhak Mandelbaum
8cadac41e9 [clang][dataflow] Add equivalence relation Value type.
Defines an equivalence relation on the `Value` type to standardize several
places in the code where we replicate the ~same equivalence comparison.

Differential Revision: https://reviews.llvm.org/D135964
2022-10-19 12:23:09 +00:00
Susana Monteiro
57ba07c06f [clang] fix typo in unit test 2022-10-18 16:32:13 +01:00
Yitzhak Mandelbaum
13cd184ef7 [clang-dataflow][NFC] Mark test analysis classes as final.
Change from marking individual methods as `final` to marking the whole class.

Differential Revision: https://reviews.llvm.org/D135923
2022-10-14 17:51:57 +00:00
Yitzhak Mandelbaum
39b9d4f188 [clang][dataflow] Add support for a Top value in boolean formulas.
Currently, our boolean formulas (`BoolValue`) don't form a lattice, since they
have no Top element. This patch adds such an element, thereby "completing" the
built-in model of bools to be a proper semi-lattice. It still has infinite
height, which is its own problem, but that can be solved separately, through
widening and the like.

Patch 1 for Issue #56931.

Differential Revision: https://reviews.llvm.org/D135397
2022-10-14 17:41:53 +00:00
Yitzhak Mandelbaum
0b12efc7a4 [clang][dataflow] Add support for nested method calls.
Extend the context-sensitive analysis to handle a call to a method (of the same
class) from within a method. That, is a member-call expression through `this`.

Differential Revision: https://reviews.llvm.org/D134432
2022-09-22 19:16:31 +00:00
Wei Yi Tee
003566cb1f [clang][dataflow] Remove deprecated overloads of checkDataflow in TestingSupport.h.
Reviewed By: gribozavr2

Differential Revision: https://reviews.llvm.org/D134081
2022-09-21 10:36:44 +00:00
Wei Yi Tee
88210b81ee [clang][dataflow] Refactor clang/Analysis/FlowSensitive/MatchSwitchTest.cpp.
- Remove use of `runDataflowAnalysis` to keep test isolated.
- Add test for `ASTMatchSwitch<CXXCtorInitializer, ...>`.

Reviewed By: gribozavr2, sgatev

Differential Revision: https://reviews.llvm.org/D133935
2022-09-19 19:10:41 +00:00
Wei Yi Tee
41d52c5a7f [clang][dataflow] Modify transfer in DataflowModel to take CFGElement as input instead of Stmt.
To keep API of transfer functions consistent.

The single use of this transfer function in `ChromiumCheckModel` is also updated.

Reviewed By: gribozavr2, sgatev

Differential Revision: https://reviews.llvm.org/D133933
2022-09-19 18:40:29 +00:00
Wei Yi Tee
cf94c52e35 [clang][dataflow] Replace transfer(const Stmt *, ...) with transfer(const CFGElement *, ...) in clang/Analysis/FlowSensitive.
Reviewed By: gribozavr2, sgatev

Differential Revision: https://reviews.llvm.org/D133931
2022-09-19 18:06:57 +00:00
Wei Yi Tee
7538b36045 [clang][dataflow] Replace usage of deprecated functions with the optional check
- Update `transfer` and `diagnose` to take `const CFGElement *` as input in `Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel`.
- Update `clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp` accordingly.
- Rename `runDataflowAnalysisOnCFG` to `runDataflowAnalysis` and remove the deprecated `runDataflowAnalysis` (this was only used by the now updated optional check).

Reviewed By: gribozavr2, sgatev

Differential Revision: https://reviews.llvm.org/D133930
2022-09-19 17:33:25 +00:00
Wei Yi Tee
a4f8e3d240 Revert "[clang][dataflow] Replace transfer(const Stmt *, ...) with transfer(const CFGElement *, ...) in Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel."
This reverts commit 41f235d26887946f472d71a8417507c35d5f9074.

Details at https://lab.llvm.org/buildbot#builders/139/builds/28171.
Breakage due to API change.
2022-09-16 18:07:35 +00:00
Wei Yi Tee
41f235d268 [clang][dataflow] Replace transfer(const Stmt *, ...) with transfer(const CFGElement *, ...) in Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.
Reviewed By: gribozavr2, sgatev

Differential Revision: https://reviews.llvm.org/D133930
2022-09-16 17:54:12 +00:00