From ac633fb5c4b46f1e716a20fd1c0198035ff47217 Mon Sep 17 00:00:00 2001 From: Artem Dergachev Date: Sat, 10 Feb 2018 00:55:49 +0000 Subject: [PATCH] [analyzer] Add missing pre-post-statement callbacks for OffsetOfExpr. 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 --- .../Checkers/AnalysisOrderChecker.cpp | 12 ++++++++++++ lib/StaticAnalyzer/Core/ExprEngine.cpp | 13 ++++++++++--- test/Analysis/Inputs/system-header-simulator.h | 4 +++- test/Analysis/offsetofexpr-callback.c | 13 +++++++++++++ 4 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 test/Analysis/offsetofexpr-callback.c diff --git a/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp index dc9dd5bd06..e4cdc500de 100644 --- a/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp @@ -33,6 +33,8 @@ class AnalysisOrderChecker check::PostStmt, check::PreStmt, check::PostStmt, + check::PreStmt, + check::PostStmt, check::PreCall, check::PostCall, check::NewAllocator, @@ -91,6 +93,16 @@ public: 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"; diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index fef7116d90..210cea6818 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -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(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), diff --git a/test/Analysis/Inputs/system-header-simulator.h b/test/Analysis/Inputs/system-header-simulator.h index ff69a1502b..8542387d42 100644 --- a/test/Analysis/Inputs/system-header-simulator.h +++ b/test/Analysis/Inputs/system-header-simulator.h @@ -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 index 0000000000..0fcb90797d --- /dev/null +++ b/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 -- 2.40.0