Index: lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp @@ -33,6 +33,8 @@ check::PostStmt, check::PreStmt, check::PostStmt, + check::PreStmt, + check::PostStmt, check::PreCall, check::PostCall, check::NewAllocator, @@ -89,6 +91,16 @@ llvm::errs() << "PostStmt\n"; } + void checkPreStmt(const OffsetOfExpr *OOE, CheckerContext &C) const { + if (isCallbackEnabled(C, "PreStmtOffsetOfExpr")) + llvm::errs() << "PreStmt\n"; + } + + void checkPostStmt(const OffsetOfExpr *OOE, CheckerContext &C) const { + if (isCallbackEnabled(C, "PostStmtOffsetOfExpr")) + llvm::errs() << "PostStmt\n"; + } + void checkPreCall(const CallEvent &Call, CheckerContext &C) const { if (isCallbackEnabled(C, "PreCall")) { llvm::errs() << "PreCall"; Index: lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- lib/StaticAnalyzer/Core/ExprEngine.cpp +++ lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1488,12 +1488,19 @@ Bldr.addNodes(Dst); break; - case Stmt::OffsetOfExprClass: + case Stmt::OffsetOfExprClass: { Bldr.takeNodes(Pred); - VisitOffsetOfExpr(cast(S), Pred, Dst); + ExplodedNodeSet PreVisit; + getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this); + + ExplodedNodeSet PostVisit; + for (ExplodedNode *Node : PreVisit) + VisitOffsetOfExpr(cast(S), Node, PostVisit); + + getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this); Bldr.addNodes(Dst); break; - + } case Stmt::UnaryExprOrTypeTraitExprClass: Bldr.takeNodes(Pred); VisitUnaryExprOrTypeTraitExpr(cast(S), Index: test/Analysis/Inputs/system-header-simulator.h =================================================================== --- test/Analysis/Inputs/system-header-simulator.h +++ test/Analysis/Inputs/system-header-simulator.h @@ -109,4 +109,6 @@ #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) Index: test/Analysis/offsetofexpr-callback.c =================================================================== --- /dev/null +++ test/Analysis/offsetofexpr-callback.c @@ -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 +// CHECK-NEXT: PostStmt