[clang] 87c51e2 - Run PreStmt/PostStmt checker for GCCAsmStmt (#95409)

via cfe-commits cfe-commits at lists.llvm.org
Wed Jul 10 05:15:57 PDT 2024


Author: T-Gruber
Date: 2024-07-10T14:15:53+02:00
New Revision: 87c51e2af006b96d928d55b077c8bb510c4b6e33

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

LOG: Run PreStmt/PostStmt checker for GCCAsmStmt (#95409)

Fixes #94940

Run PreStmt and PostStmt checker for GCCAsmStmt.
Unittest to validate that corresponding callback functions are triggered.

Added: 
    clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp

Modified: 
    clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
    clang/unittests/StaticAnalyzer/CMakeLists.txt

Removed: 
    


################################################################################
diff  --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 977deb3182deb..19c85352a6144 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -2057,11 +2057,17 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
       llvm_unreachable("Support for MatrixSubscriptExpr is not implemented.");
       break;
 
-    case Stmt::GCCAsmStmtClass:
+    case Stmt::GCCAsmStmtClass: {
       Bldr.takeNodes(Pred);
-      VisitGCCAsmStmt(cast<GCCAsmStmt>(S), Pred, Dst);
+      ExplodedNodeSet PreVisit;
+      getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+      ExplodedNodeSet PostVisit;
+      for (ExplodedNode *const N : PreVisit)
+        VisitGCCAsmStmt(cast<GCCAsmStmt>(S), N, PostVisit);
+      getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
       Bldr.addNodes(Dst);
       break;
+    }
 
     case Stmt::MSAsmStmtClass:
       Bldr.takeNodes(Pred);

diff  --git a/clang/unittests/StaticAnalyzer/CMakeLists.txt b/clang/unittests/StaticAnalyzer/CMakeLists.txt
index dcc557b44fb31..5ef72cfaea401 100644
--- a/clang/unittests/StaticAnalyzer/CMakeLists.txt
+++ b/clang/unittests/StaticAnalyzer/CMakeLists.txt
@@ -10,6 +10,7 @@ add_clang_unittest(StaticAnalysisTests
   CallDescriptionTest.cpp
   CallEventTest.cpp
   ConflictingEvalCallsTest.cpp
+  ExprEngineVisitTest.cpp
   FalsePositiveRefutationBRVisitorTest.cpp
   IsCLibraryFunctionTest.cpp
   MemRegionDescriptiveNameTest.cpp

diff  --git a/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp b/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
new file mode 100644
index 0000000000000..a8579f9d0f90c
--- /dev/null
+++ b/clang/unittests/StaticAnalyzer/ExprEngineVisitTest.cpp
@@ -0,0 +1,87 @@
+//===- ExprEngineVisitTest.cpp --------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "CheckerRegistration.h"
+#include "clang/AST/Stmt.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
+#include "clang/StaticAnalyzer/Core/Checker.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace ento;
+
+namespace {
+
+void emitErrorReport(CheckerContext &C, const BugType &Bug,
+                     const std::string &Desc) {
+  if (ExplodedNode *Node = C.generateNonFatalErrorNode(C.getState())) {
+    auto Report = std::make_unique<PathSensitiveBugReport>(Bug, Desc, Node);
+    C.emitReport(std::move(Report));
+  }
+}
+
+#define CREATE_EXPR_ENGINE_CHECKER(CHECKER_NAME, CALLBACK, STMT_TYPE,          \
+                                   BUG_NAME)                                   \
+  class CHECKER_NAME : public Checker<check::CALLBACK<STMT_TYPE>> {            \
+  public:                                                                      \
+    void check##CALLBACK(const STMT_TYPE *ASM, CheckerContext &C) const {      \
+      emitErrorReport(C, Bug, "check" #CALLBACK "<" #STMT_TYPE ">");           \
+    }                                                                          \
+                                                                               \
+  private:                                                                     \
+    const BugType Bug{this, BUG_NAME};                                         \
+  };
+
+CREATE_EXPR_ENGINE_CHECKER(ExprEngineVisitPreChecker, PreStmt, GCCAsmStmt,
+                           "GCCAsmStmtBug")
+CREATE_EXPR_ENGINE_CHECKER(ExprEngineVisitPostChecker, PostStmt, GCCAsmStmt,
+                           "GCCAsmStmtBug")
+
+void addExprEngineVisitPreChecker(AnalysisASTConsumer &AnalysisConsumer,
+                                  AnalyzerOptions &AnOpts) {
+  AnOpts.CheckersAndPackages = {{"ExprEngineVisitPreChecker", true}};
+  AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
+    Registry.addChecker<ExprEngineVisitPreChecker>("ExprEngineVisitPreChecker",
+                                                   "Desc", "DocsURI");
+  });
+}
+
+void addExprEngineVisitPostChecker(AnalysisASTConsumer &AnalysisConsumer,
+                                   AnalyzerOptions &AnOpts) {
+  AnOpts.CheckersAndPackages = {{"ExprEngineVisitPostChecker", true}};
+  AnalysisConsumer.AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
+    Registry.addChecker<ExprEngineVisitPostChecker>(
+        "ExprEngineVisitPostChecker", "Desc", "DocsURI");
+  });
+}
+
+TEST(ExprEngineVisitTest, checkPreStmtGCCAsmStmt) {
+  std::string Diags;
+  EXPECT_TRUE(runCheckerOnCode<addExprEngineVisitPreChecker>(R"(
+    void top() {
+      asm("");
+    }
+  )",
+                                                             Diags));
+  EXPECT_EQ(Diags, "ExprEngineVisitPreChecker: checkPreStmt<GCCAsmStmt>\n");
+}
+
+TEST(ExprEngineVisitTest, checkPostStmtGCCAsmStmt) {
+  std::string Diags;
+  EXPECT_TRUE(runCheckerOnCode<addExprEngineVisitPostChecker>(R"(
+    void top() {
+      asm("");
+    }
+  )",
+                                                              Diags));
+  EXPECT_EQ(Diags, "ExprEngineVisitPostChecker: checkPostStmt<GCCAsmStmt>\n");
+}
+
+} // namespace


        


More information about the cfe-commits mailing list