Index: include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h @@ -20,6 +20,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h" #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h" #include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" namespace clang { namespace ento { @@ -29,8 +30,10 @@ llvm::ImmutableList L; public: - CompoundValData(QualType t, llvm::ImmutableList l) - : T(t), L(l) {} + CompoundValData(QualType t, llvm::ImmutableList l) : T(t), L(l) { + assert(t->isRecordType() || t->isArrayType() || + t->isVectorType() || t->isComplexType()); + } typedef llvm::ImmutableList::iterator iterator; iterator begin() const { return L.begin(); } @@ -47,7 +50,12 @@ const TypedValueRegion *region; public: LazyCompoundValData(const StoreRef &st, const TypedValueRegion *r) - : store(st), region(r) {} + : store(st), region(r) { + assert(r->getValueType()->isRecordType() || + r->getValueType()->isArrayType() || + r->getValueType()->isVectorType() || + r->getValueType()->isComplexType()); + } const void *getStore() const { return store.getStore(); } const TypedValueRegion *getRegion() const { return region; } Index: include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -182,6 +182,7 @@ MemSpaceRegion(MemRegionManager *mgr, Kind k) : MemRegion(k), Mgr(mgr) { assert(classof(this)); + assert(mgr); } MemRegionManager* getMemRegionManager() const override { return Mgr; } @@ -215,9 +216,12 @@ class GlobalsSpaceRegion : public MemSpaceRegion { virtual void anchor(); + protected: - GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) - : MemSpaceRegion(mgr, k) {} + GlobalsSpaceRegion(MemRegionManager *mgr, Kind k) : MemSpaceRegion(mgr, k) { + assert(classof(this)); + } + public: static bool classof(const MemRegion *R) { Kind k = R->getKind(); @@ -236,7 +240,9 @@ const CodeTextRegion *CR; StaticGlobalSpaceRegion(MemRegionManager *mgr, const CodeTextRegion *cr) - : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) {} + : GlobalsSpaceRegion(mgr, StaticGlobalSpaceRegionKind), CR(cr) { + assert(cr); + } public: void Profile(llvm::FoldingSetNodeID &ID) const override; @@ -257,9 +263,13 @@ /// RegionStoreManager::invalidateRegions (instead of finding all the dependent /// globals, we invalidate the whole parent region). class NonStaticGlobalSpaceRegion : public GlobalsSpaceRegion { + virtual void anchor() override; + protected: NonStaticGlobalSpaceRegion(MemRegionManager *mgr, Kind k) - : GlobalsSpaceRegion(mgr, k) {} + : GlobalsSpaceRegion(mgr, k) { + assert(classof(this)); + } public: @@ -326,7 +336,6 @@ }; class HeapSpaceRegion : public MemSpaceRegion { - virtual void anchor(); friend class MemRegionManager; HeapSpaceRegion(MemRegionManager *mgr) @@ -341,10 +350,10 @@ }; class UnknownSpaceRegion : public MemSpaceRegion { - virtual void anchor(); friend class MemRegionManager; UnknownSpaceRegion(MemRegionManager *mgr) - : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {} + : MemSpaceRegion(mgr, UnknownSpaceRegionKind) {} + public: void dumpToStream(raw_ostream &os) const override; @@ -355,13 +364,15 @@ }; class StackSpaceRegion : public MemSpaceRegion { -private: + virtual void anchor(); + const StackFrameContext *SFC; protected: StackSpaceRegion(MemRegionManager *mgr, Kind k, const StackFrameContext *sfc) : MemSpaceRegion(mgr, k), SFC(sfc) { assert(classof(this)); + assert(sfc); } public: @@ -376,7 +387,6 @@ }; class StackLocalsSpaceRegion : public StackSpaceRegion { - virtual void anchor(); friend class MemRegionManager; StackLocalsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) : StackSpaceRegion(mgr, StackLocalsSpaceRegionKind, sfc) {} @@ -391,7 +401,6 @@ class StackArgumentsSpaceRegion : public StackSpaceRegion { private: - virtual void anchor(); friend class MemRegionManager; StackArgumentsSpaceRegion(MemRegionManager *mgr, const StackFrameContext *sfc) : StackSpaceRegion(mgr, StackArgumentsSpaceRegionKind, sfc) {} @@ -408,11 +417,15 @@ /// SubRegion - A region that subsets another larger region. Most regions /// are subclasses of SubRegion. class SubRegion : public MemRegion { -private: virtual void anchor(); + protected: const MemRegion* superRegion; - SubRegion(const MemRegion* sReg, Kind k) : MemRegion(k), superRegion(sReg) {} + SubRegion(const MemRegion *sReg, Kind k) : MemRegion(k), superRegion(sReg) { + assert(classof(this)); + assert(sReg); + } + public: const MemRegion* getSuperRegion() const { return superRegion; @@ -440,13 +453,18 @@ /// by a call to 'alloca'. class AllocaRegion : public SubRegion { friend class MemRegionManager; -protected: + unsigned Cnt; // Block counter. Used to distinguish different pieces of // memory allocated by alloca at the same call site. const Expr *Ex; AllocaRegion(const Expr *ex, unsigned cnt, const MemRegion *superRegion) - : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {} + : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) { + assert(Ex); + } + + static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex, + unsigned Cnt, const MemRegion *superRegion); public: @@ -458,9 +476,6 @@ void Profile(llvm::FoldingSetNodeID& ID) const override; - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Expr *Ex, - unsigned Cnt, const MemRegion *superRegion); - void dumpToStream(raw_ostream &os) const override; static bool classof(const MemRegion* R) { @@ -470,10 +485,12 @@ /// TypedRegion - An abstract class representing regions that are typed. class TypedRegion : public SubRegion { -public: - void anchor() override; + virtual void anchor() override; + protected: - TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {} + TypedRegion(const MemRegion *sReg, Kind k) : SubRegion(sReg, k) { + assert(classof(this)); + } public: virtual QualType getLocationType() const = 0; @@ -492,10 +509,12 @@ /// TypedValueRegion - An abstract class representing regions having a typed value. class TypedValueRegion : public TypedRegion { -public: - void anchor() override; + virtual void anchor() override; + protected: - TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) {} + TypedValueRegion(const MemRegion* sReg, Kind k) : TypedRegion(sReg, k) { + assert(classof(this)); + } public: virtual QualType getValueType() const = 0; @@ -524,10 +543,13 @@ class CodeTextRegion : public TypedRegion { -public: - void anchor() override; + virtual void anchor() override; + protected: - CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {} + CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) { + assert(classof(this)); + } + public: bool isBoundable() const override { return false; } @@ -539,13 +561,19 @@ /// FunctionCodeRegion - A region that represents code texts of function. class FunctionCodeRegion : public CodeTextRegion { + friend class MemRegionManager; + const NamedDecl *FD; -public: + FunctionCodeRegion(const NamedDecl *fd, const MemRegion* sreg) : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) { assert(isa(fd) || isa(fd)); } + static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD, + const MemRegion*); + +public: QualType getLocationType() const override { const ASTContext &Ctx = getContext(); if (const FunctionDecl *D = dyn_cast(FD)) { @@ -568,9 +596,6 @@ void Profile(llvm::FoldingSetNodeID& ID) const override; - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD, - const MemRegion*); - static bool classof(const MemRegion* R) { return R->getKind() == FunctionCodeRegionKind; } @@ -592,7 +617,15 @@ BlockCodeRegion(const BlockDecl *bd, CanQualType lTy, AnalysisDeclContext *ac, const MemRegion* sreg) - : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) {} + : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) { + assert(bd); + assert(ac); + assert(lTy->getTypePtr()->isBlockPointerType()); + } + + static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD, + CanQualType, const AnalysisDeclContext*, + const MemRegion*); public: QualType getLocationType() const override { @@ -609,10 +642,6 @@ void Profile(llvm::FoldingSetNodeID& ID) const override; - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const BlockDecl *BD, - CanQualType, const AnalysisDeclContext*, - const MemRegion*); - static bool classof(const MemRegion* R) { return R->getKind() == BlockCodeRegionKind; } @@ -626,6 +655,7 @@ /// variables. class BlockDataRegion : public TypedRegion { friend class MemRegionManager; + const BlockCodeRegion *BC; const LocationContext *LC; // Can be null */ unsigned BlockCount; @@ -634,9 +664,15 @@ BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc, unsigned count, const MemRegion *sreg) - : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), - BlockCount(count), - ReferencedVars(nullptr), OriginalVars(nullptr) {} + : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc), + BlockCount(count), ReferencedVars(nullptr), OriginalVars(nullptr) { + assert(bc); + assert(lc); + } + + static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *, + const LocationContext *, unsigned, + const MemRegion *); public: const BlockCodeRegion *getCodeRegion() const { return BC; } @@ -686,10 +722,6 @@ void Profile(llvm::FoldingSetNodeID& ID) const override; - static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *, - const LocationContext *, unsigned, - const MemRegion *); - static bool classof(const MemRegion* R) { return R->getKind() == BlockDataRegionKind; } @@ -705,13 +737,19 @@ /// map the concept of symbolic values into the domain of regions. Symbolic /// regions do not need to be typed. class SymbolicRegion : public SubRegion { -protected: + friend class MemRegionManager; + const SymbolRef sym; -public: - SymbolicRegion(const SymbolRef s, const MemRegion* sreg) - : SubRegion(sreg, SymbolicRegionKind), sym(s) {} + SymbolicRegion(const SymbolRef s, const MemRegion *sreg) + : SubRegion(sreg, SymbolicRegionKind), sym(s) { + assert(s); + assert(s->getType()->isAnyPointerType() || + s->getType()->isReferenceType() || + s->getType()->isBlockPointerType()); + } +public: SymbolRef getSymbol() const { return sym; } @@ -736,11 +774,13 @@ /// StringRegion - Region associated with a StringLiteral. class StringRegion : public TypedValueRegion { friend class MemRegionManager; + const StringLiteral* Str; -protected: - StringRegion(const StringLiteral* str, const MemRegion* sreg) - : TypedValueRegion(sreg, StringRegionKind), Str(str) {} + StringRegion(const StringLiteral *str, const MemRegion *sreg) + : TypedValueRegion(sreg, StringRegionKind), Str(str) { + assert(str); + } static void ProfileRegion(llvm::FoldingSetNodeID& ID, const StringLiteral* Str, @@ -772,12 +812,14 @@ /// The region associated with an ObjCStringLiteral. class ObjCStringRegion : public TypedValueRegion { friend class MemRegionManager; + const ObjCStringLiteral* Str; -protected: - - ObjCStringRegion(const ObjCStringLiteral* str, const MemRegion* sreg) - : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {} - + + ObjCStringRegion(const ObjCStringLiteral *str, const MemRegion *sreg) + : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) { + assert(str); + } + static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCStringLiteral* Str, const MemRegion* superRegion); @@ -807,12 +849,14 @@ /// Compound literals are essentially temporaries that are stack allocated /// or in the global constant pool. class CompoundLiteralRegion : public TypedValueRegion { -private: friend class MemRegionManager; + const CompoundLiteralExpr *CL; - CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion* sReg) - : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {} + CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion *sReg) + : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) { + assert(cl); + } static void ProfileRegion(llvm::FoldingSetNodeID& ID, const CompoundLiteralExpr *CL, @@ -839,8 +883,11 @@ protected: const Decl *D; - DeclRegion(const Decl *d, const MemRegion* sReg, Kind k) - : TypedValueRegion(sReg, k), D(d) {} + DeclRegion(const Decl *d, const MemRegion *sReg, Kind k) + : TypedValueRegion(sReg, k), D(d) { + assert(classof(this)); + assert(d); + } static void ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D, const MemRegion* superRegion, Kind k); @@ -867,9 +914,9 @@ DeclRegion::ProfileRegion(ID, VD, superRegion, VarRegionKind); } +public: void Profile(llvm::FoldingSetNodeID& ID) const override; -public: const VarDecl *getDecl() const { return cast(D); } const StackFrameContext *getStackFrame() const; @@ -895,17 +942,18 @@ /// referred to by 'this', but rather 'this' itself. class CXXThisRegion : public TypedValueRegion { friend class MemRegionManager; - CXXThisRegion(const PointerType *thisPointerTy, - const MemRegion *sReg) - : TypedValueRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {} + + CXXThisRegion(const PointerType *thisPointerTy, const MemRegion *sReg) + : TypedValueRegion(sReg, CXXThisRegionKind), + ThisPointerTy(thisPointerTy) {} static void ProfileRegion(llvm::FoldingSetNodeID &ID, const PointerType *PT, const MemRegion *sReg); +public: void Profile(llvm::FoldingSetNodeID &ID) const override; -public: QualType getValueType() const override { return QualType(ThisPointerTy, 0); } @@ -926,6 +974,11 @@ FieldRegion(const FieldDecl *fd, const MemRegion* sReg) : DeclRegion(fd, sReg, FieldRegionKind) {} + static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD, + const MemRegion* superRegion) { + DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind); + } + public: const FieldDecl *getDecl() const { return cast(D); } @@ -936,11 +989,6 @@ DefinedOrUnknownSVal getExtent(SValBuilder &svalBuilder) const override; - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD, - const MemRegion* superRegion) { - DeclRegion::ProfileRegion(ID, FD, superRegion, FieldRegionKind); - } - static bool classof(const MemRegion* R) { return R->getKind() == FieldRegionKind; } @@ -954,7 +1002,6 @@ }; class ObjCIvarRegion : public DeclRegion { - friend class MemRegionManager; ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg); @@ -982,7 +1029,6 @@ class ElementRegion; class RegionRawOffset { -private: friend class ElementRegion; const MemRegion *Region; @@ -1047,12 +1093,14 @@ Expr const *Ex; - CXXTempObjectRegion(Expr const *E, MemRegion const *sReg) - : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {} + CXXTempObjectRegion(Expr const *E, MemRegion const *sReg) + : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) { + assert(E); + } static void ProfileRegion(llvm::FoldingSetNodeID &ID, Expr const *E, const MemRegion *sReg); - + public: const Expr *getExpr() const { return Ex; } @@ -1078,7 +1126,9 @@ CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual, const MemRegion *SReg) - : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {} + : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) { + assert(RD); + } static void ProfileRegion(llvm::FoldingSetNodeID &ID, const CXXRecordDecl *RD, bool IsVirtual, const MemRegion *SReg); Index: include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -40,6 +40,22 @@ class ProgramStateManager; class SValBuilder; +namespace nonloc { +/// Sub-kinds for NonLoc values. +enum Kind { +#define NONLOC_SVAL(Id, Parent) Id ## Kind, +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" +}; +} + +namespace loc { +/// Sub-kinds for Loc values. +enum Kind { +#define LOC_SVAL(Id, Parent) Id ## Kind, +#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" +}; +} + /// SVal - This represents a symbolic expression, which can be either /// an L-value or an R-value. /// @@ -74,10 +90,7 @@ template T castAs() const { assert(T::isKind(*this)); - T t; - SVal& sv = t; - sv = *this; - return t; + return *static_cast(this); } /// \brief Convert to the specified SVal type, returning None if this SVal is @@ -86,10 +99,7 @@ Optional getAs() const { if (!T::isKind(*this)) return None; - T t; - SVal& sv = t; - sv = *this; - return t; + return *static_cast(this); } /// BufferTy - A temporary buffer to hold a set of SVals. @@ -136,9 +146,6 @@ bool isZeroConstant() const; - /// hasConjuredSymbol - If this SVal wraps a conjured symbol, return true; - bool hasConjuredSymbol() const; - /// getAsFunctionDecl - If this SVal is a MemRegionVal and wraps a /// CodeTextRegion wrapping a FunctionDecl, return that FunctionDecl. /// Otherwise return 0. @@ -306,15 +313,11 @@ namespace nonloc { -enum Kind { -#define NONLOC_SVAL(Id, Parent) Id ## Kind, -#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" -}; - /// \brief Represents symbolic expression. class SymbolVal : public NonLoc { public: - SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) {} + SymbolVal() = delete; + SymbolVal(SymbolRef sym) : NonLoc(SymbolValKind, sym) { assert(sym); } SymbolRef getSymbol() const { return (const SymExpr*) Data; @@ -326,7 +329,6 @@ private: friend class SVal; - SymbolVal() {} static bool isKind(const SVal& V) { return V.getBaseKind() == NonLocKind && V.getSubKind() == SymbolValKind; @@ -372,7 +374,11 @@ explicit LocAsInteger(const std::pair &data) : NonLoc(LocAsIntegerKind, &data) { - assert (data.first.getAs()); + // We do not need to represent loc::ConcreteInt as LocAsInteger, + // as it'd collapse into a nonloc::ConcreteInt instead. + assert(data.first.getBaseKind() == LocKind && + (data.first.getSubKind() == loc::MemRegionValKind || + data.first.getSubKind() == loc::GotoLabelKind)); } public: @@ -467,14 +473,11 @@ namespace loc { -enum Kind { -#define LOC_SVAL(Id, Parent) Id ## Kind, -#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.def" -}; - class GotoLabel : public Loc { public: - explicit GotoLabel(LabelDecl *Label) : Loc(GotoLabelKind, Label) {} + explicit GotoLabel(LabelDecl *Label) : Loc(GotoLabelKind, Label) { + assert(Label); + } const LabelDecl *getLabel() const { return static_cast(Data); @@ -495,7 +498,9 @@ class MemRegionVal : public Loc { public: - explicit MemRegionVal(const MemRegion* r) : Loc(MemRegionValKind, r) {} + explicit MemRegionVal(const MemRegion* r) : Loc(MemRegionValKind, r) { + assert(r); + } /// \brief Get the underlining region. const MemRegion* getRegion() const { Index: include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h @@ -42,6 +42,12 @@ protected: SymExpr(Kind k) : K(k) {} + static bool isValidTypeForSymbol(QualType T) { + // FIXME: Depending on wether we choose to deprecate structural symbols, + // this may become much stricter. + return !T.isNull() && !T->isVoidType(); + } + public: virtual ~SymExpr() {} @@ -103,7 +109,9 @@ const SymbolID Sym; protected: - SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) {} + SymbolData(Kind k, SymbolID sym) : SymExpr(k), Sym(sym) { + assert(classof(this)); + } public: ~SymbolData() override {} Index: include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h =================================================================== --- include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -44,7 +44,10 @@ public: SymbolRegionValue(SymbolID sym, const TypedValueRegion *r) - : SymbolData(SymbolRegionValueKind, sym), R(r) {} + : SymbolData(SymbolRegionValueKind, sym), R(r) { + assert(r); + assert(isValidTypeForSymbol(r->getValueType())); + } const TypedValueRegion* getRegion() const { return R; } @@ -81,7 +84,15 @@ SymbolConjured(SymbolID sym, const Stmt *s, const LocationContext *lctx, QualType t, unsigned count, const void *symbolTag) : SymbolData(SymbolConjuredKind, sym), S(s), T(t), Count(count), - LCtx(lctx), SymbolTag(symbolTag) {} + LCtx(lctx), SymbolTag(symbolTag) { + // FIXME: 's' might be a nullptr if we're conducting invalidation + // that was caused by a destructor call on a temporary object, + // which has no statement associated with it. + // Due to this, we might be creating the same invalidation symbol for + // two different invalidation passes (for two different temporaries). + assert(lctx); + assert(isValidTypeForSymbol(t)); + } const Stmt *getStmt() const { return S; } unsigned getCount() const { return Count; } @@ -120,7 +131,11 @@ public: SymbolDerived(SymbolID sym, SymbolRef parent, const TypedValueRegion *r) - : SymbolData(SymbolDerivedKind, sym), parentSymbol(parent), R(r) {} + : SymbolData(SymbolDerivedKind, sym), parentSymbol(parent), R(r) { + assert(parent); + assert(r); + assert(isValidTypeForSymbol(r->getValueType())); + } SymbolRef getParentSymbol() const { return parentSymbol; } const TypedValueRegion *getRegion() const { return R; } @@ -155,7 +170,9 @@ public: SymbolExtent(SymbolID sym, const SubRegion *r) - : SymbolData(SymbolExtentKind, sym), R(r) {} + : SymbolData(SymbolExtentKind, sym), R(r) { + assert(r); + } const SubRegion *getRegion() const { return R; } @@ -193,7 +210,13 @@ SymbolMetadata(SymbolID sym, const MemRegion* r, const Stmt *s, QualType t, const LocationContext *LCtx, unsigned count, const void *tag) : SymbolData(SymbolMetadataKind, sym), R(r), S(s), T(t), LCtx(LCtx), - Count(count), Tag(tag) {} + Count(count), Tag(tag) { + assert(r); + assert(s); + assert(isValidTypeForSymbol(t)); + assert(LCtx); + assert(tag); + } const MemRegion *getRegion() const { return R; } const Stmt *getStmt() const { return S; } @@ -236,8 +259,13 @@ QualType ToTy; public: - SymbolCast(const SymExpr *In, QualType From, QualType To) : - SymExpr(SymbolCastKind), Operand(In), FromTy(From), ToTy(To) { } + SymbolCast(const SymExpr *In, QualType From, QualType To) + : SymExpr(SymbolCastKind), Operand(In), FromTy(From), ToTy(To) { + assert(In); + assert(isValidTypeForSymbol(From)); + // FIXME: GenericTaintChecker creates symbols of void type. + // Otherwise, 'To' should also be a valid type. + } QualType getType() const override { return ToTy; } @@ -270,7 +298,10 @@ protected: BinarySymExpr(Kind k, BinaryOperator::Opcode op, QualType t) - : SymExpr(k), Op(op), T(t) {} + : SymExpr(k), Op(op), T(t) { + assert(classof(this)); + assert(isValidTypeForSymbol(t)); + } public: // FIXME: We probably need to make this out-of-line to avoid redundant @@ -293,8 +324,10 @@ public: SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op, - const llvm::APSInt& rhs, QualType t) - : BinarySymExpr(SymIntExprKind, op, t), LHS(lhs), RHS(rhs) {} + const llvm::APSInt &rhs, QualType t) + : BinarySymExpr(SymIntExprKind, op, t), LHS(lhs), RHS(rhs) { + assert(lhs); + } void dumpToStream(raw_ostream &os) const override; @@ -327,9 +360,11 @@ const SymExpr *RHS; public: - IntSymExpr(const llvm::APSInt& lhs, BinaryOperator::Opcode op, + IntSymExpr(const llvm::APSInt &lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) - : BinarySymExpr(IntSymExprKind, op, t), LHS(lhs), RHS(rhs) {} + : BinarySymExpr(IntSymExprKind, op, t), LHS(lhs), RHS(rhs) { + assert(rhs); + } void dumpToStream(raw_ostream &os) const override; @@ -364,7 +399,10 @@ public: SymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) - : BinarySymExpr(SymSymExprKind, op, t), LHS(lhs), RHS(rhs) {} + : BinarySymExpr(SymSymExprKind, op, t), LHS(lhs), RHS(rhs) { + assert(lhs); + assert(rhs); + } const SymExpr *getLHS() const { return LHS; } const SymExpr *getRHS() const { return RHS; } Index: lib/StaticAnalyzer/Core/MemRegion.cpp =================================================================== --- lib/StaticAnalyzer/Core/MemRegion.cpp +++ lib/StaticAnalyzer/Core/MemRegion.cpp @@ -379,10 +379,8 @@ //===----------------------------------------------------------------------===// void GlobalsSpaceRegion::anchor() { } -void HeapSpaceRegion::anchor() { } -void UnknownSpaceRegion::anchor() { } -void StackLocalsSpaceRegion::anchor() { } -void StackArgumentsSpaceRegion::anchor() { } +void NonStaticGlobalSpaceRegion::anchor() { } +void StackSpaceRegion::anchor() { } void TypedRegion::anchor() { } void TypedValueRegion::anchor() { } void CodeTextRegion::anchor() { } Index: lib/StaticAnalyzer/Core/SVals.cpp =================================================================== --- lib/StaticAnalyzer/Core/SVals.cpp +++ lib/StaticAnalyzer/Core/SVals.cpp @@ -29,25 +29,6 @@ // Utility methods. //===----------------------------------------------------------------------===// -bool SVal::hasConjuredSymbol() const { - if (Optional SV = getAs()) { - SymbolRef sym = SV->getSymbol(); - if (isa(sym)) - return true; - } - - if (Optional RV = getAs()) { - const MemRegion *R = RV->getRegion(); - if (const SymbolicRegion *SR = dyn_cast(R)) { - SymbolRef sym = SR->getSymbol(); - if (isa(sym)) - return true; - } - } - - return false; -} - const FunctionDecl *SVal::getAsFunctionDecl() const { if (Optional X = getAs()) { const MemRegion* R = X->getRegion();