]> granicus.if.org Git - clang/commitdiff
[analyzer] Add missing pre-post-statement callbacks for OffsetOfExpr.
authorArtem Dergachev <artem.dergachev@gmail.com>
Sat, 10 Feb 2018 00:55:49 +0000 (00:55 +0000)
committerArtem Dergachev <artem.dergachev@gmail.com>
Sat, 10 Feb 2018 00:55:49 +0000 (00:55 +0000)
This expression may or may not be evaluated in compile time, so tracking the
result symbol is of potential interest. However, run-time offsetof is not yet
supported by the analyzer, so for now this callback is only there to assist
future implementation.

Patch by Henry Wong!

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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@324790 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
lib/StaticAnalyzer/Core/ExprEngine.cpp
test/Analysis/Inputs/system-header-simulator.h
test/Analysis/offsetofexpr-callback.c [new file with mode: 0644]

index dc9dd5bd06d46fc88077608902c5769f8f2c11b4..e4cdc500de6adada4dd36023e15902293d2ccebe 100644 (file)
@@ -33,6 +33,8 @@ class AnalysisOrderChecker
                      check::PostStmt<ArraySubscriptExpr>,
                      check::PreStmt<CXXNewExpr>,
                      check::PostStmt<CXXNewExpr>,
+                     check::PreStmt<OffsetOfExpr>,
+                     check::PostStmt<OffsetOfExpr>,
                      check::PreCall,
                      check::PostCall,
                      check::NewAllocator,
@@ -91,6 +93,16 @@ public:
       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 fef7116d905f7b06af145d4e6d4974447ea6a198..210cea6818e20770eddd78513c2fc8226cf3dd53 100644 (file)
@@ -1543,12 +1543,19 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,
       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 (ExplodedNode *Node : PreVisit)
+        VisitOffsetOfExpr(cast<OffsetOfExpr>(S), Node, PostVisit);
+
+      getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this);
       Bldr.addNodes(Dst);
       break;
-
+    }
     case Stmt::UnaryExprOrTypeTraitExprClass:
       Bldr.takeNodes(Pred);
       VisitUnaryExprOrTypeTraitExpr(cast<UnaryExprOrTypeTraitExpr>(S),
index ff69a1502b94052d5e52d1342bf1ea1f9eff87e6..8542387d4277a14e5885a1c912e9b22e3cc1325e 100644 (file)
@@ -110,4 +110,6 @@ void _Exit(int status) __attribute__ ((__noreturn__));
 #ifndef NULL
 #define __DARWIN_NULL 0
 #define NULL __DARWIN_NULL
-#endif
\ No newline at end of file
+#endif
+
+#define offsetof(t, d) __builtin_offsetof(t, d)
\ No newline at end of file
diff --git a/test/Analysis/offsetofexpr-callback.c b/test/Analysis/offsetofexpr-callback.c
new file mode 100644 (file)
index 0000000..0fcb907
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.AnalysisOrder -analyzer-config debug.AnalysisOrder:PreStmtOffsetOfExpr=true,debug.AnalysisOrder:PostStmtOffsetOfExpr=true %s 2>&1 | FileCheck %s
+#include "Inputs/system-header-simulator.h"
+
+struct S {
+  char c;
+};
+
+void test() {
+  offsetof(struct S, c); 
+}
+
+// CHECK: PreStmt<OffsetOfExpr>
+// CHECK-NEXT: PostStmt<OffsetOfExpr>
\ No newline at end of file