diff options
Diffstat (limited to 'include/clang/StaticAnalyzer/Core/PathSensitive')
11 files changed, 253 insertions, 111 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h index b0dda78a00a98..d605a6a667f6b 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h @@ -15,9 +15,9 @@ #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_ANALYSISMANAGER_H #include "clang/Analysis/AnalysisDeclContext.h" +#include "clang/Analysis/PathDiagnostic.h" #include "clang/StaticAnalyzer/Core/AnalyzerOptions.h" #include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" -#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" #include "clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h" namespace clang { @@ -32,7 +32,6 @@ class AnalysisManager : public BugReporterData { AnalysisDeclContextManager AnaCtxMgr; ASTContext &Ctx; - DiagnosticsEngine &Diags; const LangOptions &LangOpts; PathDiagnosticConsumers PathConsumers; @@ -45,7 +44,7 @@ class AnalysisManager : public BugReporterData { public: AnalyzerOptions &options; - AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, + AnalysisManager(ASTContext &ctx, const PathDiagnosticConsumers &Consumers, StoreManagerCreator storemgr, ConstraintManagerCreator constraintmgr, @@ -84,10 +83,6 @@ public: return getASTContext().getSourceManager(); } - DiagnosticsEngine &getDiagnostic() override { - return Diags; - } - const LangOptions &getLangOpts() const { return LangOpts; } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index db84102983af1..fc1cc91388266 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -347,7 +347,7 @@ public: ProgramStateRef invalidateRegions(unsigned BlockCount, ProgramStateRef Orig = nullptr) const; - using FrameBindingTy = std::pair<Loc, SVal>; + using FrameBindingTy = std::pair<SVal, SVal>; using BindingsTy = SmallVectorImpl<FrameBindingTy>; /// Populates the given SmallVector with the bindings in the callee's stack @@ -386,11 +386,12 @@ public: /// 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; + const StackFrameContext *getCalleeStackFrame(unsigned BlockCount) 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; + const VarRegion *getParameterLocation(unsigned Index, + unsigned BlockCount) 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 @@ -1063,8 +1064,19 @@ class CallDescription { // e.g. "{a, b}" represent the qualified names, like "a::b". std::vector<const char *> QualifiedName; Optional<unsigned> RequiredArgs; + Optional<size_t> RequiredParams; int Flags; + // A constructor helper. + static Optional<size_t> readRequiredParams(Optional<unsigned> RequiredArgs, + Optional<size_t> RequiredParams) { + if (RequiredParams) + return RequiredParams; + if (RequiredArgs) + return static_cast<size_t>(*RequiredArgs); + return None; + } + public: /// Constructs a CallDescription object. /// @@ -1077,14 +1089,17 @@ public: /// call. Omit this parameter to match every occurrence of call with a given /// name regardless the number of arguments. CallDescription(int Flags, ArrayRef<const char *> QualifiedName, - Optional<unsigned> RequiredArgs = None) + Optional<unsigned> RequiredArgs = None, + Optional<size_t> RequiredParams = None) : QualifiedName(QualifiedName), RequiredArgs(RequiredArgs), + RequiredParams(readRequiredParams(RequiredArgs, RequiredParams)), Flags(Flags) {} /// Construct a CallDescription with default flags. CallDescription(ArrayRef<const char *> QualifiedName, - Optional<unsigned> RequiredArgs = None) - : CallDescription(0, QualifiedName, RequiredArgs) {} + Optional<unsigned> RequiredArgs = None, + Optional<size_t> RequiredParams = None) + : CallDescription(0, QualifiedName, RequiredArgs, RequiredParams) {} /// Get the name of the function that this object matches. StringRef getFunctionName() const { return QualifiedName.back(); } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h index 981133e669775..7f4df0d88def6 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h @@ -103,7 +103,7 @@ public: return Eng.getBugReporter(); } - SourceManager &getSourceManager() { + const SourceManager &getSourceManager() { return getBugReporter().getSourceManager(); } @@ -234,7 +234,7 @@ public: } /// A shorthand version of getNoteTag that doesn't require you to accept - /// the BugReporterContext arguments when you don't need it. + /// the 'BugReporterContext' argument when you don't need it. /// /// @param Cb Callback only with 'BugReport &' parameter. /// @param IsPrunable Whether the note is prunable. It allows BugReporter @@ -247,6 +247,19 @@ public: IsPrunable); } + /// A shorthand version of getNoteTag that doesn't require you to accept + /// the arguments when you don't need it. + /// + /// @param Cb Callback without parameters. + /// @param IsPrunable Whether the note is prunable. It allows BugReporter + /// to omit the note from the report if it would make the displayed + /// bug path significantly shorter. + const NoteTag *getNoteTag(std::function<std::string()> &&Cb, + bool IsPrunable = false) { + return getNoteTag([Cb](BugReporterContext &, BugReport &) { return Cb(); }, + IsPrunable); + } + /// A shorthand version of getNoteTag that accepts a plain note. /// /// @param Note The note. diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicCastInfo.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicCastInfo.h new file mode 100644 index 0000000000000..f5a710c77a6ad --- /dev/null +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicCastInfo.h @@ -0,0 +1,55 @@ +//===- DynamicCastInfo.h - Runtime cast information -------------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICCASTINFO_H +#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICCASTINFO_H + +#include "clang/AST/Type.h" + +namespace clang { +namespace ento { + +class DynamicCastInfo { +public: + enum CastResult { Success, Failure }; + + DynamicCastInfo(QualType from, QualType to, CastResult resultKind) + : From(from), To(to), ResultKind(resultKind) {} + + QualType from() const { return From; } + QualType to() const { return To; } + + bool equals(QualType from, QualType to) const { + return From == from && To == to; + } + + bool succeeds() const { return ResultKind == CastResult::Success; } + bool fails() const { return ResultKind == CastResult::Failure; } + + bool operator==(const DynamicCastInfo &RHS) const { + return From == RHS.From && To == RHS.To; + } + bool operator<(const DynamicCastInfo &RHS) const { + return From < RHS.From && To < RHS.To; + } + + void Profile(llvm::FoldingSetNodeID &ID) const { + ID.Add(From); + ID.Add(To); + ID.AddInteger(ResultKind); + } + +private: + QualType From, To; + CastResult ResultKind; +}; + +} // namespace ento +} // namespace clang + +#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICCASTINFO_H diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h new file mode 100644 index 0000000000000..356401d77561c --- /dev/null +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h @@ -0,0 +1,73 @@ +//===- DynamicType.h - Dynamic type related APIs ----------------*- 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 APIs that track and query dynamic type information. This +// information can be used to devirtualize calls during the symbolic execution +// or do type checking. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPE_H +#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPE_H + +#include "clang/AST/Type.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicCastInfo.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h" +#include "llvm/ADT/ImmutableMap.h" +#include "llvm/ADT/Optional.h" +#include <utility> + +namespace clang { +namespace ento { + +/// Get dynamic type information for the region \p MR. +DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR); + +/// Get raw dynamic type information for the region \p MR. +const DynamicTypeInfo *getRawDynamicTypeInfo(ProgramStateRef State, + const MemRegion *MR); + +/// Get dynamic cast information from \p CastFromTy to \p CastToTy of \p MR. +const DynamicCastInfo *getDynamicCastInfo(ProgramStateRef State, + const MemRegion *MR, + QualType CastFromTy, + QualType CastToTy); + +/// Set dynamic type information of the region; return the new state. +ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR, + DynamicTypeInfo NewTy); + +/// Set dynamic type information of the region; return the new state. +ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *MR, + QualType NewTy, bool CanBeSubClassed = true); + +/// Set dynamic type and cast information of the region; return the new state. +ProgramStateRef setDynamicTypeAndCastInfo(ProgramStateRef State, + const MemRegion *MR, + QualType CastFromTy, + QualType CastToTy, + bool IsCastSucceeds); + +/// Removes the dead type informations from \p State. +ProgramStateRef removeDeadTypes(ProgramStateRef State, SymbolReaper &SR); + +/// Removes the dead cast informations from \p State. +ProgramStateRef removeDeadCasts(ProgramStateRef State, SymbolReaper &SR); + +void printDynamicTypeInfoJson(raw_ostream &Out, ProgramStateRef State, + const char *NL = "\n", unsigned int Space = 0, + bool IsDot = false); + +} // namespace ento +} // namespace clang + +#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPE_H diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h index 9bb1e21375666..6262c4a1ce378 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h @@ -1,10 +1,11 @@ -//== DynamicTypeInfo.h - Runtime type information ----------------*- C++ -*--=// +//===- DynamicTypeInfo.h - Runtime type information -------------*- 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 // //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEINFO_H #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEINFO_H @@ -16,36 +17,37 @@ namespace ento { /// Stores the currently inferred strictest bound on the runtime type /// of a region in a given state along the analysis path. class DynamicTypeInfo { -private: - QualType T; - bool CanBeASubClass; - public: + DynamicTypeInfo() : DynTy(QualType()) {} - DynamicTypeInfo() : T(QualType()) {} - DynamicTypeInfo(QualType WithType, bool CanBeSub = true) - : T(WithType), CanBeASubClass(CanBeSub) {} + DynamicTypeInfo(QualType Ty, bool CanBeSub = true) + : DynTy(Ty), CanBeASubClass(CanBeSub) {} + + /// Returns false if the type information is precise (the type 'DynTy' is + /// the only type in the lattice), true otherwise. + bool canBeASubClass() const { return CanBeASubClass; } - /// Return false if no dynamic type info is available. - bool isValid() const { return !T.isNull(); } + /// Returns true if the dynamic type info is available. + bool isValid() const { return !DynTy.isNull(); } /// Returns the currently inferred upper bound on the runtime type. - QualType getType() const { return T; } + QualType getType() const { return DynTy; } - /// Returns false if the type information is precise (the type T is - /// the only type in the lattice), true otherwise. - bool canBeASubClass() const { return CanBeASubClass; } + bool operator==(const DynamicTypeInfo &RHS) const { + return DynTy == RHS.DynTy && CanBeASubClass == RHS.CanBeASubClass; + } void Profile(llvm::FoldingSetNodeID &ID) const { - ID.Add(T); - ID.AddInteger((unsigned)CanBeASubClass); - } - bool operator==(const DynamicTypeInfo &X) const { - return T == X.T && CanBeASubClass == X.CanBeASubClass; + ID.Add(DynTy); + ID.AddBoolean(CanBeASubClass); } + +private: + QualType DynTy; + bool CanBeASubClass; }; -} // end ento -} // end clang +} // namespace ento +} // namespace clang -#endif +#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEINFO_H diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h b/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h deleted file mode 100644 index a84b248720618..0000000000000 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h +++ /dev/null @@ -1,63 +0,0 @@ -//===- DynamicTypeMap.h - Dynamic type map ----------------------*- 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 provides APIs for tracking dynamic type information. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H -#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H - -#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h" -#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h" -#include "llvm/ADT/ImmutableMap.h" -#include "clang/AST/Type.h" - -namespace clang { -namespace ento { - -class MemRegion; - -/// The GDM component containing the dynamic type info. This is a map from a -/// symbol to its most likely type. -struct DynamicTypeMap {}; - -using DynamicTypeMapTy = llvm::ImmutableMap<const MemRegion *, DynamicTypeInfo>; - -template <> -struct ProgramStateTrait<DynamicTypeMap> - : public ProgramStatePartialTrait<DynamicTypeMapTy> { - static void *GDMIndex(); -}; - -/// Get dynamic type information for a region. -DynamicTypeInfo getDynamicTypeInfo(ProgramStateRef State, - const MemRegion *Reg); - -/// Set dynamic type information of the region; return the new state. -ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, const MemRegion *Reg, - DynamicTypeInfo NewTy); - -/// Set dynamic type information of the region; return the new state. -inline ProgramStateRef setDynamicTypeInfo(ProgramStateRef State, - const MemRegion *Reg, QualType NewTy, - bool CanBeSubClassed = true) { - return setDynamicTypeInfo(State, Reg, - DynamicTypeInfo(NewTy, CanBeSubClassed)); -} - -void printDynamicTypeInfoJson(raw_ostream &Out, ProgramStateRef State, - const char *NL = "\n", unsigned int Space = 0, - bool IsDot = false); - -} // namespace ento -} // namespace clang - -#endif // LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_DYNAMICTYPEMAP_H diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h index 727d04cba2784..e87772c04b9be 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h @@ -131,10 +131,12 @@ class ExplodedNode : public llvm::FoldingSetNode { /// Succs - The successors of this node. NodeGroup Succs; + int64_t Id; + public: explicit ExplodedNode(const ProgramPoint &loc, ProgramStateRef state, - bool IsSink) - : Location(loc), State(std::move(state)), Succs(IsSink) { + int64_t Id, bool IsSink) + : Location(loc), State(std::move(state)), Succs(IsSink), Id(Id) { assert(isSink() == IsSink); } @@ -153,7 +155,11 @@ public: CFG &getCFG() const { return *getLocationContext()->getCFG(); } - ParentMap &getParentMap() const {return getLocationContext()->getParentMap();} + const CFGBlock *getCFGBlock() const; + + const ParentMap &getParentMap() const { + return getLocationContext()->getParentMap(); + } template <typename T> T &getAnalysis() const { @@ -219,12 +225,20 @@ public: // Iterators over successor and predecessor vertices. using succ_iterator = ExplodedNode * const *; + using succ_range = llvm::iterator_range<succ_iterator>; + using const_succ_iterator = const ExplodedNode * const *; + using const_succ_range = llvm::iterator_range<const_succ_iterator>; + using pred_iterator = ExplodedNode * const *; + using pred_range = llvm::iterator_range<pred_iterator>; + using const_pred_iterator = const ExplodedNode * const *; + using const_pred_range = llvm::iterator_range<const_pred_iterator>; pred_iterator pred_begin() { return Preds.begin(); } pred_iterator pred_end() { return Preds.end(); } + pred_range preds() { return {Preds.begin(), Preds.end()}; } const_pred_iterator pred_begin() const { return const_cast<ExplodedNode*>(this)->pred_begin(); @@ -232,9 +246,11 @@ public: const_pred_iterator pred_end() const { return const_cast<ExplodedNode*>(this)->pred_end(); } + const_pred_range preds() const { return {Preds.begin(), Preds.end()}; } succ_iterator succ_begin() { return Succs.begin(); } succ_iterator succ_end() { return Succs.end(); } + succ_range succs() { return {Succs.begin(), Succs.end()}; } const_succ_iterator succ_begin() const { return const_cast<ExplodedNode*>(this)->succ_begin(); @@ -242,8 +258,9 @@ public: const_succ_iterator succ_end() const { return const_cast<ExplodedNode*>(this)->succ_end(); } + const_succ_range succs() const { return {Succs.begin(), Succs.end()}; } - int64_t getID(ExplodedGraph *G) const; + int64_t getID() const { return Id; } /// The node is trivial if it has only one successor, only one predecessor, /// it's predecessor has only one successor, @@ -252,6 +269,30 @@ public: /// Trivial nodes may be skipped while printing exploded graph. bool isTrivial() const; + /// If the node's program point corresponds to a statement, retrieve that + /// statement. Useful for figuring out where to put a warning or a note. + /// If the statement belongs to a body-farmed definition, + /// retrieve the call site for that definition. + const Stmt *getStmtForDiagnostics() const; + + /// Find the next statement that was executed on this node's execution path. + /// Useful for explaining control flow that follows the current node. + /// If the statement belongs to a body-farmed definition, retrieve the + /// call site for that definition. + const Stmt *getNextStmtForDiagnostics() const; + + /// Find the statement that was executed immediately before this node. + /// Useful when the node corresponds to a CFG block entrance. + /// If the statement belongs to a body-farmed definition, retrieve the + /// call site for that definition. + const Stmt *getPreviousStmtForDiagnostics() const; + + /// Find the statement that was executed at or immediately before this node. + /// Useful when any nearby statement will do. + /// If the statement belongs to a body-farmed definition, retrieve the + /// call site for that definition. + const Stmt *getCurrentOrPreviousStmtForDiagnostics() const; + private: void replaceSuccessor(ExplodedNode *node) { Succs.replaceNode(node); } void replacePredecessor(ExplodedNode *node) { Preds.replaceNode(node); } @@ -285,7 +326,7 @@ protected: BumpVectorContext BVC; /// NumNodes - The number of nodes in the graph. - unsigned NumNodes = 0; + int64_t NumNodes = 0; /// A list of recently allocated nodes that can potentially be recycled. NodeVector ChangedNodes; @@ -319,10 +360,11 @@ public: /// ExplodedGraph for further processing. ExplodedNode *createUncachedNode(const ProgramPoint &L, ProgramStateRef State, + int64_t Id, bool IsSink = false); std::unique_ptr<ExplodedGraph> MakeEmptyGraph() const { - return llvm::make_unique<ExplodedGraph>(); + return std::make_unique<ExplodedGraph>(); } /// addRoot - Add an untyped node to the set of roots. diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h index 2629d7121de4c..2d0967616ff20 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h @@ -145,9 +145,9 @@ private: ObjCNoReturn ObjCNoRet; /// The BugReporter associated with this engine. It is important that - /// this object be placed at the very end of member variables so that its - /// destructor is called before the rest of the ExprEngine is destroyed. - GRBugReporter BR; + /// this object be placed at the very end of member variables so that its + /// destructor is called before the rest of the ExprEngine is destroyed. + PathSensitiveBugReporter BR; /// The functions which have been analyzed through inlining. This is owned by /// AnalysisConsumer. It can be null. @@ -530,7 +530,7 @@ public: void VisitCXXDestructor(QualType ObjectType, const MemRegion *Dest, const Stmt *S, bool IsBaseDtor, ExplodedNode *Pred, ExplodedNodeSet &Dst, - const EvalCallOptions &Options); + EvalCallOptions &Options); void VisitCXXNewAllocatorCall(const CXXNewExpr *CNE, ExplodedNode *Pred, @@ -666,7 +666,7 @@ public: const LocationContext *LCtx, ProgramStateRef State); - /// Evaluate a call, running pre- and post-call checks and allowing checkers + /// Evaluate a call, running pre- and post-call checkers and allowing checkers /// to be responsible for handling the evaluation of the call itself. void evalCall(ExplodedNodeSet &Dst, ExplodedNode *Pred, const CallEvent &Call); diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index 071e35085a5f9..71cbbe28fc258 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -169,6 +169,7 @@ public: Kind getKind() const { return kind; } template<typename RegionTy> const RegionTy* getAs() const; + template<typename RegionTy> const RegionTy* castAs() const; virtual bool isBoundable() const { return false; } @@ -1231,6 +1232,11 @@ const RegionTy* MemRegion::getAs() const { return nullptr; } +template<typename RegionTy> +const RegionTy* MemRegion::castAs() const { + return cast<RegionTy>(this); +} + //===----------------------------------------------------------------------===// // MemRegionManager - Factory object for creating regions. //===----------------------------------------------------------------------===// diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index d38058f9af56d..07920790c80aa 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -507,6 +507,10 @@ public: return *svalBuilder; } + const SValBuilder &getSValBuilder() const { + return *svalBuilder; + } + SymbolManager &getSymbolManager() { return svalBuilder->getSymbolManager(); } |