MTC created this revision.
MTC added reviewers: NoQ, a.sidorin, dcoughlin.
Herald added subscribers: cfe-commits, szepet, xazax.hun.

PreStmt and PostStmt callbacks for OffsetOfExpr are necessary to implement 
`Cert ARR39-C: Do not add or subtract a scaled integer to a pointer`. And 
should I define the `offsetof` macro in 
`clang/test/Analysis/Inputs/system-header-simulator.h`? Or, like 
`clang/test/Analysis/malloc-sizeof.c`, use `#include <stddef.h>`?


Repository:
  rC Clang

https://reviews.llvm.org/D42300

Files:
  lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  test/Analysis/offsetofexpr-callback.c


Index: test/Analysis/offsetofexpr-callback.c
===================================================================
--- /dev/null
+++ test/Analysis/offsetofexpr-callback.c
@@ -0,0 +1,15 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder 
-analyzer-config 
debug.AnalysisOrder:PreStmtOffsetOfExpr=true,debug.AnalysisOrder:PostStmtOffsetOfExpr=true
 %s 2>&1 | FileCheck %s
+
+#include <stddef.h>
+
+struct S {
+    char c;
+    double d;
+};
+
+void test() {
+  offsetof(struct S, c);
+}
+
+// CHECK: PreStmt<OffsetOfExpr>
+// CHECK-NEXT: PostStmt<OffsetOfExpr>
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1488,12 +1488,21 @@
       Bldr.addNodes(Dst);
       break;
 
-    case Stmt::OffsetOfExprClass:
+    case Stmt::OffsetOfExprClass: {
       Bldr.takeNodes(Pred);
-      VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Pred, Dst);
+      ExplodedNodeSet PreVisit;
+      getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+
+      ExplodedNodeSet PostVisit;
+      for (ExplodedNodeSet::iterator i = PreVisit.begin(), e = PreVisit.end();
+           i != e; ++i) {
+        VisitOffsetOfExpr(cast<OffsetOfExpr>(S), *i, PostVisit);
+      }
+
+      getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
       Bldr.addNodes(Dst);
       break;
-
+    }
     case Stmt::UnaryExprOrTypeTraitExprClass:
       Bldr.takeNodes(Pred);
       VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
Index: lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
+++ lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
@@ -33,6 +33,8 @@
                      check::PostStmt<ArraySubscriptExpr>,
                      check::PreStmt<CXXNewExpr>,
                      check::PostStmt<CXXNewExpr>,
+                     check::PreStmt<OffsetOfExpr>,
+                     check::PostStmt<OffsetOfExpr>,
                      check::PreCall,
                      check::PostCall,
                      check::NewAllocator,
@@ -89,6 +91,16 @@
       llvm::errs() << "PostStmt<CXXNewExpr>\n";
   }
 
+  void checkPreStmt(const OffsetOfExpr *OOE, CheckerContext &C) const {
+    if (isCallbackEnabled(C, "PreStmtOffsetOfExpr"))
+      llvm::errs() << "PreStmt<OffsetOfExpr>\n";
+  }
+
+  void checkPostStmt(const OffsetOfExpr *OOE, CheckerContext &C) const {
+    if (isCallbackEnabled(C, "PostStmtOffsetOfExpr"))
+      llvm::errs() << "PostStmt<OffsetOfExpr>\n";
+  }
+
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const {
     if (isCallbackEnabled(C, "PreCall")) {
       llvm::errs() << "PreCall";


Index: test/Analysis/offsetofexpr-callback.c
===================================================================
--- /dev/null
+++ test/Analysis/offsetofexpr-callback.c
@@ -0,0 +1,15 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder -analyzer-config debug.AnalysisOrder:PreStmtOffsetOfExpr=true,debug.AnalysisOrder:PostStmtOffsetOfExpr=true %s 2>&1 | FileCheck %s
+
+#include <stddef.h>
+
+struct S {
+    char c;
+    double d;
+};
+
+void test() {
+  offsetof(struct S, c);
+}
+
+// CHECK: PreStmt<OffsetOfExpr>
+// CHECK-NEXT: PostStmt<OffsetOfExpr>
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1488,12 +1488,21 @@
       Bldr.addNodes(Dst);
       break;
 
-    case Stmt::OffsetOfExprClass:
+    case Stmt::OffsetOfExprClass: {
       Bldr.takeNodes(Pred);
-      VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Pred, Dst);
+      ExplodedNodeSet PreVisit;
+      getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
+
+      ExplodedNodeSet PostVisit;
+      for (ExplodedNodeSet::iterator i = PreVisit.begin(), e = PreVisit.end();
+           i != e; ++i) {
+        VisitOffsetOfExpr(cast<OffsetOfExpr>(S), *i, PostVisit);
+      }
+
+      getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
       Bldr.addNodes(Dst);
       break;
-
+    }
     case Stmt::UnaryExprOrTypeTraitExprClass:
       Bldr.takeNodes(Pred);
       VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
Index: lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
===================================================================
--- lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
+++ lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
@@ -33,6 +33,8 @@
                      check::PostStmt<ArraySubscriptExpr>,
                      check::PreStmt<CXXNewExpr>,
                      check::PostStmt<CXXNewExpr>,
+                     check::PreStmt<OffsetOfExpr>,
+                     check::PostStmt<OffsetOfExpr>,
                      check::PreCall,
                      check::PostCall,
                      check::NewAllocator,
@@ -89,6 +91,16 @@
       llvm::errs() << "PostStmt<CXXNewExpr>\n";
   }
 
+  void checkPreStmt(const OffsetOfExpr *OOE, CheckerContext &C) const {
+    if (isCallbackEnabled(C, "PreStmtOffsetOfExpr"))
+      llvm::errs() << "PreStmt<OffsetOfExpr>\n";
+  }
+
+  void checkPostStmt(const OffsetOfExpr *OOE, CheckerContext &C) const {
+    if (isCallbackEnabled(C, "PostStmtOffsetOfExpr"))
+      llvm::errs() << "PostStmt<OffsetOfExpr>\n";
+  }
+
   void checkPreCall(const CallEvent &Call, CheckerContext &C) const {
     if (isCallbackEnabled(C, "PreCall")) {
       llvm::errs() << "PreCall";
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to