diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp | 80 |
1 files changed, 59 insertions, 21 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp index 2ef50a727ece4..0e8cbc60689a7 100644 --- a/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp @@ -13,13 +13,14 @@ // //===----------------------------------------------------------------------===// -#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" #include "clang/AST/ExprCXX.h" #include "clang/Analysis/CFGStmtMap.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.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" +#include "llvm/Support/ErrorHandling.h" using namespace clang; using namespace ento; @@ -27,24 +28,20 @@ using namespace ento; namespace { class AnalysisOrderChecker - : public Checker<check::PreStmt<CastExpr>, - check::PostStmt<CastExpr>, - check::PreStmt<ArraySubscriptExpr>, - check::PostStmt<ArraySubscriptExpr>, - check::PreStmt<CXXNewExpr>, - check::PostStmt<CXXNewExpr>, - check::PreStmt<OffsetOfExpr>, - check::PostStmt<OffsetOfExpr>, - check::PreCall, - check::PostCall, - check::EndFunction, - check::NewAllocator, - check::Bind, - check::PointerEscape, - check::RegionChanges, - check::LiveSymbols> { - - bool isCallbackEnabled(AnalyzerOptions &Opts, StringRef CallbackName) const { + : public Checker< + check::PreStmt<CastExpr>, check::PostStmt<CastExpr>, + check::PreStmt<ArraySubscriptExpr>, + check::PostStmt<ArraySubscriptExpr>, check::PreStmt<CXXNewExpr>, + check::PostStmt<CXXNewExpr>, check::PreStmt<CXXDeleteExpr>, + check::PostStmt<CXXDeleteExpr>, check::PreStmt<CXXConstructExpr>, + check::PostStmt<CXXConstructExpr>, check::PreStmt<OffsetOfExpr>, + check::PostStmt<OffsetOfExpr>, check::PreCall, check::PostCall, + check::EndFunction, check::EndAnalysis, check::NewAllocator, + check::Bind, check::PointerEscape, check::RegionChanges, + check::LiveSymbols, eval::Call> { + + bool isCallbackEnabled(const AnalyzerOptions &Opts, + StringRef CallbackName) const { return Opts.getCheckerBooleanOption(this, "*") || Opts.getCheckerBooleanOption(this, CallbackName); } @@ -95,6 +92,26 @@ public: llvm::errs() << "PostStmt<CXXNewExpr>\n"; } + void checkPreStmt(const CXXDeleteExpr *NE, CheckerContext &C) const { + if (isCallbackEnabled(C, "PreStmtCXXDeleteExpr")) + llvm::errs() << "PreStmt<CXXDeleteExpr>\n"; + } + + void checkPostStmt(const CXXDeleteExpr *NE, CheckerContext &C) const { + if (isCallbackEnabled(C, "PostStmtCXXDeleteExpr")) + llvm::errs() << "PostStmt<CXXDeleteExpr>\n"; + } + + void checkPreStmt(const CXXConstructExpr *NE, CheckerContext &C) const { + if (isCallbackEnabled(C, "PreStmtCXXConstructExpr")) + llvm::errs() << "PreStmt<CXXConstructExpr>\n"; + } + + void checkPostStmt(const CXXConstructExpr *NE, CheckerContext &C) const { + if (isCallbackEnabled(C, "PostStmtCXXConstructExpr")) + llvm::errs() << "PostStmt<CXXConstructExpr>\n"; + } + void checkPreStmt(const OffsetOfExpr *OOE, CheckerContext &C) const { if (isCallbackEnabled(C, "PreStmtOffsetOfExpr")) llvm::errs() << "PreStmt<OffsetOfExpr>\n"; @@ -105,11 +122,25 @@ public: llvm::errs() << "PostStmt<OffsetOfExpr>\n"; } + bool evalCall(const CallEvent &Call, CheckerContext &C) const { + if (isCallbackEnabled(C, "EvalCall")) { + llvm::errs() << "EvalCall"; + if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl())) + llvm::errs() << " (" << ND->getQualifiedNameAsString() << ')'; + llvm::errs() << " {argno: " << Call.getNumArgs() << '}'; + llvm::errs() << " [" << Call.getKindAsString() << ']'; + llvm::errs() << '\n'; + return true; + } + return false; + } + 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() << " [" << Call.getKindAsString() << ']'; llvm::errs() << '\n'; } } @@ -119,6 +150,7 @@ public: llvm::errs() << "PostCall"; if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl())) llvm::errs() << " (" << ND->getQualifiedNameAsString() << ')'; + llvm::errs() << " [" << Call.getKindAsString() << ']'; llvm::errs() << '\n'; } } @@ -140,7 +172,13 @@ public: } } - void checkNewAllocator(const CXXNewExpr *CNE, SVal Target, + void checkEndAnalysis(ExplodedGraph &G, BugReporter &BR, + ExprEngine &Eng) const { + if (isCallbackEnabled(BR.getAnalyzerOptions(), "EndAnalysis")) + llvm::errs() << "EndAnalysis\n"; + } + + void checkNewAllocator(const CXXAllocatorCall &Call, CheckerContext &C) const { if (isCallbackEnabled(C, "NewAllocator")) llvm::errs() << "NewAllocator\n"; @@ -186,6 +224,6 @@ void ento::registerAnalysisOrderChecker(CheckerManager &mgr) { mgr.registerChecker<AnalysisOrderChecker>(); } -bool ento::shouldRegisterAnalysisOrderChecker(const LangOptions &LO) { +bool ento::shouldRegisterAnalysisOrderChecker(const CheckerManager &mgr) { return true; } |