summaryrefslogtreecommitdiff
path: root/clang-r353983e/include/clang/StaticAnalyzer/Core/Checker.h
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2019-07-02 16:25:20 -0700
committerAli B <abittin@gmail.com>2019-07-05 19:33:16 +0300
commit9afee4e65dc5f9f5eb371683729ff67b8df81d03 (patch)
tree4cf241d6c9044f91ee8c06e6920174d06f8de0b6 /clang-r353983e/include/clang/StaticAnalyzer/Core/Checker.h
parent2f19bd722c4c825320d1511c1ed83161b7f95d51 (diff)
Update prebuilt Clang to r353983e.HEADq10.0
clang 9.0.5 (based on r353983e) from build 5696680. Bug: http://b/135931688 Bug: http://b/136008926 Test: N/A Change-Id: I922d17410047d2e2df4625615352c588ee71b203
Diffstat (limited to 'clang-r353983e/include/clang/StaticAnalyzer/Core/Checker.h')
-rw-r--r--clang-r353983e/include/clang/StaticAnalyzer/Core/Checker.h581
1 files changed, 581 insertions, 0 deletions
diff --git a/clang-r353983e/include/clang/StaticAnalyzer/Core/Checker.h b/clang-r353983e/include/clang/StaticAnalyzer/Core/Checker.h
new file mode 100644
index 00000000..db3ae74f
--- /dev/null
+++ b/clang-r353983e/include/clang/StaticAnalyzer/Core/Checker.h
@@ -0,0 +1,581 @@
+//== Checker.h - Registration mechanism for checkers -------------*- C++ -*--=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines Checker, used to create and register checkers.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H
+#define LLVM_CLANG_STATICANALYZER_CORE_CHECKER_H
+
+#include "clang/Analysis/ProgramPoint.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/StaticAnalyzer/Core/CheckerManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/Support/Casting.h"
+
+namespace clang {
+namespace ento {
+ class BugReporter;
+
+namespace check {
+
+template <typename DECL>
+class ASTDecl {
+ template <typename CHECKER>
+ static void _checkDecl(void *checker, const Decl *D, AnalysisManager& mgr,
+ BugReporter &BR) {
+ ((const CHECKER *)checker)->checkASTDecl(cast<DECL>(D), mgr, BR);
+ }
+
+ static bool _handlesDecl(const Decl *D) {
+ return isa<DECL>(D);
+ }
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForDecl(CheckerManager::CheckDeclFunc(checker,
+ _checkDecl<CHECKER>),
+ _handlesDecl);
+ }
+};
+
+class ASTCodeBody {
+ template <typename CHECKER>
+ static void _checkBody(void *checker, const Decl *D, AnalysisManager& mgr,
+ BugReporter &BR) {
+ ((const CHECKER *)checker)->checkASTCodeBody(D, mgr, BR);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForBody(CheckerManager::CheckDeclFunc(checker,
+ _checkBody<CHECKER>));
+ }
+};
+
+class EndOfTranslationUnit {
+ template <typename CHECKER>
+ static void _checkEndOfTranslationUnit(void *checker,
+ const TranslationUnitDecl *TU,
+ AnalysisManager& mgr,
+ BugReporter &BR) {
+ ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr){
+ mgr._registerForEndOfTranslationUnit(
+ CheckerManager::CheckEndOfTranslationUnit(checker,
+ _checkEndOfTranslationUnit<CHECKER>));
+ }
+};
+
+template <typename STMT>
+class PreStmt {
+ template <typename CHECKER>
+ static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
+ ((const CHECKER *)checker)->checkPreStmt(cast<STMT>(S), C);
+ }
+
+ static bool _handlesStmt(const Stmt *S) {
+ return isa<STMT>(S);
+ }
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForPreStmt(CheckerManager::CheckStmtFunc(checker,
+ _checkStmt<CHECKER>),
+ _handlesStmt);
+ }
+};
+
+template <typename STMT>
+class PostStmt {
+ template <typename CHECKER>
+ static void _checkStmt(void *checker, const Stmt *S, CheckerContext &C) {
+ ((const CHECKER *)checker)->checkPostStmt(cast<STMT>(S), C);
+ }
+
+ static bool _handlesStmt(const Stmt *S) {
+ return isa<STMT>(S);
+ }
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForPostStmt(CheckerManager::CheckStmtFunc(checker,
+ _checkStmt<CHECKER>),
+ _handlesStmt);
+ }
+};
+
+class PreObjCMessage {
+ template <typename CHECKER>
+ static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
+ CheckerContext &C) {
+ ((const CHECKER *)checker)->checkPreObjCMessage(msg, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForPreObjCMessage(
+ CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
+ }
+};
+
+class ObjCMessageNil {
+ template <typename CHECKER>
+ static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
+ CheckerContext &C) {
+ ((const CHECKER *)checker)->checkObjCMessageNil(msg, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForObjCMessageNil(
+ CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
+ }
+};
+
+class PostObjCMessage {
+ template <typename CHECKER>
+ static void _checkObjCMessage(void *checker, const ObjCMethodCall &msg,
+ CheckerContext &C) {
+ ((const CHECKER *)checker)->checkPostObjCMessage(msg, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForPostObjCMessage(
+ CheckerManager::CheckObjCMessageFunc(checker, _checkObjCMessage<CHECKER>));
+ }
+};
+
+class PreCall {
+ template <typename CHECKER>
+ static void _checkCall(void *checker, const CallEvent &msg,
+ CheckerContext &C) {
+ ((const CHECKER *)checker)->checkPreCall(msg, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForPreCall(
+ CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
+ }
+};
+
+class PostCall {
+ template <typename CHECKER>
+ static void _checkCall(void *checker, const CallEvent &msg,
+ CheckerContext &C) {
+ ((const CHECKER *)checker)->checkPostCall(msg, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForPostCall(
+ CheckerManager::CheckCallFunc(checker, _checkCall<CHECKER>));
+ }
+};
+
+class Location {
+ template <typename CHECKER>
+ static void _checkLocation(void *checker,
+ const SVal &location, bool isLoad, const Stmt *S,
+ CheckerContext &C) {
+ ((const CHECKER *)checker)->checkLocation(location, isLoad, S, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForLocation(
+ CheckerManager::CheckLocationFunc(checker, _checkLocation<CHECKER>));
+ }
+};
+
+class Bind {
+ template <typename CHECKER>
+ static void _checkBind(void *checker,
+ const SVal &location, const SVal &val, const Stmt *S,
+ CheckerContext &C) {
+ ((const CHECKER *)checker)->checkBind(location, val, S, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForBind(
+ CheckerManager::CheckBindFunc(checker, _checkBind<CHECKER>));
+ }
+};
+
+class EndAnalysis {
+ template <typename CHECKER>
+ static void _checkEndAnalysis(void *checker, ExplodedGraph &G,
+ BugReporter &BR, ExprEngine &Eng) {
+ ((const CHECKER *)checker)->checkEndAnalysis(G, BR, Eng);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForEndAnalysis(
+ CheckerManager::CheckEndAnalysisFunc(checker, _checkEndAnalysis<CHECKER>));
+ }
+};
+
+class BeginFunction {
+ template <typename CHECKER>
+ static void _checkBeginFunction(void *checker, CheckerContext &C) {
+ ((const CHECKER *)checker)->checkBeginFunction(C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForBeginFunction(CheckerManager::CheckBeginFunctionFunc(
+ checker, _checkBeginFunction<CHECKER>));
+ }
+};
+
+class EndFunction {
+ template <typename CHECKER>
+ static void _checkEndFunction(void *checker, const ReturnStmt *RS,
+ CheckerContext &C) {
+ ((const CHECKER *)checker)->checkEndFunction(RS, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForEndFunction(
+ CheckerManager::CheckEndFunctionFunc(checker, _checkEndFunction<CHECKER>));
+ }
+};
+
+class BranchCondition {
+ template <typename CHECKER>
+ static void _checkBranchCondition(void *checker, const Stmt *Condition,
+ CheckerContext & C) {
+ ((const CHECKER *)checker)->checkBranchCondition(Condition, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForBranchCondition(
+ CheckerManager::CheckBranchConditionFunc(checker,
+ _checkBranchCondition<CHECKER>));
+ }
+};
+
+class NewAllocator {
+ template <typename CHECKER>
+ static void _checkNewAllocator(void *checker, const CXXNewExpr *NE,
+ SVal Target, CheckerContext &C) {
+ ((const CHECKER *)checker)->checkNewAllocator(NE, Target, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForNewAllocator(
+ CheckerManager::CheckNewAllocatorFunc(checker,
+ _checkNewAllocator<CHECKER>));
+ }
+};
+
+class LiveSymbols {
+ template <typename CHECKER>
+ static void _checkLiveSymbols(void *checker, ProgramStateRef state,
+ SymbolReaper &SR) {
+ ((const CHECKER *)checker)->checkLiveSymbols(state, SR);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForLiveSymbols(
+ CheckerManager::CheckLiveSymbolsFunc(checker, _checkLiveSymbols<CHECKER>));
+ }
+};
+
+class DeadSymbols {
+ template <typename CHECKER>
+ static void _checkDeadSymbols(void *checker,
+ SymbolReaper &SR, CheckerContext &C) {
+ ((const CHECKER *)checker)->checkDeadSymbols(SR, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForDeadSymbols(
+ CheckerManager::CheckDeadSymbolsFunc(checker, _checkDeadSymbols<CHECKER>));
+ }
+};
+
+class RegionChanges {
+ template <typename CHECKER>
+ static ProgramStateRef
+ _checkRegionChanges(void *checker,
+ ProgramStateRef state,
+ const InvalidatedSymbols *invalidated,
+ ArrayRef<const MemRegion *> Explicits,
+ ArrayRef<const MemRegion *> Regions,
+ const LocationContext *LCtx,
+ const CallEvent *Call) {
+ return ((const CHECKER *) checker)->checkRegionChanges(state, invalidated,
+ Explicits, Regions,
+ LCtx, Call);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForRegionChanges(
+ CheckerManager::CheckRegionChangesFunc(checker,
+ _checkRegionChanges<CHECKER>));
+ }
+};
+
+class PointerEscape {
+ template <typename CHECKER>
+ static ProgramStateRef
+ _checkPointerEscape(void *Checker,
+ ProgramStateRef State,
+ const InvalidatedSymbols &Escaped,
+ const CallEvent *Call,
+ PointerEscapeKind Kind,
+ RegionAndSymbolInvalidationTraits *ETraits) {
+
+ if (!ETraits)
+ return ((const CHECKER *)Checker)->checkPointerEscape(State,
+ Escaped,
+ Call,
+ Kind);
+
+ InvalidatedSymbols RegularEscape;
+ for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
+ E = Escaped.end(); I != E; ++I)
+ if (!ETraits->hasTrait(*I,
+ RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
+ !ETraits->hasTrait(*I,
+ RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
+ RegularEscape.insert(*I);
+
+ if (RegularEscape.empty())
+ return State;
+
+ return ((const CHECKER *)Checker)->checkPointerEscape(State,
+ RegularEscape,
+ Call,
+ Kind);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForPointerEscape(
+ CheckerManager::CheckPointerEscapeFunc(checker,
+ _checkPointerEscape<CHECKER>));
+ }
+};
+
+class ConstPointerEscape {
+ template <typename CHECKER>
+ static ProgramStateRef
+ _checkConstPointerEscape(void *Checker,
+ ProgramStateRef State,
+ const InvalidatedSymbols &Escaped,
+ const CallEvent *Call,
+ PointerEscapeKind Kind,
+ RegionAndSymbolInvalidationTraits *ETraits) {
+
+ if (!ETraits)
+ return State;
+
+ InvalidatedSymbols ConstEscape;
+ for (InvalidatedSymbols::const_iterator I = Escaped.begin(),
+ E = Escaped.end(); I != E; ++I)
+ if (ETraits->hasTrait(*I,
+ RegionAndSymbolInvalidationTraits::TK_PreserveContents) &&
+ !ETraits->hasTrait(*I,
+ RegionAndSymbolInvalidationTraits::TK_SuppressEscape))
+ ConstEscape.insert(*I);
+
+ if (ConstEscape.empty())
+ return State;
+
+ return ((const CHECKER *)Checker)->checkConstPointerEscape(State,
+ ConstEscape,
+ Call,
+ Kind);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForPointerEscape(
+ CheckerManager::CheckPointerEscapeFunc(checker,
+ _checkConstPointerEscape<CHECKER>));
+ }
+};
+
+
+template <typename EVENT>
+class Event {
+ template <typename CHECKER>
+ static void _checkEvent(void *checker, const void *event) {
+ ((const CHECKER *)checker)->checkEvent(*(const EVENT *)event);
+ }
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerListenerForEvent<EVENT>(
+ CheckerManager::CheckEventFunc(checker, _checkEvent<CHECKER>));
+ }
+};
+
+} // end check namespace
+
+namespace eval {
+
+class Assume {
+ template <typename CHECKER>
+ static ProgramStateRef _evalAssume(void *checker,
+ ProgramStateRef state,
+ const SVal &cond,
+ bool assumption) {
+ return ((const CHECKER *)checker)->evalAssume(state, cond, assumption);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForEvalAssume(
+ CheckerManager::EvalAssumeFunc(checker, _evalAssume<CHECKER>));
+ }
+};
+
+class Call {
+ template <typename CHECKER>
+ static bool _evalCall(void *checker, const CallExpr *CE, CheckerContext &C) {
+ return ((const CHECKER *)checker)->evalCall(CE, C);
+ }
+
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerForEvalCall(
+ CheckerManager::EvalCallFunc(checker, _evalCall<CHECKER>));
+ }
+};
+
+} // end eval namespace
+
+class CheckerBase : public ProgramPointTag {
+ CheckName Name;
+ friend class ::clang::ento::CheckerManager;
+
+public:
+ StringRef getTagDescription() const override;
+ CheckName getCheckName() const;
+
+ /// See CheckerManager::runCheckersForPrintState.
+ virtual void printState(raw_ostream &Out, ProgramStateRef State,
+ const char *NL, const char *Sep) const { }
+};
+
+/// Dump checker name to stream.
+raw_ostream& operator<<(raw_ostream &Out, const CheckerBase &Checker);
+
+/// Tag that can use a checker name as a message provider
+/// (see SimpleProgramPointTag).
+class CheckerProgramPointTag : public SimpleProgramPointTag {
+public:
+ CheckerProgramPointTag(StringRef CheckerName, StringRef Msg);
+ CheckerProgramPointTag(const CheckerBase *Checker, StringRef Msg);
+};
+
+template <typename CHECK1, typename... CHECKs>
+class Checker : public CHECK1, public CHECKs..., public CheckerBase {
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ CHECK1::_register(checker, mgr);
+ Checker<CHECKs...>::_register(checker, mgr);
+ }
+};
+
+template <typename CHECK1>
+class Checker<CHECK1> : public CHECK1, public CheckerBase {
+public:
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ CHECK1::_register(checker, mgr);
+ }
+};
+
+template <typename EVENT>
+class EventDispatcher {
+ CheckerManager *Mgr;
+public:
+ EventDispatcher() : Mgr(nullptr) { }
+
+ template <typename CHECKER>
+ static void _register(CHECKER *checker, CheckerManager &mgr) {
+ mgr._registerDispatcherForEvent<EVENT>();
+ static_cast<EventDispatcher<EVENT> *>(checker)->Mgr = &mgr;
+ }
+
+ void dispatchEvent(const EVENT &event) const {
+ Mgr->_dispatchEvent(event);
+ }
+};
+
+/// We dereferenced a location that may be null.
+struct ImplicitNullDerefEvent {
+ SVal Location;
+ bool IsLoad;
+ ExplodedNode *SinkNode;
+ BugReporter *BR;
+ // When true, the dereference is in the source code directly. When false, the
+ // dereference might happen later (for example pointer passed to a parameter
+ // that is marked with nonnull attribute.)
+ bool IsDirectDereference;
+
+ static int Tag;
+};
+
+/// A helper class which wraps a boolean value set to false by default.
+///
+/// This class should behave exactly like 'bool' except that it doesn't need to
+/// be explicitly initialized.
+struct DefaultBool {
+ bool val;
+ DefaultBool() : val(false) {}
+ /*implicit*/ operator bool&() { return val; }
+ /*implicit*/ operator const bool&() const { return val; }
+ DefaultBool &operator=(bool b) { val = b; return *this; }
+};
+
+} // end ento namespace
+
+} // end clang namespace
+
+#endif