[PATCH] D42300: [Analyzer] Add PreStmt and PostStmt callbacks for OffsetOfExpr
This revision was automatically updated to reflect the committed changes. Closed by commit rL324790: [analyzer] Add missing pre-post-statement callbacks for OffsetOfExpr. (authored by dergachev, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D42300?vs=133421=133721#toc Repository: rL LLVM https://reviews.llvm.org/D42300 Files: cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp cfe/trunk/test/Analysis/Inputs/system-header-simulator.h cfe/trunk/test/Analysis/offsetofexpr-callback.c Index: cfe/trunk/test/Analysis/Inputs/system-header-simulator.h === --- cfe/trunk/test/Analysis/Inputs/system-header-simulator.h +++ cfe/trunk/test/Analysis/Inputs/system-header-simulator.h @@ -110,4 +110,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) \ No newline at end of file Index: cfe/trunk/test/Analysis/offsetofexpr-callback.c === --- cfe/trunk/test/Analysis/offsetofexpr-callback.c +++ cfe/trunk/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 \ No newline at end of file Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp === --- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1543,12 +1543,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: cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp === --- cfe/trunk/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ cfe/trunk/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, @@ -91,6 +93,16 @@ llvm::errs() << "PostStmt\n"; } + void checkPreStmt(const OffsetOfExpr *OOE, CheckerContext ) const { +if (isCallbackEnabled(C, "PreStmtOffsetOfExpr")) + llvm::errs() << "PreStmt\n"; + } + + void checkPostStmt(const OffsetOfExpr *OOE, CheckerContext ) const { +if (isCallbackEnabled(C, "PostStmtOffsetOfExpr")) + llvm::errs() << "PostStmt\n"; + } + void checkPreCall(const CallEvent , CheckerContext ) const { if (isCallbackEnabled(C, "PreCall")) { llvm::errs() << "PreCall"; Index: cfe/trunk/test/Analysis/Inputs/system-header-simulator.h === --- cfe/trunk/test/Analysis/Inputs/system-header-simulator.h +++ cfe/trunk/test/Analysis/Inputs/system-header-simulator.h @@ -110,4 +110,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) \ No newline at end of file Index: cfe/trunk/test/Analysis/offsetofexpr-callback.c === --- cfe/trunk/test/Analysis/offsetofexpr-callback.c +++ cfe/trunk/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 \ No newline at end of file Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
[PATCH] D42300: [Analyzer] Add PreStmt and PostStmt callbacks for OffsetOfExpr
NoQ accepted this revision. NoQ added a comment. This revision is now accepted and ready to land. All right, i guess we already do have a pair of callbacks for `IntegerLiteral` and it doesn't hurt, especially because here they'd eventually be actually useful. I think it should land, just to make it easier to add the actual support later. Repository: rC Clang https://reviews.llvm.org/D42300 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D42300: [Analyzer] Add PreStmt and PostStmt callbacks for OffsetOfExpr
MTC added a comment. @NoQ Sorry to bother you again. It seems that this patch is useless to analyzer temporarily, if you think so, I will abandon it : ). Repository: rC Clang https://reviews.llvm.org/D42300 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D42300: [Analyzer] Add PreStmt and PostStmt callbacks for OffsetOfExpr
MTC updated this revision to Diff 133421. MTC added a comment. Herald added a reviewer: george.karpenkov. rebase Repository: rC Clang https://reviews.llvm.org/D42300 Files: lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp test/Analysis/Inputs/system-header-simulator.h test/Analysis/offsetofexpr-callback.c 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 \ No newline at end of file Index: test/Analysis/Inputs/system-header-simulator.h === --- test/Analysis/Inputs/system-header-simulator.h +++ test/Analysis/Inputs/system-header-simulator.h @@ -110,4 +110,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) \ No newline at end of file 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: 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, @@ -91,6 +93,16 @@ llvm::errs() << "PostStmt\n"; } + void checkPreStmt(const OffsetOfExpr *OOE, CheckerContext ) const { +if (isCallbackEnabled(C, "PreStmtOffsetOfExpr")) + llvm::errs() << "PreStmt\n"; + } + + void checkPostStmt(const OffsetOfExpr *OOE, CheckerContext ) const { +if (isCallbackEnabled(C, "PostStmtOffsetOfExpr")) + llvm::errs() << "PostStmt\n"; + } + void checkPreCall(const CallEvent , CheckerContext ) const { if (isCallbackEnabled(C, "PreCall")) { llvm::errs() << "PreCall"; 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 \ No newline at end of file Index: test/Analysis/Inputs/system-header-simulator.h === --- test/Analysis/Inputs/system-header-simulator.h +++ test/Analysis/Inputs/system-header-simulator.h @@ -110,4 +110,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) \ No newline at end of file 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
[PATCH] D42300: [Analyzer] Add PreStmt and PostStmt callbacks for OffsetOfExpr
MTC added a comment. In https://reviews.llvm.org/D42300#982187, @NoQ wrote: > My intuition suggests that this checker shouldn't be path-sensitive; our > path-sensitive analysis does very little to help you with this particular > checker, and you might end up with a much easier and more reliable checker if > you turn it into a simple AST visitor or an AST matcher. Just a heads up. This is a very useful suggestion, many thanks, Noq! Path-sensitive is really a bit too heavy for this checker. Repository: rC Clang https://reviews.llvm.org/D42300 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D42300: [Analyzer] Add PreStmt and PostStmt callbacks for OffsetOfExpr
MTC updated this revision to Diff 130753. MTC added a comment. - Use C++11 range-based for loop to traverse ExplodedNodeSet. - Define the macro `offsetof` in `system-header-simulator.h`. Repository: rC Clang https://reviews.llvm.org/D42300 Files: lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp lib/StaticAnalyzer/Core/ExprEngine.cpp test/Analysis/Inputs/system-header-simulator.h test/Analysis/offsetofexpr-callback.c 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 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: 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: 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 ) const { +if (isCallbackEnabled(C, "PreStmtOffsetOfExpr")) + llvm::errs() << "PreStmt\n"; + } + + void checkPostStmt(const OffsetOfExpr *OOE, CheckerContext ) const { +if (isCallbackEnabled(C, "PostStmtOffsetOfExpr")) + llvm::errs() << "PostStmt\n"; + } + void checkPreCall(const CallEvent , CheckerContext ) const { if (isCallbackEnabled(C, "PreCall")) { llvm::errs() << "PreCall"; 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 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: 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) +
[PATCH] D42300: [Analyzer] Add PreStmt and PostStmt callbacks for OffsetOfExpr
NoQ added a comment. The patch seems correct, but i suspect that your overall approach to the checker you're trying to make is not ideal. `offsetof` returns a concrete value (because, well, symbolic `offsetof`s are not yet supported in the analyzer), and even if you see the concrete value, you'd be unable to track it, because when you get another concrete value with the same integer inside, you won't be able to easily figure out if its the same value or a different value. My intuition suggests that this checker shouldn't be path-sensitive; our path-sensitive analysis does very little to help you with this particular checker, and you might end up with a much easier and more reliable checker if you turn it into a simple AST visitor or an AST matcher. Just a heads up. Repository: rC Clang https://reviews.llvm.org/D42300 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D42300: [Analyzer] Add PreStmt and PostStmt callbacks for OffsetOfExpr
a.sidorin added a comment. Hello Henry, The patch looks reasonable. I think it can be landed after comments are resolved. Comment at: lib/StaticAnalyzer/Core/ExprEngine.cpp:1497 + ExplodedNodeSet PostVisit; + for (ExplodedNodeSet::iterator i = PreVisit.begin(), e = PreVisit.end(); + i != e; ++i) { Could you C++11-fy this loop? Comment at: test/Analysis/offsetofexpr-callback.c:3 + +#include + Answering your question, we should put the declaration into system-header-simulator.h. Comment at: test/Analysis/offsetofexpr-callback.c:7 +char c; +double d; +}; This decl seems unused. Should we remove it? Repository: rC Clang https://reviews.llvm.org/D42300 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D42300: [Analyzer] Add PreStmt and PostStmt callbacks for OffsetOfExpr
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 `? 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 + +struct S { +char c; +double d; +}; + +void test() { + offsetof(struct S, c); +} + +// CHECK: PreStmt +// CHECK-NEXT: PostStmt 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(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(S), *i, PostVisit); + } + + getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this); Bldr.addNodes(Dst); break; - +} case Stmt::UnaryExprOrTypeTraitExprClass: Bldr.takeNodes(Pred); VisitUnaryExprOrTypeTraitExpr(cast(S), 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 ) const { +if (isCallbackEnabled(C, "PreStmtOffsetOfExpr")) + llvm::errs() << "PreStmt\n"; + } + + void checkPostStmt(const OffsetOfExpr *OOE, CheckerContext ) const { +if (isCallbackEnabled(C, "PostStmtOffsetOfExpr")) + llvm::errs() << "PostStmt\n"; + } + void checkPreCall(const CallEvent , CheckerContext ) 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 + +struct S { +char c; +double d; +}; + +void test() { + offsetof(struct S, c); +} + +// CHECK: PreStmt +// CHECK-NEXT: PostStmt 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(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(S), *i, PostVisit); + } + + getCheckerManager().runCheckersForPostStmt(Dst, PostVisit, S, *this); Bldr.addNodes(Dst); break; - +} case Stmt::UnaryExprOrTypeTraitExprClass: Bldr.takeNodes(Pred); VisitUnaryExprOrTypeTraitExpr(cast(S), Index: lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp === --- lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++