summaryrefslogtreecommitdiff
path: root/clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/AnalysisOrderChecker.cpp80
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;
}