[clang] 58fe7f9 - [clang][dataflow] Add API to separate analysis from diagnosis

2022-06-29 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-06-29T19:18:39Z
New Revision: 58fe7f9683a020a880426a4d8d61b067b83a9380

URL: 
https://github.com/llvm/llvm-project/commit/58fe7f9683a020a880426a4d8d61b067b83a9380
DIFF: 
https://github.com/llvm/llvm-project/commit/58fe7f9683a020a880426a4d8d61b067b83a9380.diff

LOG: [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

Added: 


Modified: 

clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
clang/unittests/Analysis/FlowSensitive/TestingSupport.h
clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp

Removed: 




diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
 
b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
index 2102ed56907bb..701db6470ac2f 100644
--- 
a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
+++ 
b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
@@ -20,6 +20,8 @@
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/MatchSwitch.h"
 #include "clang/Analysis/FlowSensitive/SourceLocationsLattice.h"
+#include "clang/Basic/SourceLocation.h"
+#include 
 
 namespace clang {
 namespace dataflow {
@@ -71,6 +73,19 @@ class UncheckedOptionalAccessModel
   MatchSwitch> TransferMatchSwitch;
 };
 
+class UncheckedOptionalAccessDiagnoser {
+public:
+  UncheckedOptionalAccessDiagnoser(
+  UncheckedOptionalAccessModelOptions Options = {});
+
+  std::vector diagnose(ASTContext &Context, const Stmt *Stmt,
+   const Environment &Env);
+
+private:
+  MatchSwitch>
+  DiagnoseMatchSwitch;
+};
+
 } // namespace dataflow
 } // namespace clang
 

diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h 
b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
index 2d3a9e456370d..5e168194064f4 100644
--- a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
@@ -115,13 +115,17 @@ TypeErasedDataflowAnalysisState transferBlock(
 HandleTransferredStmt = nullptr);
 
 /// Performs dataflow analysis and returns a mapping from basic block IDs to
-/// dataflow analysis states that model the respective basic blocks. Indices
-/// of the returned vector correspond to basic block IDs. Returns an error if
-/// the dataflow analysis cannot be performed successfully.
+/// dataflow analysis states that model the respective basic blocks. Indices of
+/// the returned vector correspond to basic block IDs. Returns an error if the
+/// dataflow analysis cannot be performed successfully. Otherwise, calls
+/// `PostVisitStmt` on each statement with the final analysis results at that
+/// program point.
 llvm::Expected>>
-runTypeErasedDataflowAnalysis(const ControlFlowContext &CFCtx,
-  TypeErasedDataflowAnalysis &Analysis,
-  const Environment &InitEnv);
+runTypeErasedDataflowAnalysis(
+const Contro

[clang-tools-extra] cafb8b4 - [clang][dataflow] Use diagnosis API in optional checker

2022-06-29 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-06-29T19:20:09Z
New Revision: cafb8b4ff2c38f81e65f97193eb1d8d16c581522

URL: 
https://github.com/llvm/llvm-project/commit/cafb8b4ff2c38f81e65f97193eb1d8d16c581522
DIFF: 
https://github.com/llvm/llvm-project/commit/cafb8b4ff2c38f81e65f97193eb1d8d16c581522.diff

LOG: [clang][dataflow] Use diagnosis API in optional checker

Followup to D127898. This patch updates `bugprone-unchecked-optional-access` to 
use the new `diagnoseCFG` function instead of just looking at the exit block.

A followup to this will update the optional model itself to use a noop lattice 
rather than redundantly computing the diagnostics in both phases of the 
analysis.

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

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
index 07fb19ff81ac1..9766450e81654 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
@@ -23,6 +23,7 @@
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/Any.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Error.h"
 #include 
 #include 
@@ -32,12 +33,13 @@ namespace tidy {
 namespace bugprone {
 using ast_matchers::MatchFinder;
 using dataflow::SourceLocationsLattice;
+using dataflow::UncheckedOptionalAccessDiagnoser;
 using dataflow::UncheckedOptionalAccessModel;
 using llvm::Optional;
 
 static constexpr llvm::StringLiteral FuncID("fun");
 
-static Optional
+static Optional>
 analyzeFunction(const FunctionDecl &FuncDecl, ASTContext &ASTCtx) {
   using dataflow::ControlFlowContext;
   using dataflow::DataflowAnalysisState;
@@ -52,23 +54,22 @@ analyzeFunction(const FunctionDecl &FuncDecl, ASTContext 
&ASTCtx) {
   std::make_unique());
   dataflow::Environment Env(AnalysisContext, FuncDecl);
   UncheckedOptionalAccessModel Analysis(ASTCtx);
+  UncheckedOptionalAccessDiagnoser Diagnoser;
+  std::vector Diagnostics;
   
Expected>>>
-  BlockToOutputState =
-  dataflow::runDataflowAnalysis(*Context, Analysis, Env);
+  BlockToOutputState = dataflow::runDataflowAnalysis(
+  *Context, Analysis, Env,
+  [&ASTCtx, &Diagnoser,
+   &Diagnostics](const Stmt *Stmt,
+ const DataflowAnalysisState
+ &State) mutable {
+auto StmtDiagnostics = Diagnoser.diagnose(ASTCtx, Stmt, State.Env);
+llvm::move(StmtDiagnostics, std::back_inserter(Diagnostics));
+  });
   if (!BlockToOutputState)
 return llvm::None;
-  assert(Context->getCFG().getExit().getBlockID() < 
BlockToOutputState->size());
 
-  const Optional>
-  &ExitBlockState =
-  (*BlockToOutputState)[Context->getCFG().getExit().getBlockID()];
-  // `runDataflowAnalysis` doesn't guarantee that the exit block is visited;
-  // for example, when it is unreachable.
-  // FIXME: Diagnose violations even when the exit block is unreachable.
-  if (!ExitBlockState)
-return llvm::None;
-
-  return std::move(ExitBlockState->Lattice);
+  return Diagnostics;
 }
 
 void UncheckedOptionalAccessCheck::registerMatchers(MatchFinder *Finder) {
@@ -97,9 +98,9 @@ void UncheckedOptionalAccessCheck::check(
   if (FuncDecl->isTemplated())
 return;
 
-  if (Optional Errors =
+  if (Optional> Errors =
   analyzeFunction(*FuncDecl, *Result.Context))
-for (const SourceLocation &Loc : Errors->getSourceLocations())
+for (const SourceLocation &Loc : *Errors)
   diag(Loc, "unchecked access to optional value");
 }
 

diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
index f4d6a221abecc..40ac95b3abddb 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
@@ -109,14 +109,33 @@ template  struct DataflowAnalysisState 
{
 /// dataflow analysis states that model the respective basic blocks. The
 /// returned vector, if any, will have the same size as the number of CFG
 /// blocks, with indices corresponding to basic block IDs. Returns an error if
-/// the dataflow analysis cannot be performed successfully.
+/// the dataflow analysis cannot be performed successfully. Otherwise, calls
+/// `PostVisitStmt` on each statement with the final analysis results at that
+/// program point.
 template 
 llvm::Expected>>>
-runDataflowAnalysis(const ControlFlowContext &CFCtx, AnalysisT &Analysis,
-const Environm

[clang] 58fe7f9 - [clang][dataflow] Add API to separate analysis from diagnosis

2022-06-29 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-06-29T19:18:39Z
New Revision: 58fe7f9683a020a880426a4d8d61b067b83a9380

URL: 
https://github.com/llvm/llvm-project/commit/58fe7f9683a020a880426a4d8d61b067b83a9380
DIFF: 
https://github.com/llvm/llvm-project/commit/58fe7f9683a020a880426a4d8d61b067b83a9380.diff

LOG: [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

Added: 


Modified: 

clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
clang/unittests/Analysis/FlowSensitive/TestingSupport.h
clang/unittests/Analysis/FlowSensitive/UncheckedOptionalAccessModelTest.cpp

Removed: 




diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
 
b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
index 2102ed56907bb..701db6470ac2f 100644
--- 
a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
+++ 
b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
@@ -20,6 +20,8 @@
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/MatchSwitch.h"
 #include "clang/Analysis/FlowSensitive/SourceLocationsLattice.h"
+#include "clang/Basic/SourceLocation.h"
+#include 
 
 namespace clang {
 namespace dataflow {
@@ -71,6 +73,19 @@ class UncheckedOptionalAccessModel
   MatchSwitch> TransferMatchSwitch;
 };
 
+class UncheckedOptionalAccessDiagnoser {
+public:
+  UncheckedOptionalAccessDiagnoser(
+  UncheckedOptionalAccessModelOptions Options = {});
+
+  std::vector diagnose(ASTContext &Context, const Stmt *Stmt,
+   const Environment &Env);
+
+private:
+  MatchSwitch>
+  DiagnoseMatchSwitch;
+};
+
 } // namespace dataflow
 } // namespace clang
 

diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h 
b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
index 2d3a9e456370d..5e168194064f4 100644
--- a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
@@ -115,13 +115,17 @@ TypeErasedDataflowAnalysisState transferBlock(
 HandleTransferredStmt = nullptr);
 
 /// Performs dataflow analysis and returns a mapping from basic block IDs to
-/// dataflow analysis states that model the respective basic blocks. Indices
-/// of the returned vector correspond to basic block IDs. Returns an error if
-/// the dataflow analysis cannot be performed successfully.
+/// dataflow analysis states that model the respective basic blocks. Indices of
+/// the returned vector correspond to basic block IDs. Returns an error if the
+/// dataflow analysis cannot be performed successfully. Otherwise, calls
+/// `PostVisitStmt` on each statement with the final analysis results at that
+/// program point.
 llvm::Expected>>
-runTypeErasedDataflowAnalysis(const ControlFlowContext &CFCtx,
-  TypeErasedDataflowAnalysis &Analysis,
-  const Environment &InitEnv);
+runTypeErasedDataflowAnalysis(
+const Contro

[clang] 335c05f - [clang][dataflow] Use NoopLattice in optional model

2022-06-29 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-06-29T19:20:58Z
New Revision: 335c05f5d19fecd5c0972ac801e58248d772a78e

URL: 
https://github.com/llvm/llvm-project/commit/335c05f5d19fecd5c0972ac801e58248d772a78e
DIFF: 
https://github.com/llvm/llvm-project/commit/335c05f5d19fecd5c0972ac801e58248d772a78e.diff

LOG: [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

Added: 
clang/include/clang/Analysis/FlowSensitive/NoopLattice.h

Modified: 
clang/docs/tools/clang-formatted-files.txt

clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
clang/unittests/Analysis/FlowSensitive/NoopAnalysis.h

Removed: 




diff  --git a/clang/docs/tools/clang-formatted-files.txt 
b/clang/docs/tools/clang-formatted-files.txt
index ed8b5e7e7ae7c..40d95411c3a0a 100644
--- a/clang/docs/tools/clang-formatted-files.txt
+++ b/clang/docs/tools/clang-formatted-files.txt
@@ -131,6 +131,7 @@ clang/include/clang/Analysis/FlowSensitive/DataflowLattice.h
 clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h
 clang/include/clang/Analysis/FlowSensitive/MapLattice.h
 clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
+clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
 clang/include/clang/Analysis/FlowSensitive/Solver.h
 clang/include/clang/Analysis/FlowSensitive/SourceLocationsLattice.h
 clang/include/clang/Analysis/FlowSensitive/StorageLocation.h

diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
 
b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
index 701db6470ac2f..25054deaf8afc 100644
--- 
a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
+++ 
b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
@@ -19,7 +19,7 @@
 #include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/MatchSwitch.h"
-#include "clang/Analysis/FlowSensitive/SourceLocationsLattice.h"
+#include "clang/Analysis/FlowSensitive/NoopLattice.h"
 #include "clang/Basic/SourceLocation.h"
 #include 
 
@@ -38,15 +38,11 @@ struct UncheckedOptionalAccessModelOptions {
   bool IgnoreSmartPointerDereference = false;
 };
 
-/// Dataflow analysis that discovers unsafe accesses of optional values and
-/// adds the respective source locations to the lattice.
+/// Dataflow analysis that models whether optionals hold values or not.
 ///
 /// Models the `std::optional`, `absl::optional`, and `base::Optional` types.
-///
-/// FIXME: Consider separating the models from the unchecked access analysis.
 class UncheckedOptionalAccessModel
-: public DataflowAnalysis {
+: public DataflowAnalysis {
 public:
   UncheckedOptionalAccessModel(
   ASTContext &AstContext, UncheckedOptionalAccessModelOptions Options = 
{});
@@ -54,12 +50,9 @@ class UncheckedOptionalAccessModel
   /// Returns a matcher for the optional classes covered by this model.
   static ast_matchers::DeclarationMatcher optionalClassDecl();
 
-  static SourceLocationsLattice initialElement() {
-return SourceLocationsLattice();
-  }
+  static NoopLattice initialElement() { return {}; }
 
-  void transfer(const Stmt *Stmt, SourceLocationsLattice &State,
-Environment &Env);
+  void transfer(const Stmt *Stmt, NoopLattice &State, Environment &Env);
 
   bool compareEquivalent(QualType Type, const Value &Val1,
  const Environment &Env1, const Value &Val2,
@@ -70,7 +63,7 @@ class UncheckedOptionalAccessModel
  Environment &MergedEnv) override;
 
 private:
-  MatchSwitch> TransferMatchSwitch;
+  MatchSwitch> TransferMatchSwitch;
 };
 
 class UncheckedOptionalAccessDiagnoser {

diff  --git a/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h 
b/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
new file mode 100644
index 0..0192193281119
--- /dev/null
+++ b/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
@@ -0,0 +1,41 @@
+//===-- NoopLattice.h ---*- C++ 
-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+//  This file defines the lattice with exactly one element.
+//

[clang] 8361877 - Revert "[clang][dataflow] Use NoopLattice in optional model"

2022-06-29 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-06-29T19:34:30Z
New Revision: 8361877b10b8180ab12300b289da54a403ce7554

URL: 
https://github.com/llvm/llvm-project/commit/8361877b10b8180ab12300b289da54a403ce7554
DIFF: 
https://github.com/llvm/llvm-project/commit/8361877b10b8180ab12300b289da54a403ce7554.diff

LOG: Revert "[clang][dataflow] Use NoopLattice in optional model"

This reverts commit 335c05f5d19fecd5c0972ac801e58248d772a78e.

Added: 


Modified: 
clang/docs/tools/clang-formatted-files.txt

clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
clang/unittests/Analysis/FlowSensitive/NoopAnalysis.h

Removed: 
clang/include/clang/Analysis/FlowSensitive/NoopLattice.h



diff  --git a/clang/docs/tools/clang-formatted-files.txt 
b/clang/docs/tools/clang-formatted-files.txt
index 40d95411c3a0a..ed8b5e7e7ae7c 100644
--- a/clang/docs/tools/clang-formatted-files.txt
+++ b/clang/docs/tools/clang-formatted-files.txt
@@ -131,7 +131,6 @@ clang/include/clang/Analysis/FlowSensitive/DataflowLattice.h
 clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h
 clang/include/clang/Analysis/FlowSensitive/MapLattice.h
 clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
-clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
 clang/include/clang/Analysis/FlowSensitive/Solver.h
 clang/include/clang/Analysis/FlowSensitive/SourceLocationsLattice.h
 clang/include/clang/Analysis/FlowSensitive/StorageLocation.h

diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
 
b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
index 25054deaf8afc..701db6470ac2f 100644
--- 
a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
+++ 
b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
@@ -19,7 +19,7 @@
 #include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/MatchSwitch.h"
-#include "clang/Analysis/FlowSensitive/NoopLattice.h"
+#include "clang/Analysis/FlowSensitive/SourceLocationsLattice.h"
 #include "clang/Basic/SourceLocation.h"
 #include 
 
@@ -38,11 +38,15 @@ struct UncheckedOptionalAccessModelOptions {
   bool IgnoreSmartPointerDereference = false;
 };
 
-/// Dataflow analysis that models whether optionals hold values or not.
+/// Dataflow analysis that discovers unsafe accesses of optional values and
+/// adds the respective source locations to the lattice.
 ///
 /// Models the `std::optional`, `absl::optional`, and `base::Optional` types.
+///
+/// FIXME: Consider separating the models from the unchecked access analysis.
 class UncheckedOptionalAccessModel
-: public DataflowAnalysis {
+: public DataflowAnalysis {
 public:
   UncheckedOptionalAccessModel(
   ASTContext &AstContext, UncheckedOptionalAccessModelOptions Options = 
{});
@@ -50,9 +54,12 @@ class UncheckedOptionalAccessModel
   /// Returns a matcher for the optional classes covered by this model.
   static ast_matchers::DeclarationMatcher optionalClassDecl();
 
-  static NoopLattice initialElement() { return {}; }
+  static SourceLocationsLattice initialElement() {
+return SourceLocationsLattice();
+  }
 
-  void transfer(const Stmt *Stmt, NoopLattice &State, Environment &Env);
+  void transfer(const Stmt *Stmt, SourceLocationsLattice &State,
+Environment &Env);
 
   bool compareEquivalent(QualType Type, const Value &Val1,
  const Environment &Env1, const Value &Val2,
@@ -63,7 +70,7 @@ class UncheckedOptionalAccessModel
  Environment &MergedEnv) override;
 
 private:
-  MatchSwitch> TransferMatchSwitch;
+  MatchSwitch> TransferMatchSwitch;
 };
 
 class UncheckedOptionalAccessDiagnoser {

diff  --git a/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h 
b/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
deleted file mode 100644
index 0192193281119..0
--- a/clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
+++ /dev/null
@@ -1,41 +0,0 @@
-//===-- NoopLattice.h ---*- C++ 
-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===--===//
-//
-//  This file defines the lattice with exactly one element.
-//
-//===--===//
-
-#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H
-#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOP_LATTICE_H
-
-#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
-#include 
-

[clang-tools-extra] 2a33d12 - Revert "[clang][dataflow] Use diagnosis API in optional checker"

2022-06-29 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-06-29T19:34:44Z
New Revision: 2a33d12642d862a8aa307e4a8b8a94d2d0c5ad1d

URL: 
https://github.com/llvm/llvm-project/commit/2a33d12642d862a8aa307e4a8b8a94d2d0c5ad1d
DIFF: 
https://github.com/llvm/llvm-project/commit/2a33d12642d862a8aa307e4a8b8a94d2d0c5ad1d.diff

LOG: Revert "[clang][dataflow] Use diagnosis API in optional checker"

This reverts commit cafb8b4ff2c38f81e65f97193eb1d8d16c581522.

Added: 


Modified: 
clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
index 9766450e81654..07fb19ff81ac1 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
@@ -23,7 +23,6 @@
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/Any.h"
 #include "llvm/ADT/Optional.h"
-#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Error.h"
 #include 
 #include 
@@ -33,13 +32,12 @@ namespace tidy {
 namespace bugprone {
 using ast_matchers::MatchFinder;
 using dataflow::SourceLocationsLattice;
-using dataflow::UncheckedOptionalAccessDiagnoser;
 using dataflow::UncheckedOptionalAccessModel;
 using llvm::Optional;
 
 static constexpr llvm::StringLiteral FuncID("fun");
 
-static Optional>
+static Optional
 analyzeFunction(const FunctionDecl &FuncDecl, ASTContext &ASTCtx) {
   using dataflow::ControlFlowContext;
   using dataflow::DataflowAnalysisState;
@@ -54,22 +52,23 @@ analyzeFunction(const FunctionDecl &FuncDecl, ASTContext 
&ASTCtx) {
   std::make_unique());
   dataflow::Environment Env(AnalysisContext, FuncDecl);
   UncheckedOptionalAccessModel Analysis(ASTCtx);
-  UncheckedOptionalAccessDiagnoser Diagnoser;
-  std::vector Diagnostics;
   
Expected>>>
-  BlockToOutputState = dataflow::runDataflowAnalysis(
-  *Context, Analysis, Env,
-  [&ASTCtx, &Diagnoser,
-   &Diagnostics](const Stmt *Stmt,
- const DataflowAnalysisState
- &State) mutable {
-auto StmtDiagnostics = Diagnoser.diagnose(ASTCtx, Stmt, State.Env);
-llvm::move(StmtDiagnostics, std::back_inserter(Diagnostics));
-  });
+  BlockToOutputState =
+  dataflow::runDataflowAnalysis(*Context, Analysis, Env);
   if (!BlockToOutputState)
 return llvm::None;
+  assert(Context->getCFG().getExit().getBlockID() < 
BlockToOutputState->size());
 
-  return Diagnostics;
+  const Optional>
+  &ExitBlockState =
+  (*BlockToOutputState)[Context->getCFG().getExit().getBlockID()];
+  // `runDataflowAnalysis` doesn't guarantee that the exit block is visited;
+  // for example, when it is unreachable.
+  // FIXME: Diagnose violations even when the exit block is unreachable.
+  if (!ExitBlockState)
+return llvm::None;
+
+  return std::move(ExitBlockState->Lattice);
 }
 
 void UncheckedOptionalAccessCheck::registerMatchers(MatchFinder *Finder) {
@@ -98,9 +97,9 @@ void UncheckedOptionalAccessCheck::check(
   if (FuncDecl->isTemplated())
 return;
 
-  if (Optional> Errors =
+  if (Optional Errors =
   analyzeFunction(*FuncDecl, *Result.Context))
-for (const SourceLocation &Loc : *Errors)
+for (const SourceLocation &Loc : Errors->getSourceLocations())
   diag(Loc, "unchecked access to optional value");
 }
 

diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
index 40ac95b3abddb..f4d6a221abecc 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
@@ -109,33 +109,14 @@ template  struct DataflowAnalysisState 
{
 /// dataflow analysis states that model the respective basic blocks. The
 /// returned vector, if any, will have the same size as the number of CFG
 /// blocks, with indices corresponding to basic block IDs. Returns an error if
-/// the dataflow analysis cannot be performed successfully. Otherwise, calls
-/// `PostVisitStmt` on each statement with the final analysis results at that
-/// program point.
+/// the dataflow analysis cannot be performed successfully.
 template 
 llvm::Expected>>>
-runDataflowAnalysis(
-const ControlFlowContext &CFCtx, AnalysisT &Analysis,
-const Environment &InitEnv,
-std::function &)>
-PostVisitStmt = nullptr) {
-  std::function
-  PostVisitStmtClosure = nullptr;
-  if (PostVisitStmt != nullptr) {
-PostVisitStmtClosure = [&PostVisitStmt](
-   const Stmt *Stmt,
-   const TypeErasedDataflowAnalysisState &State) {
-  auto *Lattice =
-

[clang-tools-extra] 2adaca5 - [clang][dataflow] Use diagnosis API in optional checker

2022-06-29 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-06-29T19:50:36Z
New Revision: 2adaca532df4d3d7ae4cd3b724b2099ffefe235c

URL: 
https://github.com/llvm/llvm-project/commit/2adaca532df4d3d7ae4cd3b724b2099ffefe235c
DIFF: 
https://github.com/llvm/llvm-project/commit/2adaca532df4d3d7ae4cd3b724b2099ffefe235c.diff

LOG: [clang][dataflow] Use diagnosis API in optional checker

Followup to D127898. This patch updates `bugprone-unchecked-optional-access` to 
use the new `diagnoseCFG` function instead of just looking at the exit block.

A followup to this will update the optional model itself to use a noop lattice 
rather than redundantly computing the diagnostics in both phases of the 
analysis.

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

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
index 07fb19ff81ac1..9766450e81654 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
@@ -23,6 +23,7 @@
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/Any.h"
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Error.h"
 #include 
 #include 
@@ -32,12 +33,13 @@ namespace tidy {
 namespace bugprone {
 using ast_matchers::MatchFinder;
 using dataflow::SourceLocationsLattice;
+using dataflow::UncheckedOptionalAccessDiagnoser;
 using dataflow::UncheckedOptionalAccessModel;
 using llvm::Optional;
 
 static constexpr llvm::StringLiteral FuncID("fun");
 
-static Optional
+static Optional>
 analyzeFunction(const FunctionDecl &FuncDecl, ASTContext &ASTCtx) {
   using dataflow::ControlFlowContext;
   using dataflow::DataflowAnalysisState;
@@ -52,23 +54,22 @@ analyzeFunction(const FunctionDecl &FuncDecl, ASTContext 
&ASTCtx) {
   std::make_unique());
   dataflow::Environment Env(AnalysisContext, FuncDecl);
   UncheckedOptionalAccessModel Analysis(ASTCtx);
+  UncheckedOptionalAccessDiagnoser Diagnoser;
+  std::vector Diagnostics;
   
Expected>>>
-  BlockToOutputState =
-  dataflow::runDataflowAnalysis(*Context, Analysis, Env);
+  BlockToOutputState = dataflow::runDataflowAnalysis(
+  *Context, Analysis, Env,
+  [&ASTCtx, &Diagnoser,
+   &Diagnostics](const Stmt *Stmt,
+ const DataflowAnalysisState
+ &State) mutable {
+auto StmtDiagnostics = Diagnoser.diagnose(ASTCtx, Stmt, State.Env);
+llvm::move(StmtDiagnostics, std::back_inserter(Diagnostics));
+  });
   if (!BlockToOutputState)
 return llvm::None;
-  assert(Context->getCFG().getExit().getBlockID() < 
BlockToOutputState->size());
 
-  const Optional>
-  &ExitBlockState =
-  (*BlockToOutputState)[Context->getCFG().getExit().getBlockID()];
-  // `runDataflowAnalysis` doesn't guarantee that the exit block is visited;
-  // for example, when it is unreachable.
-  // FIXME: Diagnose violations even when the exit block is unreachable.
-  if (!ExitBlockState)
-return llvm::None;
-
-  return std::move(ExitBlockState->Lattice);
+  return Diagnostics;
 }
 
 void UncheckedOptionalAccessCheck::registerMatchers(MatchFinder *Finder) {
@@ -97,9 +98,9 @@ void UncheckedOptionalAccessCheck::check(
   if (FuncDecl->isTemplated())
 return;
 
-  if (Optional Errors =
+  if (Optional> Errors =
   analyzeFunction(*FuncDecl, *Result.Context))
-for (const SourceLocation &Loc : Errors->getSourceLocations())
+for (const SourceLocation &Loc : *Errors)
   diag(Loc, "unchecked access to optional value");
 }
 

diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
index f4d6a221abecc..40ac95b3abddb 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
@@ -109,14 +109,33 @@ template  struct DataflowAnalysisState 
{
 /// dataflow analysis states that model the respective basic blocks. The
 /// returned vector, if any, will have the same size as the number of CFG
 /// blocks, with indices corresponding to basic block IDs. Returns an error if
-/// the dataflow analysis cannot be performed successfully.
+/// the dataflow analysis cannot be performed successfully. Otherwise, calls
+/// `PostVisitStmt` on each statement with the final analysis results at that
+/// program point.
 template 
 llvm::Expected>>>
-runDataflowAnalysis(const ControlFlowContext &CFCtx, AnalysisT &Analysis,
-const Environm

[clang] cf1f978 - [clang][dataflow] Use NoopLattice in optional model

2022-06-29 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-06-29T20:10:42Z
New Revision: cf1f978d319b91464370d71289e1c7c30baa4243

URL: 
https://github.com/llvm/llvm-project/commit/cf1f978d319b91464370d71289e1c7c30baa4243
DIFF: 
https://github.com/llvm/llvm-project/commit/cf1f978d319b91464370d71289e1c7c30baa4243.diff

LOG: [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

Added: 
clang/include/clang/Analysis/FlowSensitive/NoopLattice.h

Modified: 
clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
clang/docs/tools/clang-formatted-files.txt

clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
clang/lib/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.cpp
clang/unittests/Analysis/FlowSensitive/NoopAnalysis.h

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
index 9766450e81654..8a945a5143067 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
@@ -18,7 +18,6 @@
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/DataflowLattice.h"
 #include "clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h"
-#include "clang/Analysis/FlowSensitive/SourceLocationsLattice.h"
 #include "clang/Analysis/FlowSensitive/WatchedLiteralsSolver.h"
 #include "clang/Basic/SourceLocation.h"
 #include "llvm/ADT/Any.h"
@@ -32,7 +31,6 @@ namespace clang {
 namespace tidy {
 namespace bugprone {
 using ast_matchers::MatchFinder;
-using dataflow::SourceLocationsLattice;
 using dataflow::UncheckedOptionalAccessDiagnoser;
 using dataflow::UncheckedOptionalAccessModel;
 using llvm::Optional;
@@ -56,13 +54,14 @@ analyzeFunction(const FunctionDecl &FuncDecl, ASTContext 
&ASTCtx) {
   UncheckedOptionalAccessModel Analysis(ASTCtx);
   UncheckedOptionalAccessDiagnoser Diagnoser;
   std::vector Diagnostics;
-  
Expected>>>
+  Expected>>>
   BlockToOutputState = dataflow::runDataflowAnalysis(
   *Context, Analysis, Env,
-  [&ASTCtx, &Diagnoser,
-   &Diagnostics](const Stmt *Stmt,
- const DataflowAnalysisState
- &State) mutable {
+  [&ASTCtx, &Diagnoser, &Diagnostics](
+  const Stmt *Stmt,
+  const 
DataflowAnalysisState
+  &State) mutable {
 auto StmtDiagnostics = Diagnoser.diagnose(ASTCtx, Stmt, State.Env);
 llvm::move(StmtDiagnostics, std::back_inserter(Diagnostics));
   });

diff  --git a/clang/docs/tools/clang-formatted-files.txt 
b/clang/docs/tools/clang-formatted-files.txt
index ed8b5e7e7ae7c..40d95411c3a0a 100644
--- a/clang/docs/tools/clang-formatted-files.txt
+++ b/clang/docs/tools/clang-formatted-files.txt
@@ -131,6 +131,7 @@ clang/include/clang/Analysis/FlowSensitive/DataflowLattice.h
 clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h
 clang/include/clang/Analysis/FlowSensitive/MapLattice.h
 clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
+clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
 clang/include/clang/Analysis/FlowSensitive/Solver.h
 clang/include/clang/Analysis/FlowSensitive/SourceLocationsLattice.h
 clang/include/clang/Analysis/FlowSensitive/StorageLocation.h

diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
 
b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
index 701db6470ac2f..25054deaf8afc 100644
--- 
a/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
+++ 
b/clang/include/clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h
@@ -19,7 +19,7 @@
 #include "clang/Analysis/FlowSensitive/DataflowAnalysis.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/MatchSwitch.h"
-#include "clang/Analysis/FlowSensitive/SourceLocationsLattice.h"
+#include "clang/Analysis/FlowSensitive/NoopLattice.h"
 #include "clang/Basic/SourceLocation.h"
 #include 
 
@@ -38,15 +38,11 @@ struct UncheckedOptionalAccessModelOptions {
   bool IgnoreSmartPointerDereference = false;
 };
 
-/// Dataflow analysis that discovers unsafe accesses of optional values and
-/// adds the respective source locations to the lattice.
+/// Dataflow analysis that models whether optionals hold values or not.
 ///
 /// Models the `std::optional`,

[clang] 6a97be2 - [clang][dataflow] Delete SourceLocationsLattice

2022-06-29 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-06-29T20:14:07Z
New Revision: 6a97be27a1de652b8f09f43178d09fc100b05990

URL: 
https://github.com/llvm/llvm-project/commit/6a97be27a1de652b8f09f43178d09fc100b05990
DIFF: 
https://github.com/llvm/llvm-project/commit/6a97be27a1de652b8f09f43178d09fc100b05990.diff

LOG: [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

Added: 


Modified: 
clang/docs/tools/clang-formatted-files.txt
clang/lib/Analysis/FlowSensitive/CMakeLists.txt
clang/unittests/Analysis/FlowSensitive/CMakeLists.txt
llvm/utils/gn/secondary/clang/lib/Analysis/FlowSensitive/BUILD.gn
llvm/utils/gn/secondary/clang/unittests/Analysis/FlowSensitive/BUILD.gn

Removed: 
clang/include/clang/Analysis/FlowSensitive/SourceLocationsLattice.h
clang/lib/Analysis/FlowSensitive/SourceLocationsLattice.cpp
clang/unittests/Analysis/FlowSensitive/SourceLocationsLatticeTest.cpp



diff  --git a/clang/docs/tools/clang-formatted-files.txt 
b/clang/docs/tools/clang-formatted-files.txt
index 40d95411c3a0a..5e1c6f130a0e4 100644
--- a/clang/docs/tools/clang-formatted-files.txt
+++ b/clang/docs/tools/clang-formatted-files.txt
@@ -133,7 +133,6 @@ clang/include/clang/Analysis/FlowSensitive/MapLattice.h
 clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
 clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
 clang/include/clang/Analysis/FlowSensitive/Solver.h
-clang/include/clang/Analysis/FlowSensitive/SourceLocationsLattice.h
 clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
 clang/include/clang/Analysis/FlowSensitive/Transfer.h
 clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
@@ -310,7 +309,6 @@ clang/lib/Analysis/CodeInjector.cpp
 clang/lib/Analysis/FlowSensitive/ControlFlowContext.cpp
 clang/lib/Analysis/FlowSensitive/DataflowAnalysisContext.cpp
 clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
-clang/lib/Analysis/FlowSensitive/SourceLocationsLattice.cpp
 clang/lib/Analysis/FlowSensitive/Transfer.cpp
 clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
 clang/lib/Analysis/FlowSensitive/WatchedLiteralsSolver.cpp
@@ -637,7 +635,6 @@ 
clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp
 clang/unittests/Analysis/FlowSensitive/NoopAnalysis.h
 clang/unittests/Analysis/FlowSensitive/SingleVarConstantPropagationTest.cpp
 clang/unittests/Analysis/FlowSensitive/SolverTest.cpp
-clang/unittests/Analysis/FlowSensitive/SourceLocationsLatticeTest.cpp
 clang/unittests/Analysis/FlowSensitive/TestingSupport.cpp
 clang/unittests/Analysis/FlowSensitive/TestingSupport.h
 clang/unittests/Analysis/FlowSensitive/TestingSupportTest.cpp

diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/SourceLocationsLattice.h 
b/clang/include/clang/Analysis/FlowSensitive/SourceLocationsLattice.h
deleted file mode 100644
index d294f9768cdc5..0
--- a/clang/include/clang/Analysis/FlowSensitive/SourceLocationsLattice.h
+++ /dev/null
@@ -1,65 +0,0 @@
-//===-- SourceLocationsLattice.h *- C++ 
-*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===--===//
-//
-//  This file defines a lattice that collects source locations of interest.
-//
-//===--===//
-
-#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_SOURCELOCATIONS_LATTICE_H
-#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_SOURCELOCATIONS_LATTICE_H
-
-#include "clang/AST/ASTContext.h"
-#include "clang/Analysis/FlowSensitive/DataflowLattice.h"
-#include "clang/Basic/SourceLocation.h"
-#include "llvm/ADT/DenseSet.h"
-#include 
-#include 
-
-namespace clang {
-namespace dataflow {
-
-/// Lattice for dataflow analysis that keeps track of a set of source 
locations.
-///
-/// Bottom is the empty set, join is set union, and equality is set equality.
-///
-/// FIXME: Generalize into a (templated) PowerSetLattice.
-class SourceLocationsLattice {
-public:
-  SourceLocationsLattice() = default;
-
-  explicit SourceLocationsLattice(llvm::DenseSet Locs)
-  : Locs(std::move(Locs)) {}
-
-  bool operator==(const SourceLocationsLattice &Other) const {
-return Locs == Other.Locs;
-  }
-
-  bool operator!=(const SourceLocationsLattice &Other) const {
-return !(*this == Other);
-  }
-
-  LatticeJoinEffect join(const SourceLocationsLattice &Other);
-
-  llvm::DenseSet &getSourceLocations() { return Locs; }
-
-  const llvm::DenseSet &getSourceLocations() 

[clang] 1d83a16 - [clang][dataflow] Replace TEST_F with TEST where possible

2022-06-30 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-06-30T16:03:33Z
New Revision: 1d83a16bd3faa1dfb6e8ed40c53d018dc03e2c81

URL: 
https://github.com/llvm/llvm-project/commit/1d83a16bd3faa1dfb6e8ed40c53d018dc03e2c81
DIFF: 
https://github.com/llvm/llvm-project/commit/1d83a16bd3faa1dfb6e8ed40c53d018dc03e2c81.diff

LOG: [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

Added: 


Modified: 
clang/unittests/Analysis/FlowSensitive/ChromiumCheckModelTest.cpp
clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp
clang/unittests/Analysis/FlowSensitive/SingleVarConstantPropagationTest.cpp
clang/unittests/Analysis/FlowSensitive/TestingSupportTest.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 




diff  --git a/clang/unittests/Analysis/FlowSensitive/ChromiumCheckModelTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/ChromiumCheckModelTest.cpp
index a61d6dc682d87..2be1405465838 100644
--- a/clang/unittests/Analysis/FlowSensitive/ChromiumCheckModelTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/ChromiumCheckModelTest.cpp
@@ -128,31 +128,28 @@ class ModelAdaptorAnalysis
   Model M;
 };
 
-class ChromiumCheckModelTest : public ::testing::TestWithParam {
-protected:
-  template 
-  void runDataflow(llvm::StringRef Code, Matcher Match) {
-const tooling::FileContentMappings FileContents = {
-{"check.h", ChromiumCheckHeader}, {"othercheck.h", OtherCheckHeader}};
-
-ASSERT_THAT_ERROR(
-test::checkDataflow>(
-Code, "target",
-[](ASTContext &C, Environment &) {
-  return ModelAdaptorAnalysis(C);
-},
-[&Match](
-llvm::ArrayRef<
-std::pair>>
-Results,
-ASTContext &ASTCtx) { Match(Results, ASTCtx); },
-{"-fsyntax-only", "-fno-delayed-template-parsing", "-std=c++17"},
-FileContents),
-llvm::Succeeded());
-  }
-};
+template 
+void runDataflow(llvm::StringRef Code, Matcher Match) {
+  const tooling::FileContentMappings FileContents = {
+  {"check.h", ChromiumCheckHeader}, {"othercheck.h", OtherCheckHeader}};
+
+  ASSERT_THAT_ERROR(
+  test::checkDataflow>(
+  Code, "target",
+  [](ASTContext &C, Environment &) {
+return ModelAdaptorAnalysis(C);
+  },
+  [&Match](
+  llvm::ArrayRef<
+  std::pair>>
+  Results,
+  ASTContext &ASTCtx) { Match(Results, ASTCtx); },
+  {"-fsyntax-only", "-fno-delayed-template-parsing", "-std=c++17"},
+  FileContents),
+  llvm::Succeeded());
+}
 
-TEST_F(ChromiumCheckModelTest, CheckSuccessImpliesConditionHolds) {
+TEST(ChromiumCheckModelTest, CheckSuccessImpliesConditionHolds) {
   auto Expectations =
   [](llvm::ArrayRef<
  std::pair>>
@@ -185,7 +182,7 @@ TEST_F(ChromiumCheckModelTest, 
CheckSuccessImpliesConditionHolds) {
   runDataflow(ReplacePattern(Code, "$check", "DPCHECK"), Expectations);
 }
 
-TEST_F(ChromiumCheckModelTest, UnrelatedCheckIgnored) {
+TEST(ChromiumCheckModelTest, UnrelatedCheckIgnored) {
   auto Expectations =
   [](llvm::ArrayRef<
  std::pair>>

diff  --git a/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
index 98319760fd206..bf8c2f5eedc95 100644
--- a/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
@@ -123,25 +123,22 @@ class TestAnalysis : public 
DataflowAnalysis {
   }
 };
 
-class MatchSwitchTest : public ::testing::Test {
-protected:
-  template 
-  void RunDataflow(llvm::StringRef Code, Matcher Expectations) {
-ASSERT_THAT_ERROR(
-test::checkDataflow(
-Code, "fun",
-[](ASTContext &C, Environment &) { return TestAnalysis(C); },
-[&Expectations](
-llvm::ArrayR

[clang] fa2b83d - [clang][dataflow] Analyze calls to in-TU functions

2022-07-26 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-07-26T17:27:19Z
New Revision: fa2b83d07ecab3b24b4c5ee2e7dc4b6bbc895317

URL: 
https://github.com/llvm/llvm-project/commit/fa2b83d07ecab3b24b4c5ee2e7dc4b6bbc895317
DIFF: 
https://github.com/llvm/llvm-project/commit/fa2b83d07ecab3b24b4c5ee2e7dc4b6bbc895317.diff

LOG: [clang][dataflow] Analyze calls to in-TU functions

Depends On D130305

This patch adds initial support for context-sensitive analysis of simple 
functions whose definition is available in the translation unit, guarded by the 
`ContextSensitive` flag in the new `TransferOptions` struct. When this option 
is true, the `VisitCallExpr` case in the builtin transfer function has a 
fallthrough case which checks for a direct callee with a body. In that case, it 
constructs a CFG from that callee body, uses the new `pushCall` method on the 
`Environment` to make an environment to analyze the callee, and then calls 
`runDataflowAnalysis` with a `NoopAnalysis` (disabling context-sensitive 
analysis on that sub-analysis, to avoid problems with recursion). After the 
sub-analysis completes, the `Environment` from its exit block is simply 
assigned back to the environment at the callsite.

The `pushCall` method (which currently only supports non-method functions with 
some restrictions) first calls `initGlobalVars`, then maps the 
`SourceLocation`s for all the parameters to the existing source locations for 
the corresponding arguments from the callsite.

This patch adds a few tests to check that this context-sensitive analysis works 
on simple functions. More sophisticated functionality will be added later; the 
most important next step is to explicitly model context in some fields of the 
`DataflowAnalysisContext` class, as mentioned in a `TODO` comment in the 
`pushCall` implementation.

Reviewed By: ymandel, xazax.hun

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

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
clang/include/clang/Analysis/FlowSensitive/Transfer.h
clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index f17df36f6a4a..2e9c088d0e5c 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -128,6 +128,21 @@ class Environment {
   /// with a symbolic representation of the `this` pointee.
   Environment(DataflowAnalysisContext &DACtx, const DeclContext &DeclCtx);
 
+  /// Creates and returns an environment to use for an inline analysis  of the
+  /// callee. Uses the storage location from each argument in the `Call` as the
+  /// storage location for the corresponding parameter in the callee.
+  ///
+  /// Requirements:
+  ///
+  ///  The callee of `Call` must be a `FunctionDecl` with a body.
+  ///
+  ///  The body of the callee must not reference globals.
+  ///
+  ///  The arguments of `Call` must map 1:1 to the callee's parameters.
+  ///
+  ///  Each argument of `Call` must already have a `StorageLocation`.
+  Environment pushCall(const CallExpr *Call) const;
+
   /// Returns true if and only if the environment is equivalent to `Other`, i.e
   /// the two environments:
   ///  - have the same mappings from declarations to storage locations,

diff  --git a/clang/include/clang/Analysis/FlowSensitive/Transfer.h 
b/clang/include/clang/Analysis/FlowSensitive/Transfer.h
index 25afa01f307c..cbb625487c1e 100644
--- a/clang/include/clang/Analysis/FlowSensitive/Transfer.h
+++ b/clang/include/clang/Analysis/FlowSensitive/Transfer.h
@@ -20,6 +20,12 @@
 namespace clang {
 namespace dataflow {
 
+struct TransferOptions {
+  /// Determines whether to analyze function bodies when present in the
+  /// translation unit.
+  bool ContextSensitive = false;
+};
+
 /// Maps statements to the environments of basic blocks that contain them.
 class StmtToEnvMap {
 public:
@@ -36,7 +42,8 @@ class StmtToEnvMap {
 /// Requirements:
 ///
 ///  `S` must not be `ParenExpr` or `ExprWithCleanups`.
-void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env);
+void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env,
+  TransferOptions Options);
 
 } // namespace dataflow
 } // namespace clang

diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h 
b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
index b043062459e4..92700f164e7b 100644
--- a/clang/include/clang/Analysis/FlowSensitiv

[clang] cc9aa15 - Revert "[clang][dataflow] Analyze calls to in-TU functions"

2022-07-26 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-07-26T17:30:09Z
New Revision: cc9aa157a83a4da52f9749807429205583d815da

URL: 
https://github.com/llvm/llvm-project/commit/cc9aa157a83a4da52f9749807429205583d815da
DIFF: 
https://github.com/llvm/llvm-project/commit/cc9aa157a83a4da52f9749807429205583d815da.diff

LOG: Revert "[clang][dataflow] Analyze calls to in-TU functions"

This reverts commit fa2b83d07ecab3b24b4c5ee2e7dc4b6bbc895317.

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
clang/include/clang/Analysis/FlowSensitive/Transfer.h
clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index 2e9c088d0e5c..f17df36f6a4a 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -128,21 +128,6 @@ class Environment {
   /// with a symbolic representation of the `this` pointee.
   Environment(DataflowAnalysisContext &DACtx, const DeclContext &DeclCtx);
 
-  /// Creates and returns an environment to use for an inline analysis  of the
-  /// callee. Uses the storage location from each argument in the `Call` as the
-  /// storage location for the corresponding parameter in the callee.
-  ///
-  /// Requirements:
-  ///
-  ///  The callee of `Call` must be a `FunctionDecl` with a body.
-  ///
-  ///  The body of the callee must not reference globals.
-  ///
-  ///  The arguments of `Call` must map 1:1 to the callee's parameters.
-  ///
-  ///  Each argument of `Call` must already have a `StorageLocation`.
-  Environment pushCall(const CallExpr *Call) const;
-
   /// Returns true if and only if the environment is equivalent to `Other`, i.e
   /// the two environments:
   ///  - have the same mappings from declarations to storage locations,

diff  --git a/clang/include/clang/Analysis/FlowSensitive/Transfer.h 
b/clang/include/clang/Analysis/FlowSensitive/Transfer.h
index cbb625487c1e..25afa01f307c 100644
--- a/clang/include/clang/Analysis/FlowSensitive/Transfer.h
+++ b/clang/include/clang/Analysis/FlowSensitive/Transfer.h
@@ -20,12 +20,6 @@
 namespace clang {
 namespace dataflow {
 
-struct TransferOptions {
-  /// Determines whether to analyze function bodies when present in the
-  /// translation unit.
-  bool ContextSensitive = false;
-};
-
 /// Maps statements to the environments of basic blocks that contain them.
 class StmtToEnvMap {
 public:
@@ -42,8 +36,7 @@ class StmtToEnvMap {
 /// Requirements:
 ///
 ///  `S` must not be `ParenExpr` or `ExprWithCleanups`.
-void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env,
-  TransferOptions Options);
+void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env);
 
 } // namespace dataflow
 } // namespace clang

diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h 
b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
index 92700f164e7b..b043062459e4 100644
--- a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
@@ -23,7 +23,6 @@
 #include "clang/Analysis/FlowSensitive/ControlFlowContext.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
 #include "clang/Analysis/FlowSensitive/DataflowLattice.h"
-#include "clang/Analysis/FlowSensitive/Transfer.h"
 #include "llvm/ADT/Any.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/Support/Error.h"
@@ -37,9 +36,6 @@ struct DataflowAnalysisOptions {
   // (at which point the built-in transfer functions can be simply a standalone
   // analysis).
   bool ApplyBuiltinTransfer = true;
-
-  /// Only has an effect if `ApplyBuiltinTransfer` is true.
-  TransferOptions BuiltinTransferOptions;
 };
 
 /// Type-erased lattice element container.
@@ -61,7 +57,7 @@ class TypeErasedDataflowAnalysis : public 
Environment::ValueModel {
 
   /// Deprecated. Use the `DataflowAnalysisOptions` constructor instead.
   TypeErasedDataflowAnalysis(bool ApplyBuiltinTransfer)
-  : Options({ApplyBuiltinTransfer, TransferOptions{}}) {}
+  : Options({ApplyBuiltinTransfer}) {}
 
   TypeErasedDataflowAnalysis(DataflowAnalysisOptions Options)
   : Options(Options) {}
@@ -94,11 +90,6 @@ class TypeErasedDataflowAnalysis : public 
Environment::ValueModel {
   /// Determines whether to apply the built-in transfer functions, which model
   /// the heap and stack in the `Environment`.
   bool applyBuiltinTransfer() const

[clang] 300fbf5 - [clang][dataflow] Analyze calls to in-TU functions

2022-07-26 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-07-26T17:54:27Z
New Revision: 300fbf56f89aebbe2ef9ed490066bab23e5356d1

URL: 
https://github.com/llvm/llvm-project/commit/300fbf56f89aebbe2ef9ed490066bab23e5356d1
DIFF: 
https://github.com/llvm/llvm-project/commit/300fbf56f89aebbe2ef9ed490066bab23e5356d1.diff

LOG: [clang][dataflow] Analyze calls to in-TU functions

This patch adds initial support for context-sensitive analysis of simple 
functions whose definition is available in the translation unit, guarded by the 
`ContextSensitive` flag in the new `TransferOptions` struct. When this option 
is true, the `VisitCallExpr` case in the builtin transfer function has a 
fallthrough case which checks for a direct callee with a body. In that case, it 
constructs a CFG from that callee body, uses the new `pushCall` method on the 
`Environment` to make an environment to analyze the callee, and then calls 
`runDataflowAnalysis` with a `NoopAnalysis` (disabling context-sensitive 
analysis on that sub-analysis, to avoid problems with recursion). After the 
sub-analysis completes, the `Environment` from its exit block is simply 
assigned back to the environment at the callsite.

The `pushCall` method (which currently only supports non-method functions with 
some restrictions) maps the `SourceLocation`s for all the parameters to the 
existing source locations for the corresponding arguments from the callsite.

This patch adds a few tests to check that this context-sensitive analysis works 
on simple functions. More sophisticated functionality will be added later; the 
most important next step is to explicitly model context in some fields of the 
`DataflowAnalysisContext` class, as mentioned in a `FIXME` comment in the 
`pushCall` implementation.

Reviewed By: ymandel, xazax.hun

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

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
clang/include/clang/Analysis/FlowSensitive/Transfer.h
clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index f17df36f6a4a..2e9c088d0e5c 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -128,6 +128,21 @@ class Environment {
   /// with a symbolic representation of the `this` pointee.
   Environment(DataflowAnalysisContext &DACtx, const DeclContext &DeclCtx);
 
+  /// Creates and returns an environment to use for an inline analysis  of the
+  /// callee. Uses the storage location from each argument in the `Call` as the
+  /// storage location for the corresponding parameter in the callee.
+  ///
+  /// Requirements:
+  ///
+  ///  The callee of `Call` must be a `FunctionDecl` with a body.
+  ///
+  ///  The body of the callee must not reference globals.
+  ///
+  ///  The arguments of `Call` must map 1:1 to the callee's parameters.
+  ///
+  ///  Each argument of `Call` must already have a `StorageLocation`.
+  Environment pushCall(const CallExpr *Call) const;
+
   /// Returns true if and only if the environment is equivalent to `Other`, i.e
   /// the two environments:
   ///  - have the same mappings from declarations to storage locations,

diff  --git a/clang/include/clang/Analysis/FlowSensitive/Transfer.h 
b/clang/include/clang/Analysis/FlowSensitive/Transfer.h
index 25afa01f307c..cbb625487c1e 100644
--- a/clang/include/clang/Analysis/FlowSensitive/Transfer.h
+++ b/clang/include/clang/Analysis/FlowSensitive/Transfer.h
@@ -20,6 +20,12 @@
 namespace clang {
 namespace dataflow {
 
+struct TransferOptions {
+  /// Determines whether to analyze function bodies when present in the
+  /// translation unit.
+  bool ContextSensitive = false;
+};
+
 /// Maps statements to the environments of basic blocks that contain them.
 class StmtToEnvMap {
 public:
@@ -36,7 +42,8 @@ class StmtToEnvMap {
 /// Requirements:
 ///
 ///  `S` must not be `ParenExpr` or `ExprWithCleanups`.
-void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env);
+void transfer(const StmtToEnvMap &StmtToEnv, const Stmt &S, Environment &Env,
+  TransferOptions Options);
 
 } // namespace dataflow
 } // namespace clang

diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h 
b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
index b043062459e4..92700f164e7b 100644
--- a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
+++ b/clang/include/clan

[clang] a6ddc68 - [clang][dataflow] Handle multiple context-sensitive calls to the same function

2022-07-29 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-07-29T19:40:19Z
New Revision: a6ddc68487823d48c0ec0ddd649ace4a2732d0b0

URL: 
https://github.com/llvm/llvm-project/commit/a6ddc68487823d48c0ec0ddd649ace4a2732d0b0
DIFF: 
https://github.com/llvm/llvm-project/commit/a6ddc68487823d48c0ec0ddd649ace4a2732d0b0.diff

LOG: [clang][dataflow] Handle multiple context-sensitive calls to the same 
function

This patch enables context-sensitive analysis of multiple different calls to 
the same function (see the `ContextSensitiveSetBothTrueAndFalse` example in the 
`TransferTest` suite) by replacing the `Environment` copy-assignment with a 
call to the new `popCall` method, which  `std::move`s some fields but 
specifically does not move `DeclToLoc` and `ExprToLoc` from the callee back to 
the caller.

To enable this, the `StorageLocation` for a given parameter needs to be stable 
across different calls to the same function, so this patch also improves the 
modeling of parameter initialization, using `ReferenceValue` when necessary 
(for arguments passed by reference).

This approach explicitly does not work for recursive calls, because we 
currently only plan to use this context-sensitive machinery to support 
specialized analysis models we write, not analysis of arbitrary callees.

Reviewed By: ymandel, xazax.hun

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

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
clang/include/clang/Analysis/FlowSensitive/Transfer.h
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index 2e9c088d0e5c3..9ba73d9224a6e 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -143,6 +143,10 @@ class Environment {
   ///  Each argument of `Call` must already have a `StorageLocation`.
   Environment pushCall(const CallExpr *Call) const;
 
+  /// Moves gathered information back into `this` from a `CalleeEnv` created 
via
+  /// `pushCall`.
+  void popCall(const Environment &CalleeEnv);
+
   /// Returns true if and only if the environment is equivalent to `Other`, i.e
   /// the two environments:
   ///  - have the same mappings from declarations to storage locations,

diff  --git a/clang/include/clang/Analysis/FlowSensitive/Transfer.h 
b/clang/include/clang/Analysis/FlowSensitive/Transfer.h
index cbb625487c1eb..8babc5724d46e 100644
--- a/clang/include/clang/Analysis/FlowSensitive/Transfer.h
+++ b/clang/include/clang/Analysis/FlowSensitive/Transfer.h
@@ -22,7 +22,10 @@ namespace dataflow {
 
 struct TransferOptions {
   /// Determines whether to analyze function bodies when present in the
-  /// translation unit.
+  /// translation unit. Note: this is currently only meant to be used for
+  /// inlining of specialized model code, not for context-sensitive analysis of
+  /// arbitrary subject code. In particular, some fundamentals such as 
recursion
+  /// are explicitly unsupported.
   bool ContextSensitive = false;
 };
 

diff  --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index f6f71e34b8927..1bb4e192ef341 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -203,14 +203,6 @@ Environment::Environment(DataflowAnalysisContext &DACtx,
 Environment Environment::pushCall(const CallExpr *Call) const {
   Environment Env(*this);
 
-  // FIXME: Currently this only works if the callee is never a method and the
-  // same callee is never analyzed from multiple separate callsites. To
-  // generalize this, we'll need to store a "context" field (probably a stack 
of
-  // `const CallExpr *`s) in the `Environment`, and then change the
-  // `DataflowAnalysisContext` class to hold a map from contexts to "frames",
-  // where each frame stores its own version of what are currently the
-  // `DeclToLoc`, `ExprToLoc`, and `ThisPointeeLoc` fields.
-
   const auto *FuncDecl = Call->getDirectCallee();
   assert(FuncDecl != nullptr);
   assert(FuncDecl->getBody() != nullptr);
@@ -226,16 +218,40 @@ Environment Environment::pushCall(const CallExpr *Call) 
const {
   for (; ArgIt != ArgEnd; ++ParamIt, ++ArgIt) {
 assert(ParamIt != FuncDecl->param_end());
 
-const VarDecl *Param = *ParamIt;
 const Expr *Arg = *ArgIt;
 auto *ArgLoc = Env.getStorageLocation(*Arg, SkipPast::Reference);
 assert(ArgLoc != nullptr);
-Env.setStorageLocation(*Param, *ArgLoc);
+
+const VarDecl *Param = *ParamIt;
+auto &Loc = Env.createStorageLocation(*Param);
+Env

[clang] 0eaecbb - [clang][dataflow] Handle return statements

2022-08-04 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-08-04T17:42:19Z
New Revision: 0eaecbbc231883b43d3ac761b276d9f505c89c27

URL: 
https://github.com/llvm/llvm-project/commit/0eaecbbc231883b43d3ac761b276d9f505c89c27
DIFF: 
https://github.com/llvm/llvm-project/commit/0eaecbbc231883b43d3ac761b276d9f505c89c27.diff

LOG: [clang][dataflow] Handle return statements

This patch adds a `ReturnLoc` field to the `Environment`, serving a similar to 
the `ThisPointeeLoc` field in the `DataflowAnalysisContext`. It then uses that 
(along with a new `VisitReturnStmt` method in `TransferVisitor`) to handle 
non-`void`-returning functions in context-sensitive analysis.

Reviewed By: ymandel, sgatev

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

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 




diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
index ab60d313f242c..c83d0cbbbdbb3 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
@@ -322,6 +322,7 @@ class DataflowAnalysisContext {
   llvm::DenseMap DeclToLoc;
   llvm::DenseMap ExprToLoc;
 
+  // FIXME: Move this into `Environment`.
   StorageLocation *ThisPointeeLoc = nullptr;
 
   // Null pointer values, keyed by the canonical pointee type.

diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index 1ecac86125a7b..e8a1c2db53b5c 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -222,6 +222,9 @@ class Environment {
   /// in the environment.
   StorageLocation *getThisPointeeStorageLocation() const;
 
+  /// Returns the storage location of the return value or null, if unset.
+  StorageLocation *getReturnStorageLocation() const;
+
   /// Returns a pointer value that represents a null pointer. Calls with
   /// `PointeeType` that are canonically equivalent will return the same 
result.
   PointerValue &getOrCreateNullPointerValue(QualType PointeeType);
@@ -374,6 +377,11 @@ class Environment {
   // `DACtx` is not null and not owned by this object.
   DataflowAnalysisContext *DACtx;
 
+  // In a properly initialized `Environment`, `ReturnLoc` should only be null 
if
+  // its `DeclContext` could not be cast to a `FunctionDecl`.
+  StorageLocation *ReturnLoc = nullptr;
+  // FIXME: Move `ThisPointeeLoc` here from `DataflowAnalysisContext`.
+
   // Maps from program declarations and statements to storage locations that 
are
   // assigned to them. Unlike the maps in `DataflowAnalysisContext`, these
   // include only storage locations that are in scope for a particular basic

diff  --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 4e5b2adee5c99..f4dadbb79b5c9 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -154,9 +154,9 @@ Environment::Environment(DataflowAnalysisContext &DACtx)
 : DACtx(&DACtx), FlowConditionToken(&DACtx.makeFlowConditionToken()) {}
 
 Environment::Environment(const Environment &Other)
-: DACtx(Other.DACtx), DeclToLoc(Other.DeclToLoc),
-  ExprToLoc(Other.ExprToLoc), LocToVal(Other.LocToVal),
-  MemberLocToStruct(Other.MemberLocToStruct),
+: DACtx(Other.DACtx), ReturnLoc(Other.ReturnLoc),
+  DeclToLoc(Other.DeclToLoc), ExprToLoc(Other.ExprToLoc),
+  LocToVal(Other.LocToVal), MemberLocToStruct(Other.MemberLocToStruct),
   FlowConditionToken(&DACtx->forkFlowCondition(*Other.FlowConditionToken)) 
{
 }
 
@@ -179,6 +179,9 @@ Environment::Environment(DataflowAnalysisContext &DACtx,
   if (Value *ParamVal = createValue(ParamDecl->getType()))
 setValue(ParamLoc, *ParamVal);
 }
+
+QualType ReturnType = FuncDecl->getReturnType();
+ReturnLoc = &createStorageLocation(ReturnType);
   }
 
   if (const auto *MethodDecl = dyn_cast(&DeclCtx)) {
@@ -202,10 +205,11 @@ Environment::Environment(DataflowAnalysisContext &DACtx,
 
 Environment Environment::pushCall(const CallExpr *Call) const {
   Environment Env(*this);
+  // FIXME: Support references here.
+  Env.ReturnLoc = Env.getStorageLocation(*Call, SkipPast::Reference);
 
   const auto *FuncDecl = Call->getDirectCallee();
   assert(FuncDecl != nullptr);
-  assert(FuncDecl->getBody() != nullptr);
   // FIXME: In order to allow the callee to re

[clang] 8611a77 - [clang][dataflow] Analyze method bodies

2022-08-04 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-08-04T17:45:47Z
New Revision: 8611a77ee7ee342f5925cba2fa6df023596af9d9

URL: 
https://github.com/llvm/llvm-project/commit/8611a77ee7ee342f5925cba2fa6df023596af9d9
DIFF: 
https://github.com/llvm/llvm-project/commit/8611a77ee7ee342f5925cba2fa6df023596af9d9.diff

LOG: [clang][dataflow] Analyze method bodies

This patch adds the ability to context-sensitively analyze method bodies, by 
moving `ThisPointeeLoc` from `DataflowAnalysisContext` to `Environment`, and 
adding code in `pushCall` to set it.

Reviewed By: ymandel, sgatev, xazax.hun

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

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 




diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
index c83d0cbbbdbb3..e7533794de48b 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysisContext.h
@@ -137,22 +137,6 @@ class DataflowAnalysisContext {
 return It == ExprToLoc.end() ? nullptr : It->second;
   }
 
-  /// Assigns `Loc` as the storage location of the `this` pointee.
-  ///
-  /// Requirements:
-  ///
-  ///  The `this` pointee must not be assigned a storage location.
-  void setThisPointeeStorageLocation(StorageLocation &Loc) {
-assert(ThisPointeeLoc == nullptr);
-ThisPointeeLoc = &Loc;
-  }
-
-  /// Returns the storage location assigned to the `this` pointee or null if 
the
-  /// `this` pointee has no assigned storage location.
-  StorageLocation *getThisPointeeStorageLocation() const {
-return ThisPointeeLoc;
-  }
-
   /// Returns a pointer value that represents a null pointer. Calls with
   /// `PointeeType` that are canonically equivalent will return the same 
result.
   /// A null `PointeeType` can be used for the pointee of `std::nullptr_t`.
@@ -322,9 +306,6 @@ class DataflowAnalysisContext {
   llvm::DenseMap DeclToLoc;
   llvm::DenseMap ExprToLoc;
 
-  // FIXME: Move this into `Environment`.
-  StorageLocation *ThisPointeeLoc = nullptr;
-
   // Null pointer values, keyed by the canonical pointee type.
   //
   // FIXME: The pointer values are indexed by the pointee types which are

diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index e8a1c2db53b5c..fc43b6b43575f 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -380,7 +380,9 @@ class Environment {
   // In a properly initialized `Environment`, `ReturnLoc` should only be null 
if
   // its `DeclContext` could not be cast to a `FunctionDecl`.
   StorageLocation *ReturnLoc = nullptr;
-  // FIXME: Move `ThisPointeeLoc` here from `DataflowAnalysisContext`.
+  // The storage location of the `this` pointee. Should only be null if the
+  // function being analyzed is only a function and not a method.
+  StorageLocation *ThisPointeeLoc = nullptr;
 
   // Maps from program declarations and statements to storage locations that 
are
   // assigned to them. Unlike the maps in `DataflowAnalysisContext`, these

diff  --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index f4dadbb79b5c9..ff27a2a45179b 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -155,8 +155,9 @@ Environment::Environment(DataflowAnalysisContext &DACtx)
 
 Environment::Environment(const Environment &Other)
 : DACtx(Other.DACtx), ReturnLoc(Other.ReturnLoc),
-  DeclToLoc(Other.DeclToLoc), ExprToLoc(Other.ExprToLoc),
-  LocToVal(Other.LocToVal), MemberLocToStruct(Other.MemberLocToStruct),
+  ThisPointeeLoc(Other.ThisPointeeLoc), DeclToLoc(Other.DeclToLoc),
+  ExprToLoc(Other.ExprToLoc), LocToVal(Other.LocToVal),
+  MemberLocToStruct(Other.MemberLocToStruct),
   FlowConditionToken(&DACtx->forkFlowCondition(*Other.FlowConditionToken)) 
{
 }
 
@@ -194,10 +195,9 @@ Environment::Environment(DataflowAnalysisContext &DACtx,
   QualType ThisPointeeType = MethodDecl->getThisObjectType();
   // FIXME: Add support for union types.
   if (!ThisPointeeType->isUnionType()) {
-auto &ThisPointeeLoc = createStorageLocation(ThisPointeeType);
-DACtx.setThisPointeeStorageLocation(ThisPointeeLoc);
+ThisPointeeLoc = &createStorageLocation(ThisPointeeType);
 if (Value *ThisPointeeVal = createValue(ThisPointeeType))
-  

[clang] 000c8fe - [clang][dataflow] Analyze constructor bodies

2022-08-10 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-08-10T14:01:45Z
New Revision: 000c8fef86abb7f056cbea2de99f21dca4b81bf8

URL: 
https://github.com/llvm/llvm-project/commit/000c8fef86abb7f056cbea2de99f21dca4b81bf8
DIFF: 
https://github.com/llvm/llvm-project/commit/000c8fef86abb7f056cbea2de99f21dca4b81bf8.diff

LOG: [clang][dataflow] Analyze constructor bodies

This patch adds the ability to context-sensitively analyze constructor bodies, 
by changing `pushCall` to allow both `CallExpr` and `CXXConstructExpr`, and 
extracting the main context-sensitive logic out of `VisitCallExpr` into a new 
`transferInlineCall` method which is now also called at the end of 
`VisitCXXConstructExpr`.

Reviewed By: ymandel, sgatev, xazax.hun

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

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index 1b154010bf365..8c169005846ef 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -135,7 +135,7 @@ class Environment {
   ///
   /// Requirements:
   ///
-  ///  The callee of `Call` must be a `FunctionDecl` with a body.
+  ///  The callee of `Call` must be a `FunctionDecl`.
   ///
   ///  The body of the callee must not reference globals.
   ///
@@ -143,6 +143,7 @@ class Environment {
   ///
   ///  Each argument of `Call` must already have a `StorageLocation`.
   Environment pushCall(const CallExpr *Call) const;
+  Environment pushCall(const CXXConstructExpr *Call) const;
 
   /// Moves gathered information back into `this` from a `CalleeEnv` created 
via
   /// `pushCall`.
@@ -381,6 +382,12 @@ class Environment {
   StorageLocation &skip(StorageLocation &Loc, SkipPast SP) const;
   const StorageLocation &skip(const StorageLocation &Loc, SkipPast SP) const;
 
+  /// Shared implementation of `pushCall` overloads. Note that unlike
+  /// `pushCall`, this member is invoked on the environment of the callee, not
+  /// of the caller.
+  void pushCallInternal(const FunctionDecl *FuncDecl,
+ArrayRef Args);
+
   // `DACtx` is not null and not owned by this object.
   DataflowAnalysisContext *DACtx;
 

diff  --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 16c83cad9d9e3..e4af68e53e14e 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -207,52 +207,68 @@ Environment::Environment(DataflowAnalysisContext &DACtx,
 
 Environment Environment::pushCall(const CallExpr *Call) const {
   Environment Env(*this);
-  // FIXME: Support references here.
-  Env.ReturnLoc = Env.getStorageLocation(*Call, SkipPast::Reference);
-
-  const auto *FuncDecl = Call->getDirectCallee();
-  assert(FuncDecl != nullptr);
 
-  Env.setDeclCtx(FuncDecl);
-
-  // FIXME: In order to allow the callee to reference globals, we probably need
-  // to call `initGlobalVars` here in some way.
+  // FIXME: Support references here.
+  Env.ReturnLoc = getStorageLocation(*Call, SkipPast::Reference);
 
   if (const auto *MethodCall = dyn_cast(Call)) {
 if (const Expr *Arg = MethodCall->getImplicitObjectArgument()) {
-  Env.ThisPointeeLoc = Env.getStorageLocation(*Arg, SkipPast::Reference);
+  Env.ThisPointeeLoc = getStorageLocation(*Arg, SkipPast::Reference);
 }
   }
 
+  Env.pushCallInternal(Call->getDirectCallee(),
+   llvm::makeArrayRef(Call->getArgs(), 
Call->getNumArgs()));
+
+  return Env;
+}
+
+Environment Environment::pushCall(const CXXConstructExpr *Call) const {
+  Environment Env(*this);
+
+  // FIXME: Support references here.
+  Env.ReturnLoc = getStorageLocation(*Call, SkipPast::Reference);
+
+  Env.ThisPointeeLoc = Env.ReturnLoc;
+
+  Env.pushCallInternal(Call->getConstructor(),
+   llvm::makeArrayRef(Call->getArgs(), 
Call->getNumArgs()));
+
+  return Env;
+}
+
+void Environment::pushCallInternal(const FunctionDecl *FuncDecl,
+   ArrayRef Args) {
+  setDeclCtx(FuncDecl);
+
+  // FIXME: In order to allow the callee to reference globals, we probably need
+  // to call `initGlobalVars` here in some way.
+
   auto ParamIt = FuncDecl->param_begin();
-  auto ArgIt = Call->arg_begin();
-  auto ArgEnd = Call->arg_end();
 
   // FIXME: Parameters don't always map to arguments 1:1; examples include
   // overloaded operators implemented as member functions, and parameter packs.
-  for (; ArgIt != ArgEnd; ++ParamIt, ++ArgI

[clang] 43b298e - [clang][dataflow] Don't crash when caller args are missing storage locations

2022-08-10 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-08-10T17:50:34Z
New Revision: 43b298ea1282f29d448fc0f6ca971bc5fa698355

URL: 
https://github.com/llvm/llvm-project/commit/43b298ea1282f29d448fc0f6ca971bc5fa698355
DIFF: 
https://github.com/llvm/llvm-project/commit/43b298ea1282f29d448fc0f6ca971bc5fa698355.diff

LOG: [clang][dataflow] Don't crash when caller args are missing storage 
locations

This patch modifies `Environment`'s `pushCall` method to pass over arguments 
that are missing storage locations, instead of crashing.

Reviewed By: gribozavr2

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

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index 8c169005846ef..b3bc52a79a2fc 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -140,8 +140,6 @@ class Environment {
   ///  The body of the callee must not reference globals.
   ///
   ///  The arguments of `Call` must map 1:1 to the callee's parameters.
-  ///
-  ///  Each argument of `Call` must already have a `StorageLocation`.
   Environment pushCall(const CallExpr *Call) const;
   Environment pushCall(const CXXConstructExpr *Call) const;
 

diff  --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index e4af68e53e14e..119ef337c6319 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -253,7 +253,8 @@ void Environment::pushCallInternal(const FunctionDecl 
*FuncDecl,
 
 const Expr *Arg = Args[ArgIndex];
 auto *ArgLoc = getStorageLocation(*Arg, SkipPast::Reference);
-assert(ArgLoc != nullptr);
+if (ArgLoc == nullptr)
+  continue;
 
 const VarDecl *Param = *ParamIt;
 auto &Loc = createStorageLocation(*Param);

diff  --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
index af06021abccfd..0e33df3a38008 100644
--- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
@@ -4229,6 +4229,27 @@ TEST(TransferTest, ContextSensitiveReturnArg) {
/*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
 }
 
+TEST(TransferTest, ContextSensitiveReturnInt) {
+  std::string Code = R"(
+int identity(int x) { return x; }
+
+void target() {
+  int y = identity(42);
+  // [[p]]
+}
+  )";
+  runDataflow(Code,
+  [](llvm::ArrayRef<
+ std::pair>>
+ Results,
+ ASTContext &ASTCtx) {
+ASSERT_THAT(Results, ElementsAre(Pair("p", _)));
+// This just tests that the analysis doesn't crash.
+  },
+  {/*.ApplyBuiltinTransfer=*/true,
+   /*.BuiltinTransferOptions=*/{/*.ContextSensitive=*/true}});
+}
+
 TEST(TransferTest, ContextSensitiveMethodLiteral) {
   std::string Code = R"(
 class MyClass {



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 32dcb75 - [clang][dataflow] Move NoopAnalysis from unittests to include

2022-07-22 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-07-22T14:11:32Z
New Revision: 32dcb759c3005d8395b411a9aaa3d90815661d1c

URL: 
https://github.com/llvm/llvm-project/commit/32dcb759c3005d8395b411a9aaa3d90815661d1c
DIFF: 
https://github.com/llvm/llvm-project/commit/32dcb759c3005d8395b411a9aaa3d90815661d1c.diff

LOG: [clang][dataflow] Move NoopAnalysis from unittests to include

This patch moves `Analysis/FlowSensitive/NoopAnalysis.h` from 
`clang/unittests/` to `clang/include/clang/`, so that we can use it for doing 
context-sensitive analysis.

Reviewed By: ymandel, gribozavr2, sgatev

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

Added: 
clang/include/clang/Analysis/FlowSensitive/NoopAnalysis.h

Modified: 
clang/docs/tools/clang-formatted-files.txt
clang/unittests/Analysis/FlowSensitive/ChromiumCheckModelTest.cpp
clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
clang/unittests/Analysis/FlowSensitive/TestingSupportTest.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp
clang/unittests/Analysis/FlowSensitive/TypeErasedDataflowAnalysisTest.cpp

Removed: 
clang/unittests/Analysis/FlowSensitive/NoopAnalysis.h



diff  --git a/clang/docs/tools/clang-formatted-files.txt 
b/clang/docs/tools/clang-formatted-files.txt
index 107d4a7f3a02d..81d0e9522e604 100644
--- a/clang/docs/tools/clang-formatted-files.txt
+++ b/clang/docs/tools/clang-formatted-files.txt
@@ -132,6 +132,7 @@ 
clang/include/clang/Analysis/FlowSensitive/DataflowWorklist.h
 clang/include/clang/Analysis/FlowSensitive/DebugSupport.h
 clang/include/clang/Analysis/FlowSensitive/MapLattice.h
 clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
+clang/include/clang/Analysis/FlowSensitive/NoopAnalysis.h
 clang/include/clang/Analysis/FlowSensitive/NoopLattice.h
 clang/include/clang/Analysis/FlowSensitive/Solver.h
 clang/include/clang/Analysis/FlowSensitive/StorageLocation.h
@@ -634,7 +635,6 @@ 
clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
 clang/unittests/Analysis/FlowSensitive/MapLatticeTest.cpp
 clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
 clang/unittests/Analysis/FlowSensitive/MultiVarConstantPropagationTest.cpp
-clang/unittests/Analysis/FlowSensitive/NoopAnalysis.h
 clang/unittests/Analysis/FlowSensitive/SingleVarConstantPropagationTest.cpp
 clang/unittests/Analysis/FlowSensitive/SolverTest.cpp
 clang/unittests/Analysis/FlowSensitive/TestingSupport.cpp

diff  --git a/clang/unittests/Analysis/FlowSensitive/NoopAnalysis.h 
b/clang/include/clang/Analysis/FlowSensitive/NoopAnalysis.h
similarity index 83%
rename from clang/unittests/Analysis/FlowSensitive/NoopAnalysis.h
rename to clang/include/clang/Analysis/FlowSensitive/NoopAnalysis.h
index 45ed414406372..15b72211fa18c 100644
--- a/clang/unittests/Analysis/FlowSensitive/NoopAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/NoopAnalysis.h
@@ -6,13 +6,12 @@
 //
 
//===--===//
 //
-//  This file defines a NoopAnalysis class that is used by dataflow analysis
-//  tests.
+//  This file defines a NoopAnalysis class that just uses the builtin transfer.
 //
 
//===--===//
 
-#ifndef LLVM_CLANG_UNITTESTS_ANALYSIS_FLOWSENSITIVE_NOOPANALYSIS_H
-#define LLVM_CLANG_UNITTESTS_ANALYSIS_FLOWSENSITIVE_NOOPANALYSIS_H
+#ifndef LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOPANALYSIS_H
+#define LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOPANALYSIS_H
 
 #include "clang/AST/ASTContext.h"
 #include "clang/AST/Stmt.h"
@@ -41,4 +40,4 @@ class NoopAnalysis : public DataflowAnalysis {
 } // namespace dataflow
 } // namespace clang
 
-#endif // LLVM_CLANG_UNITTESTS_ANALYSIS_FLOWSENSITIVE_NOOPANALYSIS_H
+#endif // LLVM_CLANG_ANALYSIS_FLOWSENSITIVE_NOOPANALYSIS_H

diff  --git a/clang/unittests/Analysis/FlowSensitive/ChromiumCheckModelTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/ChromiumCheckModelTest.cpp
index 2be1405465838..103e424755e3c 100644
--- a/clang/unittests/Analysis/FlowSensitive/ChromiumCheckModelTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/ChromiumCheckModelTest.cpp
@@ -8,10 +8,10 @@
 // FIXME: Move this to clang/unittests/Analysis/FlowSensitive/Models.
 
 #include "clang/Analysis/FlowSensitive/Models/ChromiumCheckModel.h"
-#include "NoopAnalysis.h"
 #include "TestingSupport.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Analysis/FlowSensitive/NoopAnalysis.h"
 #include "clang/Tooling/Tooling.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/StringExtras.h"

diff  --git 
a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
index 434bc6b8042ee..ae70131a60a57 100644
--- a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
+++ b/clang/unittests/Analysis/FlowSensiti

[clang] aed1ab8 - [clang][dataflow] Refactor ApplyBuiltinTransfer field out into DataflowAnalysisOptions struct

2022-07-22 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-07-22T15:16:29Z
New Revision: aed1ab8cabac64b59338f5ebadd12a371cb2ee5d

URL: 
https://github.com/llvm/llvm-project/commit/aed1ab8cabac64b59338f5ebadd12a371cb2ee5d
DIFF: 
https://github.com/llvm/llvm-project/commit/aed1ab8cabac64b59338f5ebadd12a371cb2ee5d.diff

LOG: [clang][dataflow] Refactor ApplyBuiltinTransfer field out into 
DataflowAnalysisOptions struct

Depends On D130304

This patch pulls the `ApplyBuiltinTransfer` from the 
`TypeErasedDataflowAnalysis` class into a new `DataflowAnalysisOptions` struct, 
to allow us to add additional options later without breaking existing code.

Reviewed By: gribozavr2, sgatev

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

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
clang/include/clang/Analysis/FlowSensitive/NoopAnalysis.h
clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
index 40ac95b3abddb..ef8f7a51496c9 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
@@ -63,9 +63,15 @@ class DataflowAnalysis : public TypeErasedDataflowAnalysis {
   using Lattice = LatticeT;
 
   explicit DataflowAnalysis(ASTContext &Context) : Context(Context) {}
+
+  /// Deprecated. Use the `DataflowAnalysisOptions` constructor instead.
   explicit DataflowAnalysis(ASTContext &Context, bool ApplyBuiltinTransfer)
   : TypeErasedDataflowAnalysis(ApplyBuiltinTransfer), Context(Context) {}
 
+  explicit DataflowAnalysis(ASTContext &Context,
+DataflowAnalysisOptions Options)
+  : TypeErasedDataflowAnalysis(Options), Context(Context) {}
+
   ASTContext &getASTContext() final { return Context; }
 
   TypeErasedLattice typeErasedInitialElement() final {

diff  --git a/clang/include/clang/Analysis/FlowSensitive/NoopAnalysis.h 
b/clang/include/clang/Analysis/FlowSensitive/NoopAnalysis.h
index 15b72211fa18c..4f05f5f4554bb 100644
--- a/clang/include/clang/Analysis/FlowSensitive/NoopAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/NoopAnalysis.h
@@ -24,13 +24,17 @@ namespace dataflow {
 
 class NoopAnalysis : public DataflowAnalysis {
 public:
+  /// Deprecated. Use the `DataflowAnalysisOptions` constructor instead.
+  NoopAnalysis(ASTContext &Context, bool ApplyBuiltinTransfer)
+  : DataflowAnalysis(Context,
+ApplyBuiltinTransfer) {}
+
   /// `ApplyBuiltinTransfer` controls whether to run the built-in transfer
   /// functions that model memory during the analysis. Their results are not
   /// used by `NoopAnalysis`, but tests that need to inspect the environment
   /// should enable them.
-  NoopAnalysis(ASTContext &Context, bool ApplyBuiltinTransfer)
-  : DataflowAnalysis(Context,
-ApplyBuiltinTransfer) {}
+  NoopAnalysis(ASTContext &Context, DataflowAnalysisOptions Options)
+  : DataflowAnalysis(Context, Options) {}
 
   static NoopLattice initialElement() { return {}; }
 

diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h 
b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
index 5e168194064f4..b043062459e4e 100644
--- a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
@@ -30,6 +30,14 @@
 namespace clang {
 namespace dataflow {
 
+struct DataflowAnalysisOptions {
+  /// Determines whether to apply the built-in transfer functions.
+  // FIXME: Remove this option once the framework supports composing analyses
+  // (at which point the built-in transfer functions can be simply a standalone
+  // analysis).
+  bool ApplyBuiltinTransfer = true;
+};
+
 /// Type-erased lattice element container.
 ///
 /// Requirements:
@@ -42,16 +50,17 @@ struct TypeErasedLattice {
 
 /// Type-erased base class for dataflow analyses built on a single lattice 
type.
 class TypeErasedDataflowAnalysis : public Environment::ValueModel {
-  /// Determines whether to apply the built-in transfer functions.
-  // FIXME: Remove this option once the framework supports composing analyses
-  // (at which point the built-in transfer functions can be simply a standalone
-  // analysis).
-  bool ApplyBuiltinTransfer;
+  DataflowAnalysisOptions Options;
 
 public:
-  TypeErasedDataflowAnalysis() : ApplyBuiltinTransfer(true) {}
+  TypeErasedDataflowAnalysis() : Options({}) {}
+
+  /// Deprecated. Use the `DataflowAnalysisOptions` constructor instead.
   TypeErasedDataflowAnalysis(bool ApplyBuiltinTransfer)
-  : ApplyBuiltinTransfer(ApplyBuiltinTransfer) {}
+  : Options({App

[clang] b3f1a6b - [clang][dataflow] Encode options using llvm::Optional

2022-08-12 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-08-12T16:29:41Z
New Revision: b3f1a6bf1080fb67cb1760a924a56d38d51211aa

URL: 
https://github.com/llvm/llvm-project/commit/b3f1a6bf1080fb67cb1760a924a56d38d51211aa
DIFF: 
https://github.com/llvm/llvm-project/commit/b3f1a6bf1080fb67cb1760a924a56d38d51211aa.diff

LOG: [clang][dataflow] Encode options using llvm::Optional

This patch restructures `DataflowAnalysisOptions` and `TransferOptions` to use 
`llvm::Optional`, in preparation for adding more sub-options to the 
`ContextSensitiveOptions` struct introduced here.

Reviewed By: sgatev, xazax.hun

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

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
clang/include/clang/Analysis/FlowSensitive/Transfer.h
clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/lib/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
index 99e16f8255446..4c785b21526da 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
@@ -65,8 +65,9 @@ class DataflowAnalysis : public TypeErasedDataflowAnalysis {
 
   /// Deprecated. Use the `DataflowAnalysisOptions` constructor instead.
   explicit DataflowAnalysis(ASTContext &Context, bool ApplyBuiltinTransfer)
-  : DataflowAnalysis(Context, DataflowAnalysisOptions{ApplyBuiltinTransfer,
-  TransferOptions{}}) 
{}
+  : DataflowAnalysis(Context, {ApplyBuiltinTransfer
+   ? TransferOptions{}
+   : llvm::Optional()}) {}
 
   explicit DataflowAnalysis(ASTContext &Context,
 DataflowAnalysisOptions Options)

diff  --git a/clang/include/clang/Analysis/FlowSensitive/Transfer.h 
b/clang/include/clang/Analysis/FlowSensitive/Transfer.h
index 8babc5724d46e..93afcc284e1af 100644
--- a/clang/include/clang/Analysis/FlowSensitive/Transfer.h
+++ b/clang/include/clang/Analysis/FlowSensitive/Transfer.h
@@ -16,17 +16,19 @@
 
 #include "clang/AST/Stmt.h"
 #include "clang/Analysis/FlowSensitive/DataflowEnvironment.h"
+#include "llvm/ADT/Optional.h"
 
 namespace clang {
 namespace dataflow {
 
+struct ContextSensitiveOptions {};
+
 struct TransferOptions {
-  /// Determines whether to analyze function bodies when present in the
-  /// translation unit. Note: this is currently only meant to be used for
-  /// inlining of specialized model code, not for context-sensitive analysis of
-  /// arbitrary subject code. In particular, some fundamentals such as 
recursion
-  /// are explicitly unsupported.
-  bool ContextSensitive = false;
+  /// Options for analyzing function bodies when present in the translation
+  /// unit, or empty to disable context-sensitive analysis. Note that this is
+  /// fundamentally limited: some constructs, such as recursion, are explicitly
+  /// unsupported.
+  llvm::Optional ContextSensitiveOpts;
 };
 
 /// Maps statements to the environments of basic blocks that contain them.

diff  --git 
a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h 
b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
index 3bd1c8e12e9b2..58acda7e6389d 100644
--- a/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
+++ b/clang/include/clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h
@@ -32,14 +32,11 @@ namespace clang {
 namespace dataflow {
 
 struct DataflowAnalysisOptions {
-  /// Determines whether to apply the built-in transfer functions.
+  /// Options for the built-in transfer functions, or empty to not apply them.
   // FIXME: Remove this option once the framework supports composing analyses
   // (at which point the built-in transfer functions can be simply a standalone
   // analysis).
-  bool ApplyBuiltinTransfer = true;
-
-  /// Only has an effect if `ApplyBuiltinTransfer` is true.
-  TransferOptions BuiltinTransferOptions;
+  llvm::Optional BuiltinTransferOpts = TransferOptions{};
 };
 
 /// Type-erased lattice element container.
@@ -87,13 +84,11 @@ class TypeErasedDataflowAnalysis : public 
Environment::ValueModel {
   virtual void transferTypeErased(const Stmt *, TypeErasedLattice &,
   Environment &) = 0;
 
-  /// Determines whether to apply the built-in transfer functions, which model
-  /// the heap and stack in the `Environment`.
-  bool applyBuiltinTransfer() const { return Options.ApplyBuiltinTransfer; }
-
-  /// Returns the options to be passed to the built-in transfer functions.
-  Transfe

[clang] 2efc8f8 - [clang][dataflow] Add an option for context-sensitive depth

2022-08-15 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-08-15T19:58:40Z
New Revision: 2efc8f8d6561421c3f47de2f27a365ddfb734425

URL: 
https://github.com/llvm/llvm-project/commit/2efc8f8d6561421c3f47de2f27a365ddfb734425
DIFF: 
https://github.com/llvm/llvm-project/commit/2efc8f8d6561421c3f47de2f27a365ddfb734425.diff

LOG: [clang][dataflow] Add an option for context-sensitive depth

This patch adds a `Depth` field (default value 2) to `ContextSensitiveOptions`, 
allowing context-sensitive analysis of functions that call other functions. 
This also requires replacing the `DeclCtx` field on `Environment` with a 
`CallString` field that contains a vector of decl contexts, to ensure that the 
analysis doesn't try to analyze recursive or mutually recursive calls (which 
would result in a crash, due to the way we handle `StorageLocation`s).

Reviewed By: xazax.hun

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

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
clang/include/clang/Analysis/FlowSensitive/Transfer.h
clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
clang/lib/Analysis/FlowSensitive/Transfer.cpp
clang/unittests/Analysis/FlowSensitive/TransferTest.cpp

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h 
b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
index 5b29915e368ed..6955bcf2fb4ca 100644
--- a/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
+++ b/clang/include/clang/Analysis/FlowSensitive/DataflowEnvironment.h
@@ -348,10 +348,12 @@ class Environment {
 
   /// Returns the `DeclContext` of the block being analysed, if any. Otherwise,
   /// returns null.
-  const DeclContext *getDeclCtx() { return DeclCtx; }
+  const DeclContext *getDeclCtx() { return CallStack.back(); }
 
-  /// Sets the `DeclContext` of the block being analysed.
-  void setDeclCtx(const DeclContext *Ctx) { DeclCtx = Ctx; }
+  /// Returns whether this `Environment` can be extended to analyze the given
+  /// `Callee` (i.e. if `pushCall` can be used), with recursion disallowed and 
a
+  /// given `MaxDepth`.
+  bool canDescend(unsigned MaxDepth, const DeclContext *Callee) const;
 
   /// Returns the `ControlFlowContext` registered for `F`, if any. Otherwise,
   /// returns null.
@@ -390,7 +392,7 @@ class Environment {
   DataflowAnalysisContext *DACtx;
 
   // `DeclContext` of the block being analysed if provided.
-  const DeclContext *DeclCtx = nullptr;
+  std::vector CallStack;
 
   // In a properly initialized `Environment`, `ReturnLoc` should only be null 
if
   // its `DeclContext` could not be cast to a `FunctionDecl`.

diff  --git a/clang/include/clang/Analysis/FlowSensitive/Transfer.h 
b/clang/include/clang/Analysis/FlowSensitive/Transfer.h
index 93afcc284e1af..fa05013bb7208 100644
--- a/clang/include/clang/Analysis/FlowSensitive/Transfer.h
+++ b/clang/include/clang/Analysis/FlowSensitive/Transfer.h
@@ -21,7 +21,11 @@
 namespace clang {
 namespace dataflow {
 
-struct ContextSensitiveOptions {};
+struct ContextSensitiveOptions {
+  /// The maximum depth to analyze. A value of zero is equivalent to disabling
+  /// context-sensitive analysis entirely.
+  unsigned Depth = 2;
+};
 
 struct TransferOptions {
   /// Options for analyzing function bodies when present in the translation

diff  --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp 
b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 119ef337c6319..f64ade34bcb82 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -154,10 +154,10 @@ Environment::Environment(DataflowAnalysisContext &DACtx)
 : DACtx(&DACtx), FlowConditionToken(&DACtx.makeFlowConditionToken()) {}
 
 Environment::Environment(const Environment &Other)
-: DACtx(Other.DACtx), DeclCtx(Other.DeclCtx), ReturnLoc(Other.ReturnLoc),
-  ThisPointeeLoc(Other.ThisPointeeLoc), DeclToLoc(Other.DeclToLoc),
-  ExprToLoc(Other.ExprToLoc), LocToVal(Other.LocToVal),
-  MemberLocToStruct(Other.MemberLocToStruct),
+: DACtx(Other.DACtx), CallStack(Other.CallStack),
+  ReturnLoc(Other.ReturnLoc), ThisPointeeLoc(Other.ThisPointeeLoc),
+  DeclToLoc(Other.DeclToLoc), ExprToLoc(Other.ExprToLoc),
+  LocToVal(Other.LocToVal), MemberLocToStruct(Other.MemberLocToStruct),
   FlowConditionToken(&DACtx->forkFlowCondition(*Other.FlowConditionToken)) 
{
 }
 
@@ -168,11 +168,11 @@ Environment &Environment::operator=(const Environment 
&Other) {
 }
 
 Environment::Environment(DataflowAnalysisContext &DACtx,
- const DeclContext &DeclCtxArg)
+ const DeclContext &DeclCtx)
 : Environment(DACtx) {
-  setDeclCtx(&DeclCtxArg);
+  CallStack.push_back(&DeclCtx);
 
-  if (const auto *FuncDecl = dyn_cast(DeclCtx)) {
+  if (const auto *FuncDecl = dyn_

[clang] 4eecd19 - [clang][dataflow] Allow MatchSwitch to return a value

2022-06-24 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-06-24T13:32:47Z
New Revision: 4eecd194b073492a309b87c8f60da6614bba9153

URL: 
https://github.com/llvm/llvm-project/commit/4eecd194b073492a309b87c8f60da6614bba9153
DIFF: 
https://github.com/llvm/llvm-project/commit/4eecd194b073492a309b87c8f60da6614bba9153.diff

LOG: [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

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h 
b/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
index 2aaaf78f9cd0e..77271bda188d5 100644
--- a/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
+++ b/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
@@ -46,8 +46,8 @@ template  struct TransferState {
 
 /// Matches against `Stmt` and, based on its structure, dispatches to an
 /// appropriate handler.
-template 
-using MatchSwitch = std::function;
+template 
+using MatchSwitch = std::function;
 
 /// Collects cases of a "match switch": a collection of matchers paired with
 /// callbacks, which together define a switch that can be applied to a
@@ -68,7 +68,7 @@ using MatchSwitch = std::function;
 /// .Build();
 /// }
 /// \endcode
-template  class MatchSwitchBuilder {
+template  class MatchSwitchBuilder {
 public:
   /// Registers an action that will be triggered by the match of a pattern
   /// against the input statement.
@@ -79,24 +79,24 @@ template  class MatchSwitchBuilder {
   template 
   MatchSwitchBuilder &&
   CaseOf(ast_matchers::internal::Matcher M,
- std::function
+ std::function
  A) && {
 Matchers.push_back(std::move(M));
 Actions.push_back(
 [A = std::move(A)](const Stmt *Stmt,
const ast_matchers::MatchFinder::MatchResult &R,
-   State &S) { A(cast(Stmt), R, S); });
+   State &S) { return A(cast(Stmt), R, S); });
 return std::move(*this);
   }
 
-  MatchSwitch Build() && {
+  MatchSwitch Build() && {
 return [Matcher = BuildMatcher(), Actions = std::move(Actions)](
-   const Stmt &Stmt, ASTContext &Context, State &S) {
+   const Stmt &Stmt, ASTContext &Context, State &S) -> Result {
   auto Results = ast_matchers::matchDynamic(Matcher, Stmt, Context);
   if (Results.empty())
-return;
+return {};
   // Look through the map for the first binding of the form "TagN..." use
   // that to select the action.
   for (const auto &Element : Results[0].getMap()) {
@@ -104,12 +104,12 @@ template  class MatchSwitchBuilder {
 size_t Index = 0;
 if (ID.consume_front("Tag") && !ID.getAsInteger(10, Index) &&
 Index < Actions.size()) {
-  Actions[Index](
+  return Actions[Index](
   &Stmt,
   ast_matchers::MatchFinder::MatchResult(Results[0], &Context), S);
-  return;
 }
   }
+  return {};
 };
   }
 
@@ -142,7 +142,7 @@ template  class MatchSwitchBuilder {
   }
 
   std::vector Matchers;
-  std::vector>
   Actions;
 };

diff  --git a/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
index bd2ae0e96c01e..98319760fd206 100644
--- a/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
@@ -204,3 +204,29 @@ TEST_F(MatchSwitchTest, Neither) {
   RunDataflow(Code,
   UnorderedElementsAre(Pair("p", Holds(BooleanLattice(false);
 }
+
+TEST_F(MatchSwitchTest, ReturnNonVoid) {
+  using namespace ast_matchers;
+
+  auto Unit =
+  tooling::buildASTFromCode("void f() { int x = 42; }", "input.cc",
+std::make_shared());
+  auto &Context = Unit->getASTContext();
+  const auto *S =
+  selectFirst(
+  "f",
+  match(functionDecl(isDefinition(), hasName("f")).bind("f"), Context))
+  ->getBody();
+
+  MatchSwitch> Switch =
+  MatchSwitchBuilder>()
+  .CaseOf(stmt(),
+[](const Stmt *, const MatchFinder::MatchResult &,
+   const int &State) -> std::vector {
+  return {1, State, 3};
+})
+  .Build();
+  std::vector Actual = Switch(*S, Context, 7);
+  

[clang] 7b326b9 - Revert "[clang][dataflow] Allow MatchSwitch to return a value"

2022-06-24 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-06-24T13:52:11Z
New Revision: 7b326b946a38f58c9b3fdfeee09678bc4bf91292

URL: 
https://github.com/llvm/llvm-project/commit/7b326b946a38f58c9b3fdfeee09678bc4bf91292
DIFF: 
https://github.com/llvm/llvm-project/commit/7b326b946a38f58c9b3fdfeee09678bc4bf91292.diff

LOG: Revert "[clang][dataflow] Allow MatchSwitch to return a value"

This reverts commit 4eecd194b073492a309b87c8f60da6614bba9153.

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h 
b/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
index 77271bda188d5..2aaaf78f9cd0e 100644
--- a/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
+++ b/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
@@ -46,8 +46,8 @@ template  struct TransferState {
 
 /// Matches against `Stmt` and, based on its structure, dispatches to an
 /// appropriate handler.
-template 
-using MatchSwitch = std::function;
+template 
+using MatchSwitch = std::function;
 
 /// Collects cases of a "match switch": a collection of matchers paired with
 /// callbacks, which together define a switch that can be applied to a
@@ -68,7 +68,7 @@ using MatchSwitch = std::function;
 /// .Build();
 /// }
 /// \endcode
-template  class MatchSwitchBuilder {
+template  class MatchSwitchBuilder {
 public:
   /// Registers an action that will be triggered by the match of a pattern
   /// against the input statement.
@@ -79,24 +79,24 @@ template  class 
MatchSwitchBuilder {
   template 
   MatchSwitchBuilder &&
   CaseOf(ast_matchers::internal::Matcher M,
- std::function
+ std::function
  A) && {
 Matchers.push_back(std::move(M));
 Actions.push_back(
 [A = std::move(A)](const Stmt *Stmt,
const ast_matchers::MatchFinder::MatchResult &R,
-   State &S) { return A(cast(Stmt), R, S); });
+   State &S) { A(cast(Stmt), R, S); });
 return std::move(*this);
   }
 
-  MatchSwitch Build() && {
+  MatchSwitch Build() && {
 return [Matcher = BuildMatcher(), Actions = std::move(Actions)](
-   const Stmt &Stmt, ASTContext &Context, State &S) -> Result {
+   const Stmt &Stmt, ASTContext &Context, State &S) {
   auto Results = ast_matchers::matchDynamic(Matcher, Stmt, Context);
   if (Results.empty())
-return {};
+return;
   // Look through the map for the first binding of the form "TagN..." use
   // that to select the action.
   for (const auto &Element : Results[0].getMap()) {
@@ -104,12 +104,12 @@ template  class 
MatchSwitchBuilder {
 size_t Index = 0;
 if (ID.consume_front("Tag") && !ID.getAsInteger(10, Index) &&
 Index < Actions.size()) {
-  return Actions[Index](
+  Actions[Index](
   &Stmt,
   ast_matchers::MatchFinder::MatchResult(Results[0], &Context), S);
+  return;
 }
   }
-  return {};
 };
   }
 
@@ -142,7 +142,7 @@ template  class 
MatchSwitchBuilder {
   }
 
   std::vector Matchers;
-  std::vector>
   Actions;
 };

diff  --git a/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
index 98319760fd206..bd2ae0e96c01e 100644
--- a/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
@@ -204,29 +204,3 @@ TEST_F(MatchSwitchTest, Neither) {
   RunDataflow(Code,
   UnorderedElementsAre(Pair("p", Holds(BooleanLattice(false);
 }
-
-TEST_F(MatchSwitchTest, ReturnNonVoid) {
-  using namespace ast_matchers;
-
-  auto Unit =
-  tooling::buildASTFromCode("void f() { int x = 42; }", "input.cc",
-std::make_shared());
-  auto &Context = Unit->getASTContext();
-  const auto *S =
-  selectFirst(
-  "f",
-  match(functionDecl(isDefinition(), hasName("f")).bind("f"), Context))
-  ->getBody();
-
-  MatchSwitch> Switch =
-  MatchSwitchBuilder>()
-  .CaseOf(stmt(),
-[](const Stmt *, const MatchFinder::MatchResult &,
-   const int &State) -> std::vector {
-  return {1, State, 3};
-})
-  .Build();
-  std::vector Actual = Switch(*S, Context, 7);
-  std::vector Expected{1, 7, 3};
-  EXPECT_EQ(Actual, Expected);
-}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 8c278a2 - [clang][dataflow] Allow MatchSwitch to return a value

2022-06-24 Thread Sam Estep via cfe-commits

Author: Sam Estep
Date: 2022-06-24T14:38:00Z
New Revision: 8c278a27811ccf9d7a32c0a460b08069c4b3b7b5

URL: 
https://github.com/llvm/llvm-project/commit/8c278a27811ccf9d7a32c0a460b08069c4b3b7b5
DIFF: 
https://github.com/llvm/llvm-project/commit/8c278a27811ccf9d7a32c0a460b08069c4b3b7b5.diff

LOG: [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

Added: 


Modified: 
clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp

Removed: 




diff  --git a/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h 
b/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
index 2aaaf78f9cd0e..927aec7df5731 100644
--- a/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
+++ b/clang/include/clang/Analysis/FlowSensitive/MatchSwitch.h
@@ -46,8 +46,8 @@ template  struct TransferState {
 
 /// Matches against `Stmt` and, based on its structure, dispatches to an
 /// appropriate handler.
-template 
-using MatchSwitch = std::function;
+template 
+using MatchSwitch = std::function;
 
 /// Collects cases of a "match switch": a collection of matchers paired with
 /// callbacks, which together define a switch that can be applied to a
@@ -68,7 +68,7 @@ using MatchSwitch = std::function;
 /// .Build();
 /// }
 /// \endcode
-template  class MatchSwitchBuilder {
+template  class MatchSwitchBuilder {
 public:
   /// Registers an action that will be triggered by the match of a pattern
   /// against the input statement.
@@ -79,24 +79,24 @@ template  class MatchSwitchBuilder {
   template 
   MatchSwitchBuilder &&
   CaseOf(ast_matchers::internal::Matcher M,
- std::function
+ std::function
  A) && {
 Matchers.push_back(std::move(M));
 Actions.push_back(
 [A = std::move(A)](const Stmt *Stmt,
const ast_matchers::MatchFinder::MatchResult &R,
-   State &S) { A(cast(Stmt), R, S); });
+   State &S) { return A(cast(Stmt), R, S); });
 return std::move(*this);
   }
 
-  MatchSwitch Build() && {
+  MatchSwitch Build() && {
 return [Matcher = BuildMatcher(), Actions = std::move(Actions)](
-   const Stmt &Stmt, ASTContext &Context, State &S) {
+   const Stmt &Stmt, ASTContext &Context, State &S) -> Result {
   auto Results = ast_matchers::matchDynamic(Matcher, Stmt, Context);
   if (Results.empty())
-return;
+return Result();
   // Look through the map for the first binding of the form "TagN..." use
   // that to select the action.
   for (const auto &Element : Results[0].getMap()) {
@@ -104,12 +104,12 @@ template  class MatchSwitchBuilder {
 size_t Index = 0;
 if (ID.consume_front("Tag") && !ID.getAsInteger(10, Index) &&
 Index < Actions.size()) {
-  Actions[Index](
+  return Actions[Index](
   &Stmt,
   ast_matchers::MatchFinder::MatchResult(Results[0], &Context), S);
-  return;
 }
   }
+  return Result();
 };
   }
 
@@ -142,7 +142,7 @@ template  class MatchSwitchBuilder {
   }
 
   std::vector Matchers;
-  std::vector>
   Actions;
 };

diff  --git a/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp 
b/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
index bd2ae0e96c01e..98319760fd206 100644
--- a/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/MatchSwitchTest.cpp
@@ -204,3 +204,29 @@ TEST_F(MatchSwitchTest, Neither) {
   RunDataflow(Code,
   UnorderedElementsAre(Pair("p", Holds(BooleanLattice(false);
 }
+
+TEST_F(MatchSwitchTest, ReturnNonVoid) {
+  using namespace ast_matchers;
+
+  auto Unit =
+  tooling::buildASTFromCode("void f() { int x = 42; }", "input.cc",
+std::make_shared());
+  auto &Context = Unit->getASTContext();
+  const auto *S =
+  selectFirst(
+  "f",
+  match(functionDecl(isDefinition(), hasName("f")).bind("f"), Context))
+  ->getBody();
+
+  MatchSwitch> Switch =
+  MatchSwitchBuilder>()
+  .CaseOf(stmt(),
+[](const Stmt *, const MatchFinder::MatchResult &,
+   const int &State) -> std::vector {
+  return {1, State, 3};
+})
+  .Build();
+  std::vector Actual = Switch(*S, Context, 7);
+  std::vector Expected{1, 7, 3};
+  EXPECT_EQ(Actual, Expected);
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailma