diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2018-08-02 17:33:11 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2018-08-02 17:33:11 +0000 |
commit | c7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (patch) | |
tree | 27425930fc0c91650a7f3527fcac8e0f92907b90 /include/clang/StaticAnalyzer/Core | |
parent | 486754660bb926339aefcf012a3f848592babb8b (diff) | |
download | src-c7e70c433efc6953dc3888b9fbf9f3512d7da2b0.tar.gz src-c7e70c433efc6953dc3888b9fbf9f3512d7da2b0.zip |
Vendor import of clang trunk r338536:vendor/clang/clang-trunk-r338536
Notes
Notes:
svn path=/vendor/clang/dist/; revision=337139
svn path=/vendor/clang/clang-trunk-r338536/; revision=337140; tag=vendor/clang/clang-trunk-r338536
Diffstat (limited to 'include/clang/StaticAnalyzer/Core')
30 files changed, 278 insertions, 233 deletions
diff --git a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h index 9d292cfddb0c..7586f7e0835b 100644 --- a/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h +++ b/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h @@ -130,23 +130,23 @@ public: /// Pair of checker name and enable/disable. std::vector<std::pair<std::string, bool>> CheckersControlList; - + /// A key-value table of use-specified configuration values. ConfigTable Config; AnalysisStores AnalysisStoreOpt = RegionStoreModel; AnalysisConstraints AnalysisConstraintsOpt = RangeConstraintsModel; AnalysisDiagClients AnalysisDiagOpt = PD_HTML; AnalysisPurgeMode AnalysisPurgeOpt = PurgeStmt; - + std::string AnalyzeSpecificFunction; /// Store full compiler invocation for reproducible instructions in the /// generated report. std::string FullCompilerInvocation; - + /// The maximum number of times the analyzer visits a block. unsigned maxBlockVisitOnPath; - + /// Disable all analyzer checks. /// /// This flag allows one to disable analyzer checks on the code processed by @@ -170,21 +170,21 @@ public: /// precision until we have a better way to lazily evaluate such logic. The /// downside is that it eagerly bifurcates paths. unsigned eagerlyAssumeBinOpBifurcation : 1; - + unsigned TrimGraph : 1; unsigned visualizeExplodedGraphWithGraphViz : 1; unsigned visualizeExplodedGraphWithUbiGraph : 1; unsigned UnoptimizedCFG : 1; unsigned PrintStats : 1; - + /// Do not re-analyze paths leading to exhausted nodes with a different /// strategy. We get better code coverage when retry is enabled. unsigned NoRetryExhausted : 1; - + /// The inlining stack depth limit. // Cap the stack depth at 4 calls (5 stack frames, base + 4 calls). unsigned InlineMaxStackDepth = 5; - + /// The mode of function selection used during inlining. AnalysisInliningMode InliningMode = NoRedundancy; @@ -211,7 +211,7 @@ private: UMK_Deep = 2 }; - /// Controls the high-level analyzer mode, which influences the default + /// Controls the high-level analyzer mode, which influences the default /// settings for some of the lower-level config options (such as IPAMode). /// \sa getUserMode UserModeKind UserMode = UMK_NotSet; @@ -221,7 +221,7 @@ private: /// Controls which C++ member functions will be considered for inlining. CXXInlineableMemberKind CXXMemberInliningMode; - + /// \sa includeImplicitDtorsInCFG Optional<bool> IncludeImplicitDtorsInCFG; @@ -239,7 +239,7 @@ private: /// \sa mayInlineCXXStandardLibrary Optional<bool> InlineCXXStandardLibrary; - + /// \sa includeScopesInCFG Optional<bool> IncludeScopesInCFG; @@ -722,9 +722,9 @@ public: /// the option will be ignored. bool shouldElideConstructors(); }; - + using AnalyzerOptionsRef = IntrusiveRefCntPtr<AnalyzerOptions>; - + } // namespace clang #endif // LLVM_CLANG_STATICANALYZER_CORE_ANALYZEROPTIONS_H diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h index 111e1d1e8e20..9041f4c1afbd 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -74,7 +74,7 @@ using DiagnosticForConsumerMapTy = /// This class provides an interface through which checkers can create /// individual bug reports. class BugReport : public llvm::ilist_node<BugReport> { -public: +public: class NodeResolver { virtual void anchor(); @@ -102,7 +102,7 @@ protected: PathDiagnosticLocation Location; PathDiagnosticLocation UniqueingLocation; const Decl *UniqueingDecl; - + const ExplodedNode *ErrorNode = nullptr; SmallVector<SourceRange, 4> Ranges; ExtraTextList ExtraText; @@ -220,12 +220,12 @@ public: /// Disable all path pruning when generating a PathDiagnostic. void disablePathPruning() { DoNotPrunePath = true; } - + void markInteresting(SymbolRef sym); void markInteresting(const MemRegion *R); void markInteresting(SVal V); void markInteresting(const LocationContext *LC); - + bool isInteresting(SymbolRef sym); bool isInteresting(const MemRegion *R); bool isInteresting(SVal V); @@ -251,11 +251,11 @@ public: void markInvalid(const void *Tag, const void *Data) { Invalidations.insert(std::make_pair(Tag, Data)); } - + /// Return the canonical declaration, be it a method or class, where /// this issue semantically occurred. const Decl *getDeclWithIssue() const; - + /// Specifically set the Decl where an issue occurred. This isn't necessary /// for BugReports that cover a path as it will be automatically inferred. void setDeclWithIssue(const Decl *declWithIssue) { @@ -290,7 +290,7 @@ public: /// This allows for addition of meta data to the diagnostic. /// - /// Currently, only the HTMLDiagnosticClient knows how to display it. + /// Currently, only the HTMLDiagnosticClient knows how to display it. void addExtraText(StringRef S) { ExtraText.push_back(S); } @@ -310,7 +310,7 @@ public: PathDiagnosticLocation getUniqueingLocation() const { return UniqueingLocation; } - + /// Get the declaration containing the uniqueing location. const Decl *getUniqueingDecl() const { return UniqueingDecl; diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h index 92118b0fbee2..da019f83c214 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h @@ -246,7 +246,7 @@ public: BugReport &BR) override; }; -/// When a region containing undefined value or '0' value is passed +/// When a region containing undefined value or '0' value is passed /// as an argument in a call, marks the call as interesting. /// /// As a result, BugReporter will not prune the path through the function even diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h index c723f31aec26..3c1f8f718a3b 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/BugType.h @@ -52,7 +52,7 @@ public: // FIXME: This is a workaround to ensure that the correct check name is used // The check names are set after the constructors are run. // In case the BugType object is initialized in the checker's ctor - // the Check field will be empty. To circumvent this problem we use + // the Check field will be empty. To circumvent this problem we use // CheckerBase whenever it is possible. StringRef CheckName = Checker ? Checker->getCheckName().getName() : Check.getName(); diff --git a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h index b18d3c9b3031..b0bb12feba20 100644 --- a/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h +++ b/include/clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h @@ -71,17 +71,17 @@ public: PDFileEntry(llvm::FoldingSetNodeID &NodeID) : NodeID(NodeID) {} using ConsumerFiles = std::vector<std::pair<StringRef, StringRef>>; - + /// A vector of <consumer,file> pairs. ConsumerFiles files; - + /// A precomputed hash tag used for uniquing PDFileEntry objects. const llvm::FoldingSetNodeID NodeID; /// Used for profiling in the FoldingSet. void Profile(llvm::FoldingSetNodeID &ID) { ID = NodeID; } }; - + class FilesMade { llvm::BumpPtrAllocator Alloc; llvm::FoldingSet<PDFileEntry> Set; @@ -94,7 +94,7 @@ public: void addDiagnostic(const PathDiagnostic &PD, StringRef ConsumerName, StringRef fileName); - + PDFileEntry::ConsumerFiles *getFiles(const PathDiagnostic &PD); }; @@ -127,7 +127,7 @@ public: virtual PathGenerationScheme getGenerationScheme() const { return Minimal; } virtual bool supportsLogicalOpControlFlow() const { return false; } - + /// Return true if the PathDiagnosticConsumer supports individual /// PathDiagnostics that span multiple files. virtual bool supportsCrossFileDiagnostics() const { return false; } @@ -322,12 +322,12 @@ public: void flatten(); const SourceManager& getManager() const { assert(isValid()); return *SM; } - + void Profile(llvm::FoldingSetNodeID &ID) const; void dump() const; - /// Given an exploded node, retrieve the statement that should be used + /// Given an exploded node, retrieve the statement that should be used /// for the diagnostic location. static const Stmt *getStmt(const ExplodedNode *N); @@ -354,7 +354,7 @@ public: Start.flatten(); End.flatten(); } - + void Profile(llvm::FoldingSetNodeID &ID) const { Start.Profile(ID); End.Profile(ID); @@ -378,7 +378,7 @@ private: /// In the containing bug report, this piece is the last piece from /// the main source file. bool LastInMainSourceFile = false; - + /// A constant string that can be used to tag the PathDiagnosticPiece, /// typically with the identification of the creator. The actual pointer /// value is meant to be an identifier; the string itself is useful for @@ -401,14 +401,14 @@ public: /// Tag this PathDiagnosticPiece with the given C-string. void setTag(const char *tag) { Tag = tag; } - + /// Return the opaque tag (if any) on the PathDiagnosticPiece. const void *getTag() const { return Tag.data(); } - + /// Return the string representation of the tag. This is useful /// for debugging. StringRef getTagStr() const { return Tag; } - + /// getDisplayHint - Return a hint indicating where the diagnostic should /// be displayed by the PathDiagnosticConsumer. DisplayHint getDisplayHint() const { return Hint; } @@ -488,7 +488,7 @@ public: /// Interface for classes constructing Stack hints. /// -/// If a PathDiagnosticEvent occurs in a different frame than the final +/// If a PathDiagnosticEvent occurs in a different frame than the final /// diagnostic the hints can be used to summarize the effect of the call. class StackHintGenerator { public: @@ -563,12 +563,12 @@ public: bool hasCallStackHint() { return (bool)CallStackHint; } - /// Produce the hint for the given node. The node contains + /// Produce the hint for the given node. The node contains /// information about the call for which the diagnostic can be generated. std::string getCallStackMessage(const ExplodedNode *N) { if (CallStackHint) return CallStackHint->getMessage(N); - return {}; + return {}; } void dump() const override; @@ -605,16 +605,16 @@ class PathDiagnosticCallPiece : public PathDiagnosticPiece { public: PathDiagnosticLocation callEnter; PathDiagnosticLocation callEnterWithin; - PathDiagnosticLocation callReturn; + PathDiagnosticLocation callReturn; PathPieces path; ~PathDiagnosticCallPiece() override; const Decl *getCaller() const { return Caller; } - + const Decl *getCallee() const { return Callee; } void setCallee(const CallEnter &CE, const SourceManager &SM); - + bool hasCallStackMessage() { return !CallStackMessage.empty(); } void setCallStackMessage(StringRef st) { CallStackMessage = st; } @@ -725,7 +725,7 @@ public: ~PathDiagnosticMacroPiece() override; PathPieces subPieces; - + bool containsEvent() const; void flattenLocations() override { @@ -779,7 +779,7 @@ class PathDiagnostic : public llvm::FoldingSetNode { PathPieces pathImpl; SmallVector<PathPieces *, 3> pathStack; - + /// Important bug uniqueing location. /// The location info is useful to differentiate between bugs. PathDiagnosticLocation UniqueingLoc; @@ -796,22 +796,22 @@ public: const Decl *DeclToUnique, std::unique_ptr<FilesToLineNumsMap> ExecutedLines); ~PathDiagnostic(); - + const PathPieces &path; - /// Return the path currently used by builders for constructing the + /// Return the path currently used by builders for constructing the /// PathDiagnostic. PathPieces &getActivePath() { if (pathStack.empty()) return pathImpl; return *pathStack.back(); } - + /// Return a mutable version of 'path'. PathPieces &getMutablePieces() { return pathImpl; } - + /// Return the unrolled size of the path. unsigned full_size(); @@ -898,7 +898,7 @@ public: /// Two diagnostics with the same issue along different paths will generate /// different profiles. void FullProfile(llvm::FoldingSetNodeID &ID) const; -}; +}; } // namespace ento diff --git a/include/clang/StaticAnalyzer/Core/Checker.h b/include/clang/StaticAnalyzer/Core/Checker.h index 45b7a61139ea..8484cfe4c956 100644 --- a/include/clang/StaticAnalyzer/Core/Checker.h +++ b/include/clang/StaticAnalyzer/Core/Checker.h @@ -63,7 +63,7 @@ public: class EndOfTranslationUnit { template <typename CHECKER> static void _checkEndOfTranslationUnit(void *checker, - const TranslationUnitDecl *TU, + const TranslationUnitDecl *TU, AnalysisManager& mgr, BugReporter &BR) { ((const CHECKER *)checker)->checkEndOfTranslationUnit(TU, mgr, BR); @@ -331,7 +331,7 @@ public: class RegionChanges { template <typename CHECKER> - static ProgramStateRef + static ProgramStateRef _checkRegionChanges(void *checker, ProgramStateRef state, const InvalidatedSymbols *invalidated, @@ -370,7 +370,7 @@ class PointerEscape { Kind); InvalidatedSymbols RegularEscape; - for (InvalidatedSymbols::const_iterator I = Escaped.begin(), + for (InvalidatedSymbols::const_iterator I = Escaped.begin(), E = Escaped.end(); I != E; ++I) if (!ETraits->hasTrait(*I, RegionAndSymbolInvalidationTraits::TK_PreserveContents) && @@ -410,7 +410,7 @@ class ConstPointerEscape { return State; InvalidatedSymbols ConstEscape; - for (InvalidatedSymbols::const_iterator I = Escaped.begin(), + for (InvalidatedSymbols::const_iterator I = Escaped.begin(), E = Escaped.end(); I != E; ++I) if (ETraits->hasTrait(*I, RegionAndSymbolInvalidationTraits::TK_PreserveContents) && @@ -436,7 +436,7 @@ public: } }; - + template <typename EVENT> class Event { template <typename CHECKER> @@ -504,7 +504,7 @@ public: /// 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 +/// Tag that can use a checker name as a message provider /// (see SimpleProgramPointTag). class CheckerProgramPointTag : public SimpleProgramPointTag { public: diff --git a/include/clang/StaticAnalyzer/Core/CheckerManager.h b/include/clang/StaticAnalyzer/Core/CheckerManager.h index 33a794061a38..7c353326be46 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerManager.h +++ b/include/clang/StaticAnalyzer/Core/CheckerManager.h @@ -86,7 +86,7 @@ enum PointerEscapeKind { /// argument to a function. PSK_IndirectEscapeOnCall, - /// The reason for pointer escape is unknown. For example, + /// The reason for pointer escape is unknown. For example, /// a region containing this pointer is invalidated. PSK_EscapeOther }; @@ -353,18 +353,18 @@ public: /// /// This notifies the checkers about pointer escape, which occurs whenever /// the analyzer cannot track the symbol any more. For example, as a - /// result of assigning a pointer into a global or when it's passed to a + /// result of assigning a pointer into a global or when it's passed to a /// function call the analyzer cannot model. - /// + /// /// \param State The state at the point of escape. /// \param Escaped The list of escaped symbols. - /// \param Call The corresponding CallEvent, if the symbols escape as + /// \param Call The corresponding CallEvent, if the symbols escape as /// parameters to the given call. /// \param Kind The reason of pointer escape. - /// \param ITraits Information about invalidation for a particular + /// \param ITraits Information about invalidation for a particular /// region/symbol. /// \returns Checkers can modify the state by returning a new one. - ProgramStateRef + ProgramStateRef runCheckersForPointerEscape(ProgramStateRef State, const InvalidatedSymbols &Escaped, const CallEvent *Call, @@ -381,7 +381,7 @@ public: void runCheckersForEvalCall(ExplodedNodeSet &Dst, const ExplodedNodeSet &Src, const CallEvent &CE, ExprEngine &Eng); - + /// Run checkers for the entire Translation Unit. void runCheckersOnEndOfTranslationUnit(const TranslationUnitDecl *TU, AnalysisManager &mgr, @@ -419,21 +419,21 @@ public: //===----------------------------------------------------------------------===// using CheckStmtFunc = CheckerFn<void (const Stmt *, CheckerContext &)>; - + using CheckObjCMessageFunc = CheckerFn<void (const ObjCMethodCall &, CheckerContext &)>; using CheckCallFunc = CheckerFn<void (const CallEvent &, CheckerContext &)>; - + using CheckLocationFunc = CheckerFn<void (const SVal &location, bool isLoad, const Stmt *S, CheckerContext &)>; - + using CheckBindFunc = CheckerFn<void (const SVal &location, const SVal &val, const Stmt *S, CheckerContext &)>; - + using CheckEndAnalysisFunc = CheckerFn<void (ExplodedGraph &, BugReporter &, ExprEngine &)>; @@ -441,18 +441,18 @@ public: using CheckEndFunctionFunc = CheckerFn<void (const ReturnStmt *, CheckerContext &)>; - + using CheckBranchConditionFunc = CheckerFn<void (const Stmt *, CheckerContext &)>; using CheckNewAllocatorFunc = CheckerFn<void (const CXXNewExpr *, SVal, CheckerContext &)>; - + using CheckDeadSymbolsFunc = CheckerFn<void (SymbolReaper &, CheckerContext &)>; - + using CheckLiveSymbolsFunc = CheckerFn<void (ProgramStateRef,SymbolReaper &)>; - + using CheckRegionChangesFunc = CheckerFn<ProgramStateRef (ProgramStateRef, const InvalidatedSymbols *symbols, @@ -460,17 +460,17 @@ public: ArrayRef<const MemRegion *> Regions, const LocationContext *LCtx, const CallEvent *Call)>; - + using CheckPointerEscapeFunc = CheckerFn<ProgramStateRef (ProgramStateRef, const InvalidatedSymbols &Escaped, const CallEvent *Call, PointerEscapeKind Kind, RegionAndSymbolInvalidationTraits *ITraits)>; - + using EvalAssumeFunc = CheckerFn<ProgramStateRef (ProgramStateRef, const SVal &cond, bool assumption)>; - + using EvalCallFunc = CheckerFn<bool (const CallExpr *, CheckerContext &)>; using CheckEndOfTranslationUnit = @@ -531,7 +531,7 @@ public: template <typename EVENT> void _registerListenerForEvent(CheckEventFunc checkfn) { EventInfo &info = Events[getTag<EVENT>()]; - info.Checkers.push_back(checkfn); + info.Checkers.push_back(checkfn); } template <typename EVENT> @@ -636,7 +636,7 @@ private: EventInfo() = default; }; - + using EventsTy = llvm::DenseMap<EventTag, EventInfo>; EventsTy Events; }; diff --git a/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h b/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h index e981871ae4e0..2d13bf34cd15 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h +++ b/include/clang/StaticAnalyzer/Core/CheckerOptInfo.h @@ -28,7 +28,7 @@ class CheckerOptInfo { public: CheckerOptInfo(StringRef name, bool enable) : Name(name), Enable(enable), Claimed(false) { } - + StringRef getName() const { return Name; } bool isEnabled() const { return Enable; } bool isDisabled() const { return !isEnabled(); } diff --git a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h index 912a601b61c4..d580dda73488 100644 --- a/include/clang/StaticAnalyzer/Core/CheckerRegistry.h +++ b/include/clang/StaticAnalyzer/Core/CheckerRegistry.h @@ -47,7 +47,7 @@ // The clang_registerCheckers function may add any number of checkers to the // registry. If any checkers require additional initialization, use the three- // argument form of CheckerRegistry::addChecker. -// +// // To load a checker plugin, specify the full path to the dynamic library as // the argument to the -load option in the cc1 frontend. You can then enable // your custom checker using the -analyzer-checker: diff --git a/include/clang/StaticAnalyzer/Core/IssueHash.h b/include/clang/StaticAnalyzer/Core/IssueHash.h index 8cb6631fae74..03997aae79ae 100644 --- a/include/clang/StaticAnalyzer/Core/IssueHash.h +++ b/include/clang/StaticAnalyzer/Core/IssueHash.h @@ -29,7 +29,7 @@ class LangOptions; /// location. The bugtype and the name of the checker is also part of the hash. /// The last component is the string representation of the enclosing declaration /// of the associated location. -/// +/// /// In case a new hash is introduced, the old one should still be maintained for /// a while. One should not introduce a new hash for every change, it is /// possible to introduce experimental hashes that may change in the future. diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h index 93edfcef2d5a..243795e720f6 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h @@ -88,7 +88,7 @@ public: /// for 'unsigned char' (u8). RangeTestResultKind testInRange(const llvm::APSInt &Val, bool AllowMixedSign) const LLVM_READONLY; - + bool operator==(const APSIntType &Other) const { return BitWidth == Other.BitWidth && IsUnsigned == Other.IsUnsigned; } @@ -102,7 +102,7 @@ public: std::tie(Other.BitWidth, Other.IsUnsigned); } }; - + } // end ento namespace } // end clang namespace diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h index 02b335761e70..85369509efcd 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h @@ -45,12 +45,12 @@ class AnalysisManager : public BugReporterData { public: AnalyzerOptions &options; - + AnalysisManager(ASTContext &ctx,DiagnosticsEngine &diags, const LangOptions &lang, const PathDiagnosticConsumers &Consumers, StoreManagerCreator storemgr, - ConstraintManagerCreator constraintmgr, + ConstraintManagerCreator constraintmgr, CheckerManager *checkerMgr, AnalyzerOptions &Options, CodeInjector* injector = nullptr); @@ -60,7 +60,7 @@ public: void ClearContexts() { AnaCtxMgr.clear(); } - + AnalysisDeclContextManager& getAnalysisDeclContextManager() { return AnaCtxMgr; } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h index 0bbc6500d6ec..b72b158194c7 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -155,12 +155,12 @@ public: return getValue(TargetType.convert(From)); } - + const llvm::APSInt &Convert(QualType T, const llvm::APSInt &From) { APSIntType TargetType = getAPSIntType(T); if (TargetType == APSIntType(From)) return From; - + return getValue(TargetType.convert(From)); } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h index b94dadff2342..5e831095abc7 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/BlockCounter.h @@ -35,7 +35,7 @@ class BlockCounter { public: BlockCounter() : Data(nullptr) {} - unsigned getNumVisited(const StackFrameContext *CallSite, + unsigned getNumVisited(const StackFrameContext *CallSite, unsigned BlockID) const; class Factory { @@ -45,7 +45,7 @@ public: ~Factory(); BlockCounter GetEmptyCounter(); - BlockCounter IncrementCount(BlockCounter BC, + BlockCounter IncrementCount(BlockCounter BC, const StackFrameContext *CallSite, unsigned BlockID); }; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index 9c667f912e9f..9078fb94d282 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -29,6 +29,7 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" @@ -117,12 +118,12 @@ public: } }; -/// \class RuntimeDefinition +/// \class RuntimeDefinition /// Defines the runtime definition of the called function. -/// -/// Encapsulates the information we have about which Decl will be used +/// +/// Encapsulates the information we have about which Decl will be used /// when the call is executed on the given path. When dealing with dynamic -/// dispatch, the information is based on DynamicTypeInfo and might not be +/// dispatch, the information is based on DynamicTypeInfo and might not be /// precise. class RuntimeDefinition { /// The Declaration of the function which could be called at runtime. @@ -141,13 +142,13 @@ public: RuntimeDefinition(const Decl *InD, const MemRegion *InR): D(InD), R(InR) {} const Decl *getDecl() { return D; } - - /// Check if the definition we have is precise. - /// If not, it is possible that the call dispatches to another definition at + + /// Check if the definition we have is precise. + /// If not, it is possible that the call dispatches to another definition at /// execution time. bool mayHaveOtherDefinitions() { return R != nullptr; } - - /// When other definitions are possible, returns the region whose runtime type + + /// When other definitions are possible, returns the region whose runtime type /// determines the method definition. const MemRegion *getDispatchRegion() { return R; } }; @@ -404,6 +405,46 @@ public: /// \p D must not be null. static bool isVariadic(const Decl *D); + /// Returns AnalysisDeclContext for the callee stack frame. + /// Currently may fail; returns null on failure. + AnalysisDeclContext *getCalleeAnalysisDeclContext() const; + + /// Returns the callee stack frame. That stack frame will only be entered + /// during analysis if the call is inlined, but it may still be useful + /// in intermediate calculations even if the call isn't inlined. + /// May fail; returns null on failure. + const StackFrameContext *getCalleeStackFrame() const; + + /// Returns memory location for a parameter variable within the callee stack + /// frame. May fail; returns null on failure. + const VarRegion *getParameterLocation(unsigned Index) const; + + /// Returns true if on the current path, the argument was constructed by + /// calling a C++ constructor over it. This is an internal detail of the + /// analysis which doesn't necessarily represent the program semantics: + /// if we are supposed to construct an argument directly, we may still + /// not do that because we don't know how (i.e., construction context is + /// unavailable in the CFG or not supported by the analyzer). + bool isArgumentConstructedDirectly(unsigned Index) const { + // This assumes that the object was not yet removed from the state. + return ExprEngine::getObjectUnderConstruction( + getState(), {getOriginExpr(), Index}, getCalleeStackFrame()).hasValue(); + } + + /// Some calls have parameter numbering mismatched from argument numbering. + /// This function converts an argument index to the corresponding + /// parameter index. Returns None is the argument doesn't correspond + /// to any parameter variable. + Optional<unsigned> getAdjustedParameterIndex(unsigned ArgumentIndex) const { + if (dyn_cast_or_null<CXXOperatorCallExpr>(getOriginExpr()) && + dyn_cast_or_null<CXXMethodDecl>(getDecl())) { + // For member operator calls argument 0 on the expression corresponds + // to implicit this-parameter on the declaration. + return (ArgumentIndex > 0) ? Optional<unsigned>(ArgumentIndex - 1) : None; + } + return ArgumentIndex; + } + // Iterator access to formal parameters and their types. private: struct GetTypeFn { @@ -628,7 +669,7 @@ protected: : AnyFunctionCall(D, St, LCtx) {} CXXInstanceCall(const CXXInstanceCall &Other) = default; - void getExtraInvalidatedValues(ValueList &Values, + void getExtraInvalidatedValues(ValueList &Values, RegionAndSymbolInvalidationTraits *ETraits) const override; public: diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index f3a0ca7b6608..ce2b711a4a1b 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -51,7 +51,7 @@ namespace ento { /// be accessible from more than one translation unit. #define REGISTER_SET_WITH_PROGRAMSTATE(Name, Elem) \ REGISTER_TRAIT_WITH_PROGRAMSTATE(Name, llvm::ImmutableSet<Elem>) - + /// Declares an immutable list of type \p NameTy, suitable for placement into /// the ProgramState. This is implementing using llvm::ImmutableList. /// @@ -83,7 +83,7 @@ public: /// If we are post visiting a call, this flag will be set if the /// call was inlined. In all other cases it will be false. const bool wasInlined; - + CheckerContext(NodeBuilder &builder, ExprEngine &eng, ExplodedNode *pred, @@ -110,7 +110,7 @@ public: StoreManager &getStoreManager() { return Eng.getStoreManager(); } - + /// Returns the previous node in the exploded graph, which includes /// the state of the program before the checker ran. Note, checkers should /// not retain the node in their state since the nodes might get invalidated. @@ -149,7 +149,7 @@ public: BugReporter &getBugReporter() { return Eng.getBugReporter(); } - + SourceManager &getSourceManager() { return getBugReporter().getSourceManager(); } @@ -308,7 +308,7 @@ public: static bool isCLibraryFunction(const FunctionDecl *FD, StringRef Name = StringRef()); - /// Depending on wither the location corresponds to a macro, return + /// Depending on wither the location corresponds to a macro, return /// either the macro name or the token spelling. /// /// This could be useful when checkers' logic depends on whether a function diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h index 5755818cd971..17369a85bfa3 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CoreEngine.h @@ -64,7 +64,7 @@ class CoreEngine { public: using BlocksExhausted = std::vector<std::pair<BlockEdge, const ExplodedNode *>>; - + using BlocksAborted = std::vector<std::pair<const CFGBlock *, const ExplodedNode *>>; @@ -87,7 +87,7 @@ private: /// The locations where we stopped doing work because we visited a location /// too many times. BlocksExhausted blocksExhausted; - + /// The locations where we stopped because the engine aborted analysis, /// usually because it could not reason about something. BlocksAborted blocksAborted; @@ -141,7 +141,7 @@ public: /// Returns true if there is still simulation state on the worklist. bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, - ProgramStateRef InitState, + ProgramStateRef InitState, ExplodedNodeSet &Dst); /// Dispatch the work list item based on the given location information. @@ -152,8 +152,8 @@ public: // Functions for external checking of whether we have unfinished work bool wasBlockAborted() const { return !blocksAborted.empty(); } bool wasBlocksExhausted() const { return !blocksExhausted.empty(); } - bool hasWorkRemaining() const { return wasBlocksExhausted() || - WList->hasWork() || + bool hasWorkRemaining() const { return wasBlocksExhausted() || + WList->hasWork() || wasBlockAborted(); } /// Inform the CoreEngine that a basic block was aborted because @@ -161,7 +161,7 @@ public: void addAbortedBlock(const ExplodedNode *node, const CFGBlock *block) { blocksAborted.push_back(std::make_pair(block, node)); } - + WorkList *getWorkList() const { return WList.get(); } BlocksExhausted::const_iterator blocks_exhausted_begin() const { @@ -255,7 +255,7 @@ protected: /// Allow subclasses to finalize results before result_begin() is executed. virtual void finalizeResults() {} - + ExplodedNode *generateNodeImpl(const ProgramPoint &PP, ProgramStateRef State, ExplodedNode *Pred, @@ -474,7 +474,7 @@ class IndirectGotoNodeBuilder { ExplodedNode *Pred; public: - IndirectGotoNodeBuilder(ExplodedNode *pred, const CFGBlock *src, + IndirectGotoNodeBuilder(ExplodedNode *pred, const CFGBlock *src, const Expr *e, const CFGBlock *dispatch, CoreEngine* eng) : Eng(*eng), Src(src), DispatchBlock(*dispatch), E(e), Pred(pred) {} @@ -508,7 +508,7 @@ public: const Expr *getTarget() const { return E; } ProgramStateRef getState() const { return Pred->State; } - + const LocationContext *getLocationContext() const { return Pred->getLocationContext(); } @@ -562,7 +562,7 @@ public: const Expr *getCondition() const { return Condition; } ProgramStateRef getState() const { return Pred->State; } - + const LocationContext *getLocationContext() const { return Pred->getLocationContext(); } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h index d49aa81bc958..77e35398077c 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h @@ -40,14 +40,14 @@ public: const Stmt *getStmt() const { return first; } const LocationContext *getLocationContext() const { return second; } - + /// Profile an EnvironmentEntry for inclusion in a FoldingSet. static void Profile(llvm::FoldingSetNodeID &ID, const EnvironmentEntry &E) { ID.AddPointer(E.getStmt()); ID.AddPointer(E.getLocationContext()); } - + void Profile(llvm::FoldingSetNodeID &ID) const { Profile(ID, *this); } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index c12198db6598..4e0c02e6d65b 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -87,7 +87,7 @@ class ExplodedNode : public llvm::FoldingSetNode { // for the nodes in the group. // This is not a PointerIntPair in order to keep the storage type opaque. uintptr_t P; - + public: NodeGroup(bool Flag = false) : P(Flag) { assert(getFlag() == Flag); @@ -251,7 +251,7 @@ public: }; static void SetAuditor(Auditor* A); - + private: void replaceSuccessor(ExplodedNode *node) { Succs.replaceNode(node); } void replacePredecessor(ExplodedNode *node) { Preds.replaceNode(node); } @@ -286,18 +286,18 @@ protected: /// NumNodes - The number of nodes in the graph. unsigned NumNodes = 0; - + /// A list of recently allocated nodes that can potentially be recycled. NodeVector ChangedNodes; - + /// A list of nodes that can be reused. NodeVector FreeNodes; - + /// Determines how often nodes are reclaimed. /// /// If this is 0, nodes will never be reclaimed. unsigned ReclaimNodeInterval = 0; - + /// Counter to determine when to reclaim nodes. unsigned ReclaimCounter; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index 25849e94c8ff..06a90fa847a6 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -69,7 +69,7 @@ namespace cross_tu { class CrossTranslationUnitContext; } // namespace cross_tu - + namespace ento { class BasicValueFactory; @@ -117,7 +117,7 @@ private: cross_tu::CrossTranslationUnitContext &CTU; AnalysisManager &AMgr; - + AnalysisDeclContextManager &AnalysisDeclContexts; CoreEngine Engine; @@ -136,11 +136,11 @@ private: unsigned int currStmtIdx = 0; const NodeBuilderContext *currBldrCtx = nullptr; - + /// Helper object to determine if an Objective-C message expression /// implicitly never returns. ObjCNoReturn ObjCNoRet; - + /// Whether or not GC is enabled in this analysis. bool ObjCGCEnabled; @@ -173,7 +173,7 @@ public: /// state of the function call. Returns true if there is still simulation /// state on the worklist. bool ExecuteWorkListWithInitialState(const LocationContext *L, unsigned Steps, - ProgramStateRef InitState, + ProgramStateRef InitState, ExplodedNodeSet &Dst) { return Engine.ExecuteWorkListWithInitialState(L, Steps, InitState, Dst); } @@ -276,17 +276,17 @@ public: ExplodedNode *Pred, ExplodedNodeSet &Dst); void ProcessMemberDtor(const CFGMemberDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst); - void ProcessTemporaryDtor(const CFGTemporaryDtor D, + void ProcessTemporaryDtor(const CFGTemporaryDtor D, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// Called by CoreEngine when processing the entrance of a CFGBlock. void processCFGBlockEntrance(const BlockEdge &L, NodeBuilderWithSinks &nodeBuilder, ExplodedNode *Pred) override; - + /// ProcessBranch - Called by CoreEngine. Used to generate successor /// nodes by processing the 'effects' of a branch condition. - void processBranch(const Stmt *Condition, const Stmt *Term, + void processBranch(const Stmt *Condition, const Stmt *Term, NodeBuilderContext& BuilderCtx, ExplodedNode *Pred, ExplodedNodeSet &Dst, @@ -354,7 +354,7 @@ public: /// processRegionChanges - Called by ProgramStateManager whenever a change is made /// to the store. Used to update checkers that track region values. - ProgramStateRef + ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef<const MemRegion *> ExplicitRegions, @@ -410,15 +410,15 @@ public: ExplodedNodeSet &Dst); /// VisitBlockExpr - Transfer function logic for BlockExprs. - void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, + void VisitBlockExpr(const BlockExpr *BE, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitLambdaExpr - Transfer function logic for LambdaExprs. - void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, + void VisitLambdaExpr(const LambdaExpr *LE, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitBinaryOperator - Transfer function logic for binary operators. - void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred, + void VisitBinaryOperator(const BinaryOperator* B, ExplodedNode *Pred, ExplodedNodeSet &Dst); @@ -431,21 +431,21 @@ public: ExplodedNodeSet &Dst); /// VisitCompoundLiteralExpr - Transfer function logic for compound literals. - void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, + void VisitCompoundLiteralExpr(const CompoundLiteralExpr *CL, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// Transfer function logic for DeclRefExprs and BlockDeclRefExprs. void VisitCommonDeclRefExpr(const Expr *DR, const NamedDecl *D, ExplodedNode *Pred, ExplodedNodeSet &Dst); - + /// VisitDeclStmt - Transfer function logic for DeclStmts. - void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, + void VisitDeclStmt(const DeclStmt *DS, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitGuardedExpr - Transfer function logic for ?, __builtin_choose - void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, + void VisitGuardedExpr(const Expr *Ex, const Expr *L, const Expr *R, ExplodedNode *Pred, ExplodedNodeSet &Dst); - + void VisitInitListExpr(const InitListExpr *E, ExplodedNode *Pred, ExplodedNodeSet &Dst); @@ -454,7 +454,7 @@ public: ExplodedNodeSet &Dst); /// VisitMemberExpr - Transfer function for member expressions. - void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, + void VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitAtomicExpr - Transfer function for builtin atomic expressions @@ -471,16 +471,16 @@ public: /// VisitObjCForCollectionStmt - Transfer function logic for /// ObjCForCollectionStmt. - void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, + void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S, ExplodedNode *Pred, ExplodedNodeSet &Dst); void VisitObjCMessage(const ObjCMessageExpr *ME, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitReturnStmt - Transfer function logic for return statements. - void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, + void VisitReturnStmt(const ReturnStmt *R, ExplodedNode *Pred, ExplodedNodeSet &Dst); - + /// VisitOffsetOfExpr - Transfer function for offsetof. void VisitOffsetOfExpr(const OffsetOfExpr *Ex, ExplodedNode *Pred, ExplodedNodeSet &Dst); @@ -490,7 +490,7 @@ public: ExplodedNode *Pred, ExplodedNodeSet &Dst); /// VisitUnaryOperator - Transfer function logic for unary operators. - void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred, + void VisitUnaryOperator(const UnaryOperator* B, ExplodedNode *Pred, ExplodedNodeSet &Dst); /// Handle ++ and -- (both pre- and post-increment). @@ -505,7 +505,7 @@ public: void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred, ExplodedNodeSet &Dst); - void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, + void VisitCXXThisExpr(const CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet & Dst); void VisitCXXConstructExpr(const CXXConstructExpr *E, ExplodedNode *Pred, @@ -528,15 +528,15 @@ public: /// Create a C++ temporary object for an rvalue. void CreateCXXTemporaryObject(const MaterializeTemporaryExpr *ME, - ExplodedNode *Pred, + ExplodedNode *Pred, ExplodedNodeSet &Dst); - + /// evalEagerlyAssumeBinOpBifurcation - Given the nodes in 'Src', eagerly assume symbolic /// expressions of the form 'x != 0' and generate new nodes (stored in Dst) /// with those assumptions. - void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, + void evalEagerlyAssumeBinOpBifurcation(ExplodedNodeSet &Dst, ExplodedNodeSet &Src, const Expr *Ex); - + static std::pair<const ProgramPointTag *, const ProgramPointTag *> geteagerlyAssumeBinOpBifurcationTags(); @@ -580,7 +580,15 @@ public: SVal LHS, SVal RHS, QualType T) { return svalBuilder.evalBinOp(ST, Op, LHS, RHS, T); } - + + /// By looking at a certain item that may be potentially part of an object's + /// ConstructionContext, retrieve such object's location. A particular + /// statement can be transparently passed as \p Item in most cases. + static Optional<SVal> + getObjectUnderConstruction(ProgramStateRef State, + const ConstructionContextItem &Item, + const LocationContext *LC); + protected: /// evalBind - Handle the semantics of binding a value to a specific location. /// This method is used by evalStore, VisitDeclStmt, and others. @@ -761,24 +769,17 @@ private: /// This allows, among other things, to keep bindings to variable's fields /// made within the constructor alive until its declaration actually /// goes into scope. - static ProgramStateRef addObjectUnderConstruction( - ProgramStateRef State, - llvm::PointerUnion<const Stmt *, const CXXCtorInitializer *> P, - const LocationContext *LC, SVal V); + static ProgramStateRef + addObjectUnderConstruction(ProgramStateRef State, + const ConstructionContextItem &Item, + const LocationContext *LC, SVal V); /// Mark the object sa fully constructed, cleaning up the state trait /// that tracks objects under construction. - static ProgramStateRef finishObjectConstruction( - ProgramStateRef State, - llvm::PointerUnion<const Stmt *, const CXXCtorInitializer *> P, - const LocationContext *LC); - - /// If the given statement corresponds to an object under construction, - /// being part of its construciton context, retrieve that object's location. - static Optional<SVal> getObjectUnderConstruction( - ProgramStateRef State, - llvm::PointerUnion<const Stmt *, const CXXCtorInitializer *> P, - const LocationContext *LC); + static ProgramStateRef + finishObjectConstruction(ProgramStateRef State, + const ConstructionContextItem &Item, + const LocationContext *LC); /// If the given expression corresponds to a temporary that was used for /// passing into an elidable copy/move constructor and that constructor diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index f3846eba6b96..3a93aae5a9bc 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -131,9 +131,9 @@ public: bool hasGlobalsOrParametersStorage() const; bool hasStackStorage() const; - + bool hasStackNonParametersStorage() const; - + bool hasStackParametersStorage() const; /// Compute the offset within the top level memory object. @@ -253,7 +253,7 @@ class StaticGlobalSpaceRegion : public GlobalsSpaceRegion { friend class MemRegionManager; const CodeTextRegion *CR; - + StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr) : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) { assert(cr); @@ -348,7 +348,7 @@ public: class HeapSpaceRegion : public MemSpaceRegion { friend class MemRegionManager; - + HeapSpaceRegion(MemRegionManager *mgr) : MemSpaceRegion(mgr, HeapSpaceRegionKind) {} @@ -359,7 +359,7 @@ public: return R->getKind() == HeapSpaceRegionKind; } }; - + class UnknownSpaceRegion : public MemSpaceRegion { friend class MemRegionManager; @@ -613,7 +613,7 @@ public: return R->getKind() == FunctionCodeRegionKind; } }; - + /// BlockCodeRegion - A region that represents code texts of blocks (closures). /// Blocks are represented with two kinds of regions. BlockCodeRegions /// represent the "code", while BlockDataRegions represent instances of blocks, @@ -643,7 +643,7 @@ public: QualType getLocationType() const override { return locTy; } - + const BlockDecl *getDecl() const { return BD; } @@ -658,7 +658,7 @@ public: return R->getKind() == BlockCodeRegionKind; } }; - + /// BlockDataRegion - A region that represents a block instance. /// Blocks are represented with two kinds of regions. BlockCodeRegions /// represent the "code", while BlockDataRegions represent instances of blocks, @@ -733,9 +733,9 @@ public: /// Return the original region for a captured region, if /// one exists. const VarRegion *getOriginalRegion(const VarRegion *VR) const; - + referenced_vars_iterator referenced_vars_begin() const; - referenced_vars_iterator referenced_vars_end() const; + referenced_vars_iterator referenced_vars_end() const; void dumpToStream(raw_ostream &os) const override; @@ -824,7 +824,7 @@ public: return R->getKind() == StringRegionKind; } }; - + /// The region associated with an ObjCStringLiteral. class ObjCStringRegion : public TypedValueRegion { friend class MemRegionManager; @@ -840,7 +840,7 @@ class ObjCStringRegion : public TypedValueRegion { static void ProfileRegion(llvm::FoldingSetNodeID &ID, const ObjCStringLiteral *Str, const MemRegion *superRegion); - + public: const ObjCStringLiteral *getObjCStringLiteral() const { return Str; } @@ -897,9 +897,9 @@ public: class DeclRegion : public TypedValueRegion { protected: - const Decl *D; + const ValueDecl *D; - DeclRegion(const Decl *d, const MemRegion *sReg, Kind k) + DeclRegion(const ValueDecl *d, const MemRegion *sReg, Kind k) : TypedValueRegion(sReg, k), D(d) { assert(classof(this)); assert(d); @@ -909,7 +909,7 @@ protected: const MemRegion* superRegion, Kind k); public: - const Decl *getDecl() const { return D; } + const ValueDecl *getDecl() const { return D; } void Profile(llvm::FoldingSetNodeID& ID) const override; static bool classof(const MemRegion* R) { @@ -959,7 +959,7 @@ public: return R->getKind() == VarRegionKind; } }; - + /// CXXThisRegion - Represents the region for the implicit 'this' parameter /// in a call to a C++ method. This region doesn't represent the object /// referred to by 'this', but rather 'this' itself. @@ -1141,7 +1141,7 @@ public: } }; -// CXXBaseObjectRegion represents a base object within a C++ object. It is +// CXXBaseObjectRegion represents a base object within a C++ object. It is // identified by the base class declaration and the region of its parent object. class CXXBaseObjectRegion : public TypedValueRegion { friend class MemRegionManager; @@ -1197,7 +1197,7 @@ class MemRegionManager { GlobalSystemSpaceRegion *SystemGlobals = nullptr; GlobalImmutableSpaceRegion *ImmutableGlobals = nullptr; - llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *> + llvm::DenseMap<const StackFrameContext *, StackLocalsSpaceRegion *> StackLocalsSpaceRegions; llvm::DenseMap<const StackFrameContext *, StackArgumentsSpaceRegion *> StackArgumentsSpaceRegions; @@ -1213,7 +1213,7 @@ public: ~MemRegionManager(); ASTContext &getContext() { return C; } - + llvm::BumpPtrAllocator &getAllocator() { return A; } /// getStackLocalsRegion - Retrieve the memory region associated with the @@ -1251,7 +1251,7 @@ public: const CompoundLiteralRegion* getCompoundLiteralRegion(const CompoundLiteralExpr *CL, const LocationContext *LC); - + /// getCXXThisRegion - Retrieve the [artificial] region associated with the /// parameter 'this'. const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy, @@ -1320,7 +1320,7 @@ public: /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different /// super region. const CXXBaseObjectRegion * - getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg, + getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg, const SubRegion *superRegion) { return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion, baseReg->isVirtual()); @@ -1330,7 +1330,7 @@ public: const BlockCodeRegion *getBlockCodeRegion(const BlockDecl *BD, CanQualType locTy, AnalysisDeclContext *AC); - + /// getBlockDataRegion - Get the memory region associated with an instance /// of a block. Unlike many other MemRegions, the LocationContext* /// argument is allowed to be NULL for cases where we have no known @@ -1363,7 +1363,7 @@ private: template <typename REG> const REG* LazyAllocate(REG*& region); - + template <typename REG, typename ARG> const REG* LazyAllocate(REG*& region, ARG a); }; @@ -1408,7 +1408,7 @@ public: /// should be invalidated. TK_EntireMemSpace = 0x8 - // Do not forget to extend StorageTypeForKinds if number of traits exceed + // Do not forget to extend StorageTypeForKinds if number of traits exceed // the number of bits StorageTypeForKinds can store. }; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index 17ab7379fdba..b86301a03470 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -36,6 +36,7 @@ class ASTContext; namespace ento { +class AnalysisManager; class CallEvent; class CallEventManager; @@ -111,6 +112,8 @@ public: return *stateMgr; } + AnalysisManager &getAnalysisManager() const; + /// Return the ConstraintManager. ConstraintManager &getConstraintManager() const; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h index 31300d69f2ff..865014b22830 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h @@ -55,7 +55,7 @@ class SValBuilder { protected: ASTContext &Context; - + /// Manager of APSInt values. BasicValueFactory BasicVals; @@ -69,7 +69,7 @@ protected: /// The scalar type to use for array indices. const QualType ArrayIndexTy; - + /// The width of the scalar type used for array indices. const unsigned ArrayIndexWidth; @@ -137,7 +137,7 @@ public: /// that represents the same value, but is hopefully easier to work with /// than the original SVal. virtual SVal simplifySVal(ProgramStateRef State, SVal Val) = 0; - + /// Constructs a symbolic expression for two non-location values. SVal makeSymExprValNN(ProgramStateRef state, BinaryOperator::Opcode op, NonLoc lhs, NonLoc rhs, QualType resultTy); @@ -157,11 +157,11 @@ public: const ASTContext &getContext() const { return Context; } ProgramStateManager &getStateManager() { return StateMgr; } - + QualType getConditionType() const { return Context.getLangOpts().CPlusPlus ? Context.BoolTy : Context.IntTy; } - + QualType getArrayIndexType() const { return ArrayIndexTy; } @@ -237,7 +237,7 @@ public: DefinedSVal getMemberPointer(const DeclaratorDecl *DD); DefinedSVal getFunctionPointer(const FunctionDecl *func); - + DefinedSVal getBlockPointer(const BlockDecl *block, CanQualType locTy, const LocationContext *locContext, unsigned blockCount); @@ -252,7 +252,7 @@ public: return nonloc::CompoundVal(BasicVals.getCompoundValData(type, vals)); } - NonLoc makeLazyCompoundVal(const StoreRef &store, + NonLoc makeLazyCompoundVal(const StoreRef &store, const TypedValueRegion *region) { return nonloc::LazyCompoundVal( BasicVals.getLazyCompoundValData(store, region)); diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h index 0fde63e9eb09..1b79bfc3f8cf 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -202,7 +202,7 @@ public: return SymExpr::symbol_iterator(); } - SymExpr::symbol_iterator symbol_end() const { + SymExpr::symbol_iterator symbol_end() const { return SymExpr::symbol_end(); } }; @@ -230,13 +230,13 @@ public: // tautologically false. bool isUndef() const = delete; bool isValid() const = delete; - + protected: DefinedOrUnknownSVal() = default; explicit DefinedOrUnknownSVal(const void *d, bool isLoc, unsigned ValKind) : SVal(d, isLoc, ValKind) {} explicit DefinedOrUnknownSVal(BaseKind k, void *D = nullptr) : SVal(k, D) {} - + private: friend class SVal; @@ -244,11 +244,11 @@ private: return !V.isUndef(); } }; - + class UnknownVal : public DefinedOrUnknownSVal { public: explicit UnknownVal() : DefinedOrUnknownSVal(UnknownValKind) {} - + private: friend class SVal; @@ -325,7 +325,7 @@ public: void dumpToStream(raw_ostream &Out) const; static bool isLocType(QualType T) { - return T->isAnyPointerType() || T->isBlockPointerType() || + return T->isAnyPointerType() || T->isBlockPointerType() || T->isReferenceType() || T->isNullPtrType(); } @@ -664,7 +664,7 @@ private: } }; -} // namespace loc +} // namespace loc } // namespace ento diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h index dc0644df8aab..fc072a380074 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h @@ -149,7 +149,7 @@ public: // FIXME: This should soon be eliminated altogether; clients should deal with // region extents directly. - virtual DefinedOrUnknownSVal getSizeInElements(ProgramStateRef state, + virtual DefinedOrUnknownSVal getSizeInElements(ProgramStateRef state, const MemRegion *region, QualType EleTy) { return UnknownVal(); @@ -176,8 +176,8 @@ public: /// - Successful cast (ex: derived is subclass of base). /// - Failed cast (ex: derived is definitely not a subclass of base). /// The distinction of this case from the next one is necessary to model - /// dynamic_cast. - /// - We don't know (base is a symbolic region and we don't have + /// dynamic_cast. + /// - We don't know (base is a symbolic region and we don't have /// enough info to determine if the cast will succeed at run time). /// The function returns an SVal representing the derived class; it's /// valid only if Failed flag is set to false. @@ -195,7 +195,7 @@ public: virtual bool includedInBindings(Store store, const MemRegion *region) const = 0; - + /// If the StoreManager supports it, increment the reference count of /// the specified Store object. virtual void incrementReferenceCount(Store store) {} @@ -221,7 +221,7 @@ public: /// globals should get invalidated. /// \param[in,out] IS A set to fill with any symbols that are no longer /// accessible. Pass \c NULL if this information will not be used. - /// \param[in] ITraits Information about invalidation for a particular + /// \param[in] ITraits Information about invalidation for a particular /// region/symbol. /// \param[in,out] InvalidatedTopLevel A vector to fill with regions //// explicitly being invalidated. Pass \c NULL if this @@ -305,16 +305,16 @@ inline StoreRef::StoreRef(Store store, StoreManager & smgr) inline StoreRef::StoreRef(const StoreRef &sr) : store(sr.store), mgr(sr.mgr) -{ +{ if (store) mgr.incrementReferenceCount(store); } - + inline StoreRef::~StoreRef() { if (store) mgr.decrementReferenceCount(store); } - + inline StoreRef &StoreRef::operator=(StoreRef const &newStore) { assert(&newStore.mgr == &mgr); if (store != newStore.store) { diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h index c5b4e5036bdf..22259a239cf6 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h @@ -18,15 +18,15 @@ namespace clang { namespace ento { - + class StoreManager; - + /// Store - This opaque type encapsulates an immutable mapping from /// locations to values. At a high-level, it represents the symbolic /// memory model. Different subclasses of StoreManager may choose /// different types to represent the locations and values. using Store = const void *; - + class StoreRef { Store store; StoreManager &mgr; @@ -36,14 +36,14 @@ public: StoreRef(const StoreRef &sr); StoreRef &operator=(StoreRef const &newStore); ~StoreRef(); - + bool operator==(const StoreRef &x) const { assert(&mgr == &x.mgr); return x.store == store; } bool operator!=(const StoreRef &x) const { return !operator==(x); } - + Store getStore() const { return store; } const StoreManager &getStoreManager() const { return mgr; } }; diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h index e574ffdd6a15..d6aa4feddff2 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h @@ -29,7 +29,7 @@ class CrossTranslationUnitContext; } namespace ento { - + struct NodeBuilderContext; class AnalysisManager; class ExplodedNodeSet; @@ -133,7 +133,7 @@ public: /// processRegionChanges - Called by ProgramStateManager whenever a change is /// made to the store. Used to update checkers that track region values. - virtual ProgramStateRef + virtual ProgramStateRef processRegionChanges(ProgramStateRef state, const InvalidatedSymbols *invalidated, ArrayRef<const MemRegion *> ExplicitRegions, @@ -142,7 +142,7 @@ public: const CallEvent *Call) = 0; - inline ProgramStateRef + inline ProgramStateRef processRegionChange(ProgramStateRef state, const MemRegion* MR, const LocationContext *LCtx) { diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h index 52d78b6a3c82..0a75eeb3ea53 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h @@ -21,9 +21,9 @@ namespace ento { namespace summMgr { - + /* Key kinds: - + - C functions - C++ functions (name + parameter types) - ObjC methods: @@ -34,21 +34,21 @@ namespace summMgr { - C++ methods - Class, function name + parameter types + const */ - + class SummaryKey { - + }; } // end namespace clang::summMgr - + class SummaryManagerImpl { - + }; - + template <typename T> class SummaryManager : SummaryManagerImpl { - + }; } // end GR namespace diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h index cc3ce72f9e56..074551962607 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -167,7 +167,7 @@ public: /// SubRegion::getExtent instead -- the value returned may not be a symbol. class SymbolExtent : public SymbolData { const SubRegion *R; - + public: SymbolExtent(SymbolID sym, const SubRegion *r) : SymbolData(SymbolExtentKind, sym), R(r) { @@ -300,7 +300,7 @@ public: } }; -/// Represents a symbolic expression involving a binary operator +/// Represents a symbolic expression involving a binary operator class BinarySymExpr : public SymExpr { BinaryOperator::Opcode Op; QualType T; @@ -558,7 +558,7 @@ class SymbolReaper { SymbolSetTy TheDead; RegionSetTy RegionRoots; - + const StackFrameContext *LCtx; const Stmt *Loc; SymbolManager& SymMgr; @@ -614,7 +614,7 @@ public: bool hasDeadSymbols() const { return !TheDead.empty(); } - + using region_iterator = RegionSetTy::const_iterator; region_iterator region_begin() const { return RegionRoots.begin(); } @@ -627,10 +627,10 @@ public: bool isDead(SymbolRef sym) const { return TheDead.count(sym); } - + void markLive(const MemRegion *region); void markElementIndicesLive(const MemRegion *region); - + /// Set to the value of the symbolic store after /// StoreManager::removeDeadBindings has been called. void setReapedStore(StoreRef st) { reapedStore = st; } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h index 7df8f373b366..07edd35ff944 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/WorkList.h @@ -20,7 +20,7 @@ #include <cassert> namespace clang { - + class CFGBlock; namespace ento { @@ -47,13 +47,13 @@ public: /// Returns the node associated with the worklist unit. ExplodedNode *getNode() const { return node; } - + /// Returns the block counter map associated with the worklist unit. BlockCounter getBlockCounter() const { return counter; } /// Returns the CFGblock associated with the worklist unit. const CFGBlock *getBlock() const { return block; } - + /// Return the index within the CFGBlock for the worklist unit. unsigned getIndex() const { return blockIdx; } }; |