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