NoQ created this revision.
NoQ added reviewers: zaks.anna, dcoughlin, xazax.hun, a.sidorin.
NoQ added a subscriber: cfe-commits.

Put a lot of run-time checks on how our SVals are constructed, in order to 
maintain the existing status quo.
This should make understanding the hierarchy easier, and probably help us catch 
some bugs.

A couple of subtle bugs were exposed in the process, which were not addressed:

- SymbolConjured for invalidations caused by automatic destructors may possibly 
be reincarnated.
- GenericTaintChecker may produce symbolic expressions of void type.


https://reviews.llvm.org/D26837

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h
  include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
  include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h
  include/clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h
  include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h
  lib/StaticAnalyzer/Core/MemRegion.cpp
  lib/StaticAnalyzer/Core/SVals.cpp

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<nonloc::SymbolVal> SV = getAs<nonloc::SymbolVal>()) {
-    SymbolRef sym = SV->getSymbol();
-    if (isa<SymbolConjured>(sym))
-      return true;
-  }
-
-  if (Optional<loc::MemRegionVal> RV = getAs<loc::MemRegionVal>()) {
-    const MemRegion *R = RV->getRegion();
-    if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
-      SymbolRef sym = SR->getSymbol();
-      if (isa<SymbolConjured>(sym))
-        return true;
-    }
-  }
-
-  return false;
-}
-
 const FunctionDecl *SVal::getAsFunctionDecl() const {
   if (Optional<loc::MemRegionVal> X = getAs<loc::MemRegionVal>()) {
     const MemRegion* R = X->getRegion();
Index: lib/StaticAnalyzer/Core/MemRegion.cpp
===================================================================
--- lib/StaticAnalyzer/Core/MemRegion.cpp
+++ lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -331,6 +331,7 @@
 }
 
 void BlockCodeRegion::Profile(llvm::FoldingSetNodeID& ID) const {
+  locTy->getTypePtr()->isBlockPointerType();
   BlockCodeRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
 }
 
@@ -379,10 +380,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: 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: 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/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,22 +90,16 @@
   template<typename T>
   T castAs() const {
     assert(T::isKind(*this));
-    T t;
-    SVal& sv = t;
-    sv = *this;
-    return t;
+    return *static_cast<const T *>(this);
   }
 
   /// \brief Convert to the specified SVal type, returning None if this SVal is
   /// not of the desired type.
   template<typename T>
   Optional<T> getAs() const {
     if (!T::isKind(*this))
       return None;
-    T t;
-    SVal& sv = t;
-    sv = *this;
-    return t;
+    return *static_cast<const T *>(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<SVal, uintptr_t> &data)
       : NonLoc(LocAsIntegerKind, &data) {
-    assert (data.first.getAs<Loc>());
+    // 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<const LabelDecl*>(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/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<ObjCMethodDecl>(fd) || isa<FunctionDecl>(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<FunctionDecl>(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,17 +655,24 @@
 ///  variables.
 class BlockDataRegion : public TypedRegion {
   friend class MemRegionManager;
+
   const BlockCodeRegion *BC;
   const LocationContext *LC; // Can be null */
   unsigned BlockCount;
   void *ReferencedVars;
   void *OriginalVars;
 
   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<VarDecl>(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<FieldDecl>(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/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<SVal> L;
 
 public:
-  CompoundValData(QualType t, llvm::ImmutableList<SVal> l)
-    : T(t), L(l) {}
+  CompoundValData(QualType t, llvm::ImmutableList<SVal> l) : T(t), L(l) {
+    assert(t->isRecordType() || t->isArrayType() ||
+           t->isVectorType() || t->isComplexType());
+  }
 
   typedef llvm::ImmutableList<SVal>::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; }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to