diff options
author | Artem Dergachev <artem.dergachev@gmail.com> | 2018-01-18 00:53:50 +0000 |
---|---|---|
committer | Artem Dergachev <artem.dergachev@gmail.com> | 2018-01-18 00:53:50 +0000 |
commit | e941daef399e07ed1d6a4df6bcbb376d485c05e5 (patch) | |
tree | 9001bb19a3f644e35e689dfcf2efa37f5f7a5199 /clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp | |
parent | 1c64e617f57297e53abc3d48bedb5a4e3375f644 (diff) | |
download | bcm5719-llvm-e941daef399e07ed1d6a4df6bcbb376d485c05e5.tar.gz bcm5719-llvm-e941daef399e07ed1d6a4df6bcbb376d485c05e5.zip |
[analyzer] operator new: Fix callback order for CXXNewExpr.
PreStmt<CXXNewExpr> was never called.
Additionally, under c++-allocator-inlining=true, PostStmt<CXXNewExpr> was
called twice when the allocator was inlined: once after evaluating the
new-expression itself, once after evaluating the allocator call which, for the
lack of better options, uses the new-expression as the call site.
This patch fixes both problems.
Differential Revision: https://reviews.llvm.org/D41934
rdar://problem/12180598
llvm-svn: 322797
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp index 90d5c0e36a4..e2a35c04266 100644 --- a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp @@ -15,8 +15,10 @@ //===----------------------------------------------------------------------===// #include "ClangSACheckers.h" +#include "clang/AST/ExprCXX.h" #include "clang/StaticAnalyzer/Core/Checker.h" #include "clang/StaticAnalyzer/Core/CheckerManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" using namespace clang; @@ -29,6 +31,11 @@ class AnalysisOrderChecker check::PostStmt<CastExpr>, check::PreStmt<ArraySubscriptExpr>, check::PostStmt<ArraySubscriptExpr>, + check::PreStmt<CXXNewExpr>, + check::PostStmt<CXXNewExpr>, + check::PreCall, + check::PostCall, + check::NewAllocator, check::Bind, check::RegionChanges> { bool isCallbackEnabled(AnalyzerOptions &Opts, StringRef CallbackName) const { @@ -72,6 +79,40 @@ public: llvm::errs() << "PostStmt<ArraySubscriptExpr>\n"; } + void checkPreStmt(const CXXNewExpr *NE, CheckerContext &C) const { + if (isCallbackEnabled(C, "PreStmtCXXNewExpr")) + llvm::errs() << "PreStmt<CXXNewExpr>\n"; + } + + void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const { + if (isCallbackEnabled(C, "PostStmtCXXNewExpr")) + llvm::errs() << "PostStmt<CXXNewExpr>\n"; + } + + void checkPreCall(const CallEvent &Call, CheckerContext &C) const { + if (isCallbackEnabled(C, "PreCall")) { + llvm::errs() << "PreCall"; + if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl())) + llvm::errs() << " (" << ND->getQualifiedNameAsString() << ')'; + llvm::errs() << '\n'; + } + } + + void checkPostCall(const CallEvent &Call, CheckerContext &C) const { + if (isCallbackEnabled(C, "PostCall")) { + llvm::errs() << "PostCall"; + if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl())) + llvm::errs() << " (" << ND->getQualifiedNameAsString() << ')'; + llvm::errs() << '\n'; + } + } + + void checkNewAllocator(const CXXNewExpr *CNE, SVal Target, + CheckerContext &C) const { + if (isCallbackEnabled(C, "NewAllocator")) + llvm::errs() << "NewAllocator\n"; + } + void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &C) const { if (isCallbackEnabled(C, "Bind")) llvm::errs() << "Bind\n"; |