diff options
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h | 22 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h | 12 |
2 files changed, 27 insertions, 7 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h index f6c5830c29..1303acb3f9 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h @@ -68,15 +68,22 @@ public: } }; +/// \class RuntimeDefinition /// \brief Defines the runtime definition of the called function. +/// +/// 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 +/// precise. class RuntimeDefinition { - /// The Declaration of the function which will be called at runtime. - /// 0 if not available. + /// The Declaration of the function which could be called at runtime. + /// NULL if not available. const Decl *D; /// The region representing an object (ObjC/C++) on which the method is /// called. With dynamic dispatch, the method definition depends on the - /// runtime type of this object. 0 when there is no dynamic dispatch. + /// runtime type of this object. NULL when the DynamicTypeInfo is + /// precise. const MemRegion *R; public: @@ -84,8 +91,15 @@ public: RuntimeDefinition(const Decl *InD): D(InD), R(0) {} RuntimeDefinition(const Decl *InD, const MemRegion *InR): D(InD), R(InR) {} const Decl *getDecl() { return D; } - const MemRegion *getDispatchRegion() { return R; } + + /// \brief 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 != 0; } + + /// When other definitions are possible, returns the region whose runtime type + /// determines the method definition. + const MemRegion *getDispatchRegion() { return R; } }; /// \brief Represents an abstract call to a function or method along a diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h index a4d086ed4d..522228bff8 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h @@ -56,9 +56,10 @@ template <typename T> struct ProgramStateTrait { } }; -/// \class Stores the dynamic type information. -/// Information about type of an object at runtime. This is used by dynamic -/// dispatch implementation. +/// \class DynamicTypeInfo +/// +/// \brief Stores the currently inferred strictest bound on the runtime type +/// of a region in a given state along the analysis path. class DynamicTypeInfo { QualType T; bool CanBeASubClass; @@ -68,9 +69,14 @@ public: DynamicTypeInfo(QualType WithType, bool CanBeSub = true) : T(WithType), CanBeASubClass(CanBeSub) {} + /// \brief Return true if no dynamic type info is available. bool isValid() const { return !T.isNull(); } + /// \brief Returns the currently inferred upper bound on the runtime type. QualType getType() const { return T; } + + /// \brief Returns false if the type T is the only type in the lattice + /// (the type information is precise), true otherwise. bool canBeASubClass() const { return CanBeASubClass; } void Profile(llvm::FoldingSetNodeID &ID) const { |