diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-04-29 22:17:41 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-04-29 22:17:41 +0000 |
commit | 718c4f7b3ff713c3ebee46553d687bde63e5666f (patch) | |
tree | aeb2f3877956ce8c59a70d6925b933133655d906 /include/clang | |
parent | 1b8bd4d71c2098126041b4de4267175a82f0103c (diff) |
Added lval::FieldOffset, which represents symbolic lvalues for field offsets from other Lvalues.
This removes the failure in null-deref-ps.c (test suite).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50449 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/Analysis/PathSensitive/BasicValueFactory.h | 4 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/RValues.h | 56 |
2 files changed, 52 insertions, 8 deletions
diff --git a/include/clang/Analysis/PathSensitive/BasicValueFactory.h b/include/clang/Analysis/PathSensitive/BasicValueFactory.h index 9462ed597d..e36e521d79 100644 --- a/include/clang/Analysis/PathSensitive/BasicValueFactory.h +++ b/include/clang/Analysis/PathSensitive/BasicValueFactory.h @@ -71,8 +71,8 @@ public: const llvm::APSInt& V1, const llvm::APSInt& V2); - const std::pair<RVal, unsigned>& - getPersistentSizedRVal(const RVal& V, unsigned Bits); + const std::pair<RVal, uintptr_t>& + getPersistentRValWithData(const RVal& V, uintptr_t Data); }; } // end clang namespace diff --git a/include/clang/Analysis/PathSensitive/RValues.h b/include/clang/Analysis/PathSensitive/RValues.h index 8a53588564..353046d4be 100644 --- a/include/clang/Analysis/PathSensitive/RValues.h +++ b/include/clang/Analysis/PathSensitive/RValues.h @@ -234,17 +234,20 @@ public: }; class LValAsInteger : public NonLVal { - LValAsInteger(const std::pair<RVal, unsigned>& data) : - NonLVal(LValAsIntegerKind, &data) {} + LValAsInteger(const std::pair<RVal, uintptr_t>& data) : + NonLVal(LValAsIntegerKind, &data) { + assert (isa<LVal>(data.first)); + } public: LVal getLVal() const { - return cast<LVal>(((std::pair<RVal, unsigned>*) Data)->first); + return cast<LVal>(((std::pair<RVal, uintptr_t>*) Data)->first); } const LVal& getPersistentLVal() const { - return cast<LVal>(((std::pair<RVal, unsigned>*) Data)->first); + const RVal& V = ((std::pair<RVal, uintptr_t>*) Data)->first; + return cast<LVal>(V); } unsigned getNumBits() const { @@ -263,7 +266,7 @@ public: static inline LValAsInteger Make(BasicValueFactory& Vals, LVal V, unsigned Bits) { - return LValAsInteger(Vals.getPersistentSizedRVal(V, Bits)); + return LValAsInteger(Vals.getPersistentRValWithData(V, Bits)); } }; @@ -276,7 +279,7 @@ public: namespace lval { enum Kind { SymbolValKind, GotoLabelKind, DeclValKind, FuncValKind, - ConcreteIntKind, StringLiteralValKind }; + ConcreteIntKind, StringLiteralValKind, FieldOffsetKind }; class SymbolVal : public LVal { public: @@ -409,7 +412,48 @@ public: return V->getSubKind() == StringLiteralValKind; } }; + +class FieldOffset : public LVal { + FieldOffset(const std::pair<RVal, uintptr_t>& data) + : LVal(FieldOffsetKind, &data) { + assert (isa<LVal>(data.first)); + } + +public: + + LVal getBase() const { + return reinterpret_cast<const std::pair<LVal,uintptr_t>*> (Data)->first; + } + + const LVal& getPersistentBase() const { + return reinterpret_cast<const std::pair<LVal,uintptr_t>*> (Data)->first; + } + + + FieldDecl* getFieldDecl() const { + return (FieldDecl*) + reinterpret_cast<const std::pair<LVal,uintptr_t>*> (Data)->second; + } + + // Implement isa<T> support. + static inline bool classof(const RVal* V) { + return V->getBaseKind() == LValKind && + V->getSubKind() == FieldOffsetKind; + } + + static inline bool classof(const LVal* V) { + return V->getSubKind() == FieldOffsetKind; + } + + static inline RVal Make(BasicValueFactory& Vals, RVal Base, FieldDecl* D) { + + if (Base.isUnknownOrUndef()) + return Base; + return FieldOffset(Vals.getPersistentRValWithData(cast<LVal>(Base), + (uintptr_t) D)); + } +}; } // end clang::lval namespace } // end clang namespace |