[PATCH] D128352: [clang][dataflow] Use diagnosis API in optional checker

Sam Estep via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 28 11:17:07 PDT 2022


samestep updated this revision to Diff 440702.
samestep added a comment.
Herald added a project: clang.

- Merge branch 'diagnose-api' into optional-check-diagnose
- Use the updated API


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128352/new/

https://reviews.llvm.org/D128352

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


Index: clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
===================================================================
--- clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
+++ clang/include/clang/Analysis/FlowSensitive/DataflowAnalysis.h
@@ -113,10 +113,21 @@
 template <typename AnalysisT>
 llvm::Expected<std::vector<
     llvm::Optional<DataflowAnalysisState<typename AnalysisT::Lattice>>>>
-runDataflowAnalysis(const ControlFlowContext &CFCtx, AnalysisT &Analysis,
-                    const Environment &InitEnv) {
-  auto TypeErasedBlockStates =
-      runTypeErasedDataflowAnalysis(CFCtx, Analysis, InitEnv);
+runDataflowAnalysis(
+    const ControlFlowContext &CFCtx, AnalysisT &Analysis,
+    const Environment &InitEnv,
+    std::function<void(const Stmt *, const DataflowAnalysisState<
+                                         typename AnalysisT::Lattice> &)>
+        PostVisitStmt = nullptr) {
+  auto TypeErasedBlockStates = runTypeErasedDataflowAnalysis(
+      CFCtx, Analysis, InitEnv,
+      [&PostVisitStmt](const Stmt *Stmt,
+                       const TypeErasedDataflowAnalysisState &State) {
+        auto *Lattice =
+            llvm::any_cast<typename AnalysisT::Lattice>(&State.Lattice.Value);
+        PostVisitStmt(Stmt, DataflowAnalysisState<typename AnalysisT::Lattice>{
+                                *Lattice, State.Env});
+      });
   if (!TypeErasedBlockStates)
     return TypeErasedBlockStates.takeError();
 
Index: clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
+++ clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.cpp
@@ -32,12 +32,13 @@
 namespace bugprone {
 using ast_matchers::MatchFinder;
 using dataflow::SourceLocationsLattice;
+using dataflow::UncheckedOptionalAccessDiagnosis;
 using dataflow::UncheckedOptionalAccessModel;
 using llvm::Optional;
 
 static constexpr llvm::StringLiteral FuncID("fun");
 
-static Optional<SourceLocationsLattice>
+static Optional<std::vector<SourceLocation>>
 analyzeFunction(const FunctionDecl &FuncDecl, ASTContext &ASTCtx) {
   using dataflow::ControlFlowContext;
   using dataflow::DataflowAnalysisState;
@@ -52,23 +53,23 @@
       std::make_unique<dataflow::WatchedLiteralsSolver>());
   dataflow::Environment Env(AnalysisContext, FuncDecl);
   UncheckedOptionalAccessModel Analysis(ASTCtx);
+  UncheckedOptionalAccessDiagnosis Diagnosis(ASTCtx);
+  std::vector<SourceLocation> Diagnostics;
   Expected<std::vector<Optional<DataflowAnalysisState<SourceLocationsLattice>>>>
-      BlockToOutputState =
-          dataflow::runDataflowAnalysis(*Context, Analysis, Env);
+      BlockToOutputState = dataflow::runDataflowAnalysis(
+          *Context, Analysis, Env,
+          [&Diagnosis,
+           &Diagnostics](const Stmt *Stmt,
+                         const DataflowAnalysisState<SourceLocationsLattice>
+                             &State) mutable {
+            auto StmtDiagnostics = Diagnosis.diagnose(Stmt, State.Env);
+            std::move(StmtDiagnostics.begin(), StmtDiagnostics.end(),
+                      std::back_inserter(Diagnostics));
+          });
   if (!BlockToOutputState)
     return llvm::None;
-  assert(Context->getCFG().getExit().getBlockID() < BlockToOutputState->size());
 
-  const Optional<DataflowAnalysisState<SourceLocationsLattice>>
-      &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 @@
   if (FuncDecl->isTemplated())
     return;
 
-  if (Optional<SourceLocationsLattice> Errors =
+  if (Optional<std::vector<SourceLocation>> Errors =
           analyzeFunction(*FuncDecl, *Result.Context))
-    for (const SourceLocation &Loc : Errors->getSourceLocations())
+    for (const SourceLocation &Loc : *Errors)
       diag(Loc, "unchecked access to optional value");
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D128352.440702.patch
Type: text/x-patch
Size: 4376 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220628/e88513ba/attachment.bin>


More information about the cfe-commits mailing list