clang  7.0.0svn
AnalysisOrderChecker.cpp
Go to the documentation of this file.
1 //===- AnalysisOrderChecker - Print callbacks called ------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This checker prints callbacks that are called during analysis.
11 // This is required to ensure that callbacks are fired in order
12 // and do not duplicate or get lost.
13 // Feel free to extend this checker with any callback you need to check.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #include "ClangSACheckers.h"
18 #include "clang/AST/ExprCXX.h"
23 
24 using namespace clang;
25 using namespace ento;
26 
27 namespace {
28 
29 class AnalysisOrderChecker
30  : public Checker<check::PreStmt<CastExpr>,
31  check::PostStmt<CastExpr>,
32  check::PreStmt<ArraySubscriptExpr>,
33  check::PostStmt<ArraySubscriptExpr>,
34  check::PreStmt<CXXNewExpr>,
35  check::PostStmt<CXXNewExpr>,
36  check::PreStmt<OffsetOfExpr>,
37  check::PostStmt<OffsetOfExpr>,
38  check::PreCall,
39  check::PostCall,
40  check::NewAllocator,
41  check::Bind,
42  check::RegionChanges,
43  check::LiveSymbols> {
44 
45  bool isCallbackEnabled(AnalyzerOptions &Opts, StringRef CallbackName) const {
46  return Opts.getBooleanOption("*", false, this) ||
47  Opts.getBooleanOption(CallbackName, false, this);
48  }
49 
50  bool isCallbackEnabled(CheckerContext &C, StringRef CallbackName) const {
52  return isCallbackEnabled(Opts, CallbackName);
53  }
54 
55  bool isCallbackEnabled(ProgramStateRef State, StringRef CallbackName) const {
56  AnalyzerOptions &Opts = State->getStateManager().getOwningEngine()
57  ->getAnalysisManager().getAnalyzerOptions();
58  return isCallbackEnabled(Opts, CallbackName);
59  }
60 
61 public:
62  void checkPreStmt(const CastExpr *CE, CheckerContext &C) const {
63  if (isCallbackEnabled(C, "PreStmtCastExpr"))
64  llvm::errs() << "PreStmt<CastExpr> (Kind : " << CE->getCastKindName()
65  << ")\n";
66  }
67 
68  void checkPostStmt(const CastExpr *CE, CheckerContext &C) const {
69  if (isCallbackEnabled(C, "PostStmtCastExpr"))
70  llvm::errs() << "PostStmt<CastExpr> (Kind : " << CE->getCastKindName()
71  << ")\n";
72  }
73 
74  void checkPreStmt(const ArraySubscriptExpr *SubExpr,
75  CheckerContext &C) const {
76  if (isCallbackEnabled(C, "PreStmtArraySubscriptExpr"))
77  llvm::errs() << "PreStmt<ArraySubscriptExpr>\n";
78  }
79 
80  void checkPostStmt(const ArraySubscriptExpr *SubExpr,
81  CheckerContext &C) const {
82  if (isCallbackEnabled(C, "PostStmtArraySubscriptExpr"))
83  llvm::errs() << "PostStmt<ArraySubscriptExpr>\n";
84  }
85 
86  void checkPreStmt(const CXXNewExpr *NE, CheckerContext &C) const {
87  if (isCallbackEnabled(C, "PreStmtCXXNewExpr"))
88  llvm::errs() << "PreStmt<CXXNewExpr>\n";
89  }
90 
91  void checkPostStmt(const CXXNewExpr *NE, CheckerContext &C) const {
92  if (isCallbackEnabled(C, "PostStmtCXXNewExpr"))
93  llvm::errs() << "PostStmt<CXXNewExpr>\n";
94  }
95 
96  void checkPreStmt(const OffsetOfExpr *OOE, CheckerContext &C) const {
97  if (isCallbackEnabled(C, "PreStmtOffsetOfExpr"))
98  llvm::errs() << "PreStmt<OffsetOfExpr>\n";
99  }
100 
101  void checkPostStmt(const OffsetOfExpr *OOE, CheckerContext &C) const {
102  if (isCallbackEnabled(C, "PostStmtOffsetOfExpr"))
103  llvm::errs() << "PostStmt<OffsetOfExpr>\n";
104  }
105 
106  void checkPreCall(const CallEvent &Call, CheckerContext &C) const {
107  if (isCallbackEnabled(C, "PreCall")) {
108  llvm::errs() << "PreCall";
109  if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl()))
110  llvm::errs() << " (" << ND->getQualifiedNameAsString() << ')';
111  llvm::errs() << '\n';
112  }
113  }
114 
115  void checkPostCall(const CallEvent &Call, CheckerContext &C) const {
116  if (isCallbackEnabled(C, "PostCall")) {
117  llvm::errs() << "PostCall";
118  if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(Call.getDecl()))
119  llvm::errs() << " (" << ND->getQualifiedNameAsString() << ')';
120  llvm::errs() << '\n';
121  }
122  }
123 
124  void checkNewAllocator(const CXXNewExpr *CNE, SVal Target,
125  CheckerContext &C) const {
126  if (isCallbackEnabled(C, "NewAllocator"))
127  llvm::errs() << "NewAllocator\n";
128  }
129 
130  void checkBind(SVal Loc, SVal Val, const Stmt *S, CheckerContext &C) const {
131  if (isCallbackEnabled(C, "Bind"))
132  llvm::errs() << "Bind\n";
133  }
134 
135  void checkLiveSymbols(ProgramStateRef State, SymbolReaper &SymReaper) const {
136  if (isCallbackEnabled(State, "LiveSymbols"))
137  llvm::errs() << "LiveSymbols\n";
138  }
139 
141  checkRegionChanges(ProgramStateRef State,
142  const InvalidatedSymbols *Invalidated,
143  ArrayRef<const MemRegion *> ExplicitRegions,
145  const LocationContext *LCtx, const CallEvent *Call) const {
146  if (isCallbackEnabled(State, "RegionChanges"))
147  llvm::errs() << "RegionChanges\n";
148  return State;
149  }
150 };
151 } // end anonymous namespace
152 
153 //===----------------------------------------------------------------------===//
154 // Registration.
155 //===----------------------------------------------------------------------===//
156 
157 void ento::registerAnalysisOrderChecker(CheckerManager &mgr) {
158  mgr.registerChecker<AnalysisOrderChecker>();
159 }
Stmt - This represents one statement.
Definition: Stmt.h:66
AnalysisManager & getAnalysisManager()
Defines the clang::Expr interface and subclasses for C++ expressions.
LineState State
const char * getCastKindName() const
Definition: Expr.cpp:1636
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:2723
AnalyzerOptions & getAnalyzerOptions() override
virtual const Decl * getDecl() const
Returns the declaration of the function or method that will be called.
Definition: CallEvent.h:205
bool getBooleanOption(StringRef Name, bool DefaultVal, const ento::CheckerBase *C=nullptr, bool SearchInParents=false)
Interprets an option&#39;s string value as a boolean.
CHECKER * registerChecker()
Used to register checkers.
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)"...
Definition: ExprCXX.h:1845
SVal - This represents a symbolic expression, which can be either an L-value or an R-value...
Definition: SVals.h:63
A class responsible for cleaning up unused symbols.
Dataflow Directional Tag Classes.
Represents an abstract call to a function or method along a particular path.
Definition: CallEvent.h:140
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2130
This represents a decl that may have a name.
Definition: Decl.h:248
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type, member-designator).
Definition: Expr.h:1935