CheckerManager.h revision deb6447d0029bdb122397fafb5fa2a4e76f2e555
1//===--- CheckerManager.h - Static Analyzer Checker Manager -----*- 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// Defines the Static Analyzer Checker Manager. 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef LLVM_CLANG_SA_CORE_CHECKERMANAGER_H 15#define LLVM_CLANG_SA_CORE_CHECKERMANAGER_H 16 17#include "clang/Basic/LangOptions.h" 18#include "llvm/ADT/SmallVector.h" 19#include "llvm/ADT/DenseMap.h" 20#include "llvm/ADT/FoldingSet.h" 21#include <vector> 22 23namespace clang { 24 class Decl; 25 class Stmt; 26 class CallExpr; 27 28namespace ento { 29 class ExprEngine; 30 class AnalysisManager; 31 class BugReporter; 32 class CheckerContext; 33 class ObjCMessage; 34 class SVal; 35 class ExplodedNode; 36 class ExplodedNodeSet; 37 class ExplodedGraph; 38 class GRState; 39 class EndOfFunctionNodeBuilder; 40 class BranchNodeBuilder; 41 class MemRegion; 42 class SymbolReaper; 43 44class GraphExpander { 45public: 46 virtual ~GraphExpander(); 47 virtual void expandGraph(ExplodedNodeSet &Dst, ExplodedNode *Pred) = 0; 48}; 49 50struct VoidCheckerFnParm {}; 51template <typename P1=VoidCheckerFnParm, typename P2=VoidCheckerFnParm, 52 typename P3=VoidCheckerFnParm, typename P4=VoidCheckerFnParm> 53class CheckerFn { 54 typedef void (*Func)(void *, P1, P2, P3, P4); 55 Func Fn; 56public: 57 void *Checker; 58 CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 59 void operator()(P1 p1, P2 p2, P3 p3, P4 p4) { Fn(Checker, p1, p2, p3, p4); } 60}; 61 62template <typename P1, typename P2, typename P3> 63class CheckerFn<P1, P2, P3, VoidCheckerFnParm> { 64 typedef void (*Func)(void *, P1, P2, P3); 65 Func Fn; 66public: 67 void *Checker; 68 CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 69 void operator()(P1 p1, P2 p2, P3 p3) { Fn(Checker, p1, p2, p3); } 70}; 71 72template <typename P1, typename P2> 73class CheckerFn<P1, P2, VoidCheckerFnParm, VoidCheckerFnParm> { 74 typedef void (*Func)(void *, P1, P2); 75 Func Fn; 76public: 77 void *Checker; 78 CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 79 void operator()(P1 p1, P2 p2) { Fn(Checker, p1, p2); } 80}; 81 82template <> 83class CheckerFn<VoidCheckerFnParm, VoidCheckerFnParm, VoidCheckerFnParm, 84 VoidCheckerFnParm> { 85 typedef void (*Func)(void *); 86 Func Fn; 87public: 88 void *Checker; 89 CheckerFn(void *checker, Func fn) : Fn(fn), Checker(checker) { } 90 void operator()() { Fn(Checker); } 91}; 92 93class CheckerManager { 94 const LangOptions LangOpts; 95 96public: 97 CheckerManager(const LangOptions &langOpts) : LangOpts(langOpts) { } 98 ~CheckerManager(); 99 100 void finishedCheckerRegistration(); 101 102 const LangOptions &getLangOptions() const { return LangOpts; } 103 104 typedef void *CheckerRef; 105 typedef void *CheckerTag; 106 typedef CheckerFn<> CheckerDtor; 107 108//===----------------------------------------------------------------------===// 109// registerChecker 110//===----------------------------------------------------------------------===// 111 112 /// \brief Used to register checkers. 113 /// 114 /// \returns a pointer to the checker object. 115 template <typename CHECKER> 116 CHECKER *registerChecker() { 117 CheckerTag tag = getTag<CHECKER>(); 118 CheckerRef &ref = CheckerTags[tag]; 119 if (ref) 120 return static_cast<CHECKER *>(ref); // already registered. 121 122 CHECKER *checker = new CHECKER(); 123 CheckerDtors.push_back(CheckerDtor(checker, destruct<CHECKER>)); 124 CHECKER::_register(checker, *this); 125 ref = checker; 126 return checker; 127 } 128 129//===----------------------------------------------------------------------===// 130// Functions for running checkers for AST traversing.. 131//===----------------------------------------------------------------------===// 132 133 /// \brief Run checkers handling Decls. 134 void runCheckersOnASTDecl(const Decl *D, AnalysisManager& mgr, 135 BugReporter &BR); 136 137 /// \brief Run checkers handling Decls containing a Stmt body. 138 void runCheckersOnASTBody(const Decl *D, AnalysisManager& mgr, 139 BugReporter &BR); 140 141//===----------------------------------------------------------------------===// 142// Functions for running checkers for path-sensitive checking. 143//===----------------------------------------------------------------------===// 144 145 /// \brief Run checkers for pre-visiting Stmts. 146 void runCheckersForPreStmt(ExplodedNodeSet &Dst, 147 const ExplodedNodeSet &Src, 148 const Stmt *S, 149 ExprEngine &Eng) { 150 runCheckersForStmt(/*isPreVisit=*/true, Dst, Src, S, Eng); 151 } 152 153 /// \brief Run checkers for post-visiting Stmts. 154 void runCheckersForPostStmt(ExplodedNodeSet &Dst, 155 const ExplodedNodeSet &Src, 156 const Stmt *S, 157 ExprEngine &Eng) { 158 runCheckersForStmt(/*isPreVisit=*/false, Dst, Src, S, Eng); 159 } 160 161 /// \brief Run checkers for visiting Stmts. 162 void runCheckersForStmt(bool isPreVisit, 163 ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, 164 const Stmt *S, ExprEngine &Eng); 165 166 /// \brief Run checkers for pre-visiting obj-c messages. 167 void runCheckersForPreObjCMessage(ExplodedNodeSet &Dst, 168 const ExplodedNodeSet &Src, 169 const ObjCMessage &msg, 170 ExprEngine &Eng) { 171 runCheckersForObjCMessage(/*isPreVisit=*/true, Dst, Src, msg, Eng); 172 } 173 174 /// \brief Run checkers for post-visiting obj-c messages. 175 void runCheckersForPostObjCMessage(ExplodedNodeSet &Dst, 176 const ExplodedNodeSet &Src, 177 const ObjCMessage &msg, 178 ExprEngine &Eng) { 179 runCheckersForObjCMessage(/*isPreVisit=*/false, Dst, Src, msg, Eng); 180 } 181 182 /// \brief Run checkers for visiting obj-c messages. 183 void runCheckersForObjCMessage(bool isPreVisit, 184 ExplodedNodeSet &Dst, 185 const ExplodedNodeSet &Src, 186 const ObjCMessage &msg, ExprEngine &Eng); 187 188 /// \brief Run checkers for load/store of a location. 189 void runCheckersForLocation(ExplodedNodeSet &Dst, 190 const ExplodedNodeSet &Src, 191 SVal location, bool isLoad, 192 const Stmt *S, 193 ExprEngine &Eng); 194 195 /// \brief Run checkers for binding of a value to a location. 196 void runCheckersForBind(ExplodedNodeSet &Dst, 197 const ExplodedNodeSet &Src, 198 SVal location, SVal val, 199 const Stmt *S, ExprEngine &Eng); 200 201 /// \brief Run checkers for end of analysis. 202 void runCheckersForEndAnalysis(ExplodedGraph &G, BugReporter &BR, 203 ExprEngine &Eng); 204 205 /// \brief Run checkers for end of path. 206 void runCheckersForEndPath(EndOfFunctionNodeBuilder &B, ExprEngine &Eng); 207 208 /// \brief Run checkers for branch condition. 209 void runCheckersForBranchCondition(const Stmt *condition, 210 BranchNodeBuilder &B, ExprEngine &Eng); 211 212 /// \brief Run checkers for live symbols. 213 void runCheckersForLiveSymbols(const GRState *state, 214 SymbolReaper &SymReaper); 215 216 /// \brief Run checkers for dead symbols. 217 void runCheckersForDeadSymbols(ExplodedNodeSet &Dst, 218 const ExplodedNodeSet &Src, 219 SymbolReaper &SymReaper, const Stmt *S, 220 ExprEngine &Eng); 221 222 /// \brief True if at least one checker wants to check region changes. 223 bool wantsRegionChangeUpdate(const GRState *state); 224 225 /// \brief Run checkers for region changes. 226 const GRState *runCheckersForRegionChanges(const GRState *state, 227 const MemRegion * const *Begin, 228 const MemRegion * const *End); 229 230 /// \brief Run checkers for handling assumptions on symbolic values. 231 const GRState *runCheckersForEvalAssume(const GRState *state, 232 SVal Cond, bool Assumption); 233 234 /// \brief Run checkers for evaluating a call. 235 void runCheckersForEvalCall(ExplodedNodeSet &Dst, 236 const ExplodedNodeSet &Src, 237 const CallExpr *CE, ExprEngine &Eng, 238 GraphExpander *defaultEval = 0); 239 240//===----------------------------------------------------------------------===// 241// Internal registration functions for AST traversing. 242//===----------------------------------------------------------------------===// 243 244 // Functions used by the registration mechanism, checkers should not touch 245 // these directly. 246 247 typedef CheckerFn<const Decl *, AnalysisManager&, BugReporter &> 248 CheckDeclFunc; 249 250 typedef bool (*HandlesDeclFunc)(const Decl *D); 251 void _registerForDecl(CheckDeclFunc checkfn, HandlesDeclFunc isForDeclFn); 252 253 void _registerForBody(CheckDeclFunc checkfn); 254 255//===----------------------------------------------------------------------===// 256// Internal registration functions for path-sensitive checking. 257//===----------------------------------------------------------------------===// 258 259 typedef CheckerFn<const Stmt *, CheckerContext &> CheckStmtFunc; 260 typedef CheckerFn<const ObjCMessage &, CheckerContext &> CheckObjCMessageFunc; 261 typedef CheckerFn<const SVal &/*location*/, bool/*isLoad*/, CheckerContext &> 262 CheckLocationFunc; 263 typedef CheckerFn<const SVal &/*location*/, const SVal &/*val*/, 264 CheckerContext &> CheckBindFunc; 265 typedef CheckerFn<ExplodedGraph &, BugReporter &, ExprEngine &> 266 CheckEndAnalysisFunc; 267 typedef CheckerFn<EndOfFunctionNodeBuilder &, ExprEngine &> CheckEndPathFunc; 268 typedef CheckerFn<const Stmt *, BranchNodeBuilder &, ExprEngine &> 269 CheckBranchConditionFunc; 270 typedef CheckerFn<SymbolReaper &, CheckerContext &> CheckDeadSymbolsFunc; 271 typedef CheckerFn<const GRState *, SymbolReaper &> CheckLiveSymbolsFunc; 272 273 typedef bool (*HandlesStmtFunc)(const Stmt *D); 274 void _registerForPreStmt(CheckStmtFunc checkfn, 275 HandlesStmtFunc isForStmtFn); 276 void _registerForPostStmt(CheckStmtFunc checkfn, 277 HandlesStmtFunc isForStmtFn); 278 279 void _registerForPreObjCMessage(CheckObjCMessageFunc checkfn); 280 void _registerForPostObjCMessage(CheckObjCMessageFunc checkfn); 281 282 void _registerForLocation(CheckLocationFunc checkfn); 283 284 void _registerForBind(CheckBindFunc checkfn); 285 286 void _registerForEndAnalysis(CheckEndAnalysisFunc checkfn); 287 288 void _registerForEndPath(CheckEndPathFunc checkfn); 289 290 void _registerForBranchCondition(CheckBranchConditionFunc checkfn); 291 292 void _registerForLiveSymbols(CheckLiveSymbolsFunc checkfn); 293 294 void _registerForDeadSymbols(CheckDeadSymbolsFunc checkfn); 295 296 class CheckRegionChangesFunc { 297 typedef const GRState * (*Func)(void *, const GRState *, 298 const MemRegion * const *, 299 const MemRegion * const *); 300 Func Fn; 301 public: 302 void *Checker; 303 CheckRegionChangesFunc(void *checker, Func fn) : Fn(fn), Checker(checker) {} 304 const GRState *operator()(const GRState *state, 305 const MemRegion * const *begin, 306 const MemRegion * const *end) { 307 return Fn(Checker, state, begin, end); 308 } 309 }; 310 311 class WantsRegionChangeUpdateFunc { 312 typedef bool (*Func)(void *, const GRState *); 313 Func Fn; 314 public: 315 void *Checker; 316 WantsRegionChangeUpdateFunc(void *checker, Func fn) 317 : Fn(fn), Checker(checker) { } 318 bool operator()(const GRState *state) { 319 return Fn(Checker, state); 320 } 321 }; 322 323 void _registerForRegionChanges(CheckRegionChangesFunc checkfn, 324 WantsRegionChangeUpdateFunc wantUpdateFn); 325 326 class EvalAssumeFunc { 327 typedef const GRState * (*Func)(void *, const GRState *, 328 const SVal &/*cond*/, bool /*assumption*/); 329 Func Fn; 330 public: 331 void *Checker; 332 EvalAssumeFunc(void *checker, Func fn) : Fn(fn), Checker(checker) {} 333 const GRState *operator()(const GRState *state, 334 const SVal &cond, bool assumption) { 335 return Fn(Checker, state, cond, assumption); 336 } 337 }; 338 339 void _registerForEvalAssume(EvalAssumeFunc checkfn); 340 341 class EvalCallFunc { 342 typedef bool (*Func)(void *, const CallExpr *, CheckerContext &); 343 Func Fn; 344 public: 345 void *Checker; 346 EvalCallFunc(void *checker, Func fn) : Fn(fn), Checker(checker) { } 347 bool operator()(const CallExpr *CE, CheckerContext &C) { 348 return Fn(Checker, CE, C); 349 } 350 }; 351 352 void _registerForEvalCall(EvalCallFunc checkfn); 353 354//===----------------------------------------------------------------------===// 355// Internal registration functions for events. 356//===----------------------------------------------------------------------===// 357 358 typedef void *EventTag; 359 360 class CheckEventFunc { 361 typedef void (*Func)(void *, const void *); 362 Func Fn; 363 public: 364 void *Checker; 365 CheckEventFunc(void *checker, Func fn) 366 : Fn(fn), Checker(checker) { } 367 void operator()(const void *event) const { 368 return Fn(Checker, event); 369 } 370 }; 371 372 template <typename EVENT> 373 void _registerListenerForEvent(CheckEventFunc checkfn) { 374 EventInfo &info = Events[getTag<EVENT>()]; 375 info.Checkers.push_back(checkfn); 376 } 377 378 template <typename EVENT> 379 void _registerDispatcherForEvent() { 380 EventInfo &info = Events[getTag<EVENT>()]; 381 info.HasDispatcher = true; 382 } 383 384 template <typename EVENT> 385 void _dispatchEvent(const EVENT &event) const { 386 EventsTy::const_iterator I = Events.find(getTag<EVENT>()); 387 if (I == Events.end()) 388 return; 389 const EventInfo &info = I->second; 390 for (unsigned i = 0, e = info.Checkers.size(); i != e; ++i) 391 info.Checkers[i](&event); 392 } 393 394//===----------------------------------------------------------------------===// 395// Implementation details. 396//===----------------------------------------------------------------------===// 397 398private: 399 template <typename CHECKER> 400 static void destruct(void *obj) { delete static_cast<CHECKER *>(obj); } 401 402 template <typename T> 403 static void *getTag() { static int tag; return &tag; } 404 405 llvm::DenseMap<CheckerTag, CheckerRef> CheckerTags; 406 407 std::vector<CheckerDtor> CheckerDtors; 408 409 struct DeclCheckerInfo { 410 CheckDeclFunc CheckFn; 411 HandlesDeclFunc IsForDeclFn; 412 }; 413 std::vector<DeclCheckerInfo> DeclCheckers; 414 415 std::vector<CheckDeclFunc> BodyCheckers; 416 417 typedef llvm::SmallVector<CheckDeclFunc, 4> CachedDeclCheckers; 418 typedef llvm::DenseMap<unsigned, CachedDeclCheckers> CachedDeclCheckersMapTy; 419 CachedDeclCheckersMapTy CachedDeclCheckersMap; 420 421 struct StmtCheckerInfo { 422 CheckStmtFunc CheckFn; 423 HandlesStmtFunc IsForStmtFn; 424 bool IsPreVisit; 425 }; 426 std::vector<StmtCheckerInfo> StmtCheckers; 427 428 struct CachedStmtCheckersKey { 429 unsigned StmtKind; 430 bool IsPreVisit; 431 432 CachedStmtCheckersKey() : StmtKind(0), IsPreVisit(0) { } 433 CachedStmtCheckersKey(unsigned stmtKind, bool isPreVisit) 434 : StmtKind(stmtKind), IsPreVisit(isPreVisit) { } 435 436 static CachedStmtCheckersKey getSentinel() { 437 return CachedStmtCheckersKey(~0U, 0); 438 } 439 unsigned getHashValue() const { 440 llvm::FoldingSetNodeID ID; 441 ID.AddInteger(StmtKind); 442 ID.AddBoolean(IsPreVisit); 443 return ID.ComputeHash(); 444 } 445 bool operator==(const CachedStmtCheckersKey &RHS) const { 446 return StmtKind == RHS.StmtKind && IsPreVisit == RHS.IsPreVisit; 447 } 448 }; 449 friend struct llvm::DenseMapInfo<CachedStmtCheckersKey>; 450 451 typedef llvm::SmallVector<CheckStmtFunc, 4> CachedStmtCheckers; 452 typedef llvm::DenseMap<CachedStmtCheckersKey, CachedStmtCheckers> 453 CachedStmtCheckersMapTy; 454 CachedStmtCheckersMapTy CachedStmtCheckersMap; 455 456 CachedStmtCheckers *getCachedStmtCheckersFor(const Stmt *S, bool isPreVisit); 457 458 std::vector<CheckObjCMessageFunc> PreObjCMessageCheckers; 459 std::vector<CheckObjCMessageFunc> PostObjCMessageCheckers; 460 461 std::vector<CheckLocationFunc> LocationCheckers; 462 463 std::vector<CheckBindFunc> BindCheckers; 464 465 std::vector<CheckEndAnalysisFunc> EndAnalysisCheckers; 466 467 std::vector<CheckEndPathFunc> EndPathCheckers; 468 469 std::vector<CheckBranchConditionFunc> BranchConditionCheckers; 470 471 std::vector<CheckLiveSymbolsFunc> LiveSymbolsCheckers; 472 473 std::vector<CheckDeadSymbolsFunc> DeadSymbolsCheckers; 474 475 struct RegionChangesCheckerInfo { 476 CheckRegionChangesFunc CheckFn; 477 WantsRegionChangeUpdateFunc WantUpdateFn; 478 }; 479 std::vector<RegionChangesCheckerInfo> RegionChangesCheckers; 480 481 std::vector<EvalAssumeFunc> EvalAssumeCheckers; 482 483 std::vector<EvalCallFunc> EvalCallCheckers; 484 485 struct EventInfo { 486 llvm::SmallVector<CheckEventFunc, 4> Checkers; 487 bool HasDispatcher; 488 EventInfo() : HasDispatcher(false) { } 489 }; 490 491 typedef llvm::DenseMap<EventTag, EventInfo> EventsTy; 492 EventsTy Events; 493}; 494 495} // end ento namespace 496 497} // end clang namespace 498 499namespace llvm { 500 /// Define DenseMapInfo so that CachedStmtCheckersKey can be used as key 501 /// in DenseMap and DenseSets. 502 template <> 503 struct DenseMapInfo<clang::ento::CheckerManager::CachedStmtCheckersKey> { 504 static inline clang::ento::CheckerManager::CachedStmtCheckersKey 505 getEmptyKey() { 506 return clang::ento::CheckerManager::CachedStmtCheckersKey(); 507 } 508 static inline clang::ento::CheckerManager::CachedStmtCheckersKey 509 getTombstoneKey() { 510 return clang::ento::CheckerManager::CachedStmtCheckersKey::getSentinel(); 511 } 512 513 static unsigned 514 getHashValue(clang::ento::CheckerManager::CachedStmtCheckersKey S) { 515 return S.getHashValue(); 516 } 517 518 static bool isEqual(clang::ento::CheckerManager::CachedStmtCheckersKey LHS, 519 clang::ento::CheckerManager::CachedStmtCheckersKey RHS) { 520 return LHS == RHS; 521 } 522 }; 523} // end namespace llvm 524 525#endif 526