[analyzer] Enforce super-region classes for various memory regions.
authorArtem Dergachev <artem.dergachev@gmail.com>
Thu, 13 Apr 2017 09:56:07 +0000 (09:56 +0000)
committerArtem Dergachev <artem.dergachev@gmail.com>
Thu, 13 Apr 2017 09:56:07 +0000 (09:56 +0000)
We now check the type of the super-region pointer for most SubRegion classes
in compile time; some checks are run-time though.

This is an API-breaking change (we now require explicit casts to specific region
sub-classes), but in practice very few checkers are affected.

Differential Revision: https://reviews.llvm.org/D26838

llvm-svn: 300189

clang/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h
clang/include/clang/StaticAnalyzer/Core/PathSensitive/Store.h
clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
clang/lib/StaticAnalyzer/Core/MemRegion.cpp
clang/lib/StaticAnalyzer/Core/RegionStore.cpp
clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
clang/lib/StaticAnalyzer/Core/Store.cpp

index bb0caf9..29b1c4c 100644 (file)
@@ -458,8 +458,8 @@ class AllocaRegion : public SubRegion {
                 // 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) {
+  AllocaRegion(const Expr *ex, unsigned cnt, const MemSpaceRegion *superRegion)
+      : SubRegion(superRegion, AllocaRegionKind), Cnt(cnt), Ex(ex) {
     assert(Ex);
   }
 
@@ -546,7 +546,7 @@ class CodeTextRegion : public TypedRegion {
   virtual void anchor() override;
 
 protected:
-  CodeTextRegion(const MemRegion *sreg, Kind k) : TypedRegion(sreg, k) {
+  CodeTextRegion(const MemSpaceRegion *sreg, Kind k) : TypedRegion(sreg, k) {
     assert(classof(this));
   }
 
@@ -565,7 +565,7 @@ class FunctionCodeRegion : public CodeTextRegion {
 
   const NamedDecl *FD;
 
-  FunctionCodeRegion(const NamedDecl *fd, const MemRegion* sreg)
+  FunctionCodeRegion(const NamedDecl *fd, const CodeSpaceRegion* sreg)
     : CodeTextRegion(sreg, FunctionCodeRegionKind), FD(fd) {
     assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd));
   }
@@ -616,7 +616,7 @@ class BlockCodeRegion : public CodeTextRegion {
   CanQualType locTy;
 
   BlockCodeRegion(const BlockDecl *bd, CanQualType lTy,
-                  AnalysisDeclContext *ac, const MemRegion* sreg)
+                  AnalysisDeclContext *ac, const CodeSpaceRegion* sreg)
       : CodeTextRegion(sreg, BlockCodeRegionKind), BD(bd), AC(ac), locTy(lTy) {
     assert(bd);
     assert(ac);
@@ -663,11 +663,14 @@ class BlockDataRegion : public TypedRegion {
   void *OriginalVars;
 
   BlockDataRegion(const BlockCodeRegion *bc, const LocationContext *lc,
-                  unsigned count, const MemRegion *sreg)
+                  unsigned count, const MemSpaceRegion *sreg)
       : TypedRegion(sreg, BlockDataRegionKind), BC(bc), LC(lc),
         BlockCount(count), ReferencedVars(nullptr), OriginalVars(nullptr) {
     assert(bc);
     assert(lc);
+    assert(isa<GlobalImmutableSpaceRegion>(sreg) ||
+           isa<StackLocalsSpaceRegion>(sreg) ||
+           isa<UnknownSpaceRegion>(sreg));
   }
 
   static void ProfileRegion(llvm::FoldingSetNodeID&, const BlockCodeRegion *,
@@ -741,12 +744,13 @@ class SymbolicRegion : public SubRegion {
 
   const SymbolRef sym;
 
-  SymbolicRegion(const SymbolRef s, const MemRegion *sreg)
+  SymbolicRegion(const SymbolRef s, const MemSpaceRegion *sreg)
       : SubRegion(sreg, SymbolicRegionKind), sym(s) {
     assert(s);
     assert(s->getType()->isAnyPointerType() ||
            s->getType()->isReferenceType() ||
            s->getType()->isBlockPointerType());
+    assert(isa<UnknownSpaceRegion>(sreg) || isa<HeapSpaceRegion>(sreg));
   }
 
 public:
@@ -777,7 +781,7 @@ class StringRegion : public TypedValueRegion {
 
   const StringLiteral* Str;
 
-  StringRegion(const StringLiteral *str, const MemRegion *sreg)
+  StringRegion(const StringLiteral *str, const GlobalInternalSpaceRegion *sreg)
       : TypedValueRegion(sreg, StringRegionKind), Str(str) {
     assert(str);
   }
@@ -815,7 +819,8 @@ class ObjCStringRegion : public TypedValueRegion {
 
   const ObjCStringLiteral* Str;
 
-  ObjCStringRegion(const ObjCStringLiteral *str, const MemRegion *sreg)
+  ObjCStringRegion(const ObjCStringLiteral *str,
+                   const GlobalInternalSpaceRegion *sreg)
       : TypedValueRegion(sreg, ObjCStringRegionKind), Str(str) {
     assert(str);
   }
@@ -853,9 +858,12 @@ class CompoundLiteralRegion : public TypedValueRegion {
 
   const CompoundLiteralExpr *CL;
 
-  CompoundLiteralRegion(const CompoundLiteralExpr *cl, const MemRegion *sReg)
+  CompoundLiteralRegion(const CompoundLiteralExpr *cl,
+                        const MemSpaceRegion *sReg)
       : TypedValueRegion(sReg, CompoundLiteralRegionKind), CL(cl) {
     assert(cl);
+    assert(isa<GlobalInternalSpaceRegion>(sReg) ||
+           isa<StackLocalsSpaceRegion>(sReg));
   }
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID,
@@ -906,8 +914,15 @@ class VarRegion : public DeclRegion {
   friend class MemRegionManager;
 
   // Constructors and private methods.
-  VarRegion(const VarDecl *vd, const MemRegion* sReg)
-    : DeclRegion(vd, sReg, VarRegionKind) {}
+  VarRegion(const VarDecl *vd, const MemRegion *sReg)
+      : DeclRegion(vd, sReg, VarRegionKind) {
+    // VarRegion appears in unknown space when it's a block variable as seen
+    // from a block using it, when this block is analyzed at top-level.
+    // Other block variables appear within block data regions,
+    // which, unlike everything else on this list, are not memory spaces.
+    assert(isa<GlobalsSpaceRegion>(sReg) || isa<StackSpaceRegion>(sReg) ||
+           isa<BlockDataRegion>(sReg) || isa<UnknownSpaceRegion>(sReg));
+  }
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const VarDecl *VD,
                             const MemRegion *superRegion) {
@@ -943,7 +958,8 @@ public:
 class CXXThisRegion : public TypedValueRegion {
   friend class MemRegionManager;
 
-  CXXThisRegion(const PointerType *thisPointerTy, const MemRegion *sReg)
+  CXXThisRegion(const PointerType *thisPointerTy,
+                const StackArgumentsSpaceRegion *sReg)
       : TypedValueRegion(sReg, CXXThisRegionKind),
         ThisPointerTy(thisPointerTy) {}
 
@@ -971,7 +987,7 @@ private:
 class FieldRegion : public DeclRegion {
   friend class MemRegionManager;
 
-  FieldRegion(const FieldDecl *fd, const MemRegion* sReg)
+  FieldRegion(const FieldDecl *fd, const SubRegion* sReg)
     : DeclRegion(fd, sReg, FieldRegionKind) {}
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FieldDecl *FD,
@@ -1004,7 +1020,7 @@ public:
 class ObjCIvarRegion : public DeclRegion {
   friend class MemRegionManager;
 
-  ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg);
+  ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg);
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, const ObjCIvarDecl *ivd,
                             const MemRegion* superRegion);
@@ -1053,9 +1069,9 @@ class ElementRegion : public TypedValueRegion {
   QualType ElementType;
   NonLoc Index;
 
-  ElementRegion(QualType elementType, NonLoc Idx, const MemRegion* sReg)
-    : TypedValueRegion(sReg, ElementRegionKind),
-      ElementType(elementType), Index(Idx) {
+  ElementRegion(QualType elementType, NonLoc Idx, const SubRegion *sReg)
+      : TypedValueRegion(sReg, ElementRegionKind),
+        ElementType(elementType), Index(Idx) {
     assert((!Idx.getAs<nonloc::ConcreteInt>() ||
             Idx.castAs<nonloc::ConcreteInt>().getValue().isSigned()) &&
            "The index must be signed");
@@ -1093,9 +1109,11 @@ class CXXTempObjectRegion : public TypedValueRegion {
 
   Expr const *Ex;
 
-  CXXTempObjectRegion(Expr const *E, MemRegion const *sReg)
+  CXXTempObjectRegion(Expr const *E, MemSpaceRegion const *sReg)
       : TypedValueRegion(sReg, CXXTempObjectRegionKind), Ex(E) {
     assert(E);
+    assert(isa<StackLocalsSpaceRegion>(sReg) ||
+           isa<GlobalInternalSpaceRegion>(sReg));
   }
 
   static void ProfileRegion(llvm::FoldingSetNodeID &ID,
@@ -1125,7 +1143,7 @@ class CXXBaseObjectRegion : public TypedValueRegion {
   llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> Data;
 
   CXXBaseObjectRegion(const CXXRecordDecl *RD, bool IsVirtual,
-                      const MemRegion *SReg)
+                      const SubRegion *SReg)
       : TypedValueRegion(SReg, CXXBaseObjectRegionKind), Data(RD, IsVirtual) {
     assert(RD);
   }
@@ -1254,16 +1272,16 @@ public:
 
   /// getVarRegion - Retrieve or create the memory region associated with
   ///  a specified VarDecl and super region.
-  const VarRegiongetVarRegion(const VarDecl *D, const MemRegion *superR);
-  
+  const VarRegion *getVarRegion(const VarDecl *D, const MemRegion *superR);
+
   /// getElementRegion - Retrieve the memory region associated with the
   ///  associated element type, index, and super region.
   const ElementRegion *getElementRegion(QualType elementType, NonLoc Idx,
-                                        const MemRegion *superRegion,
+                                        const SubRegion *superRegion,
                                         ASTContext &Ctx);
 
   const ElementRegion *getElementRegionWithSuper(const ElementRegion *ER,
-                                                 const MemRegion *superRegion) {
+                                                 const SubRegion *superRegion) {
     return getElementRegion(ER->getElementType(), ER->getIndex(),
                             superRegion, ER->getContext());
   }
@@ -1273,10 +1291,10 @@ public:
   ///  memory region (which typically represents the memory representing
   ///  a structure or class).
   const FieldRegion *getFieldRegion(const FieldDecl *fd,
-                                    const MemRegion* superRegion);
+                                    const SubRegion* superRegion);
 
   const FieldRegion *getFieldRegionWithSuper(const FieldRegion *FR,
-                                             const MemRegion *superRegion) {
+                                             const SubRegion *superRegion) {
     return getFieldRegion(FR->getDecl(), superRegion);
   }
 
@@ -1285,7 +1303,7 @@ public:
   ///   to the containing region (which typically represents the Objective-C
   ///   object).
   const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl *ivd,
-                                          const MemRegion* superRegion);
+                                          const SubRegion* superRegion);
 
   const CXXTempObjectRegion *getCXXTempObjectRegion(Expr const *Ex,
                                                     LocationContext const *LC);
@@ -1295,14 +1313,14 @@ public:
   ///
   /// The type of \p Super is assumed be a class deriving from \p BaseClass.
   const CXXBaseObjectRegion *
-  getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const MemRegion *Super,
+  getCXXBaseObjectRegion(const CXXRecordDecl *BaseClass, const SubRegion *Super,
                          bool IsVirtual);
 
   /// Create a CXXBaseObjectRegion with the same CXXRecordDecl but a different
   /// super region.
   const CXXBaseObjectRegion *
   getCXXBaseObjectRegionWithSuper(const CXXBaseObjectRegion *baseReg, 
-                                  const MemRegion *superRegion) {
+                                  const SubRegion *superRegion) {
     return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion,
                                   baseReg->isVirtual());
   }
@@ -1326,17 +1344,22 @@ public:
   const CXXTempObjectRegion *getCXXStaticTempObjectRegion(const Expr *Ex);
 
 private:
-  template <typename RegionTy, typename A1>
-  RegionTy* getSubRegion(const A1 a1, const MemRegion* superRegion);
+  template <typename RegionTy, typename SuperTy,
+            typename Arg1Ty>
+  RegionTy* getSubRegion(const Arg1Ty arg1,
+                         const SuperTy* superRegion);
+
+  template <typename RegionTy, typename SuperTy,
+            typename Arg1Ty, typename Arg2Ty>
+  RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
+                         const SuperTy* superRegion);
+
+  template <typename RegionTy, typename SuperTy,
+            typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
+  RegionTy* getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
+                         const Arg3Ty arg3,
+                         const SuperTy* superRegion);
 
-  template <typename RegionTy, typename A1, typename A2>
-  RegionTy* getSubRegion(const A1 a1, const A2 a2,
-                         const MemRegion* superRegion);
-
-  template <typename RegionTy, typename A1, typename A2, typename A3>
-  RegionTy* getSubRegion(const A1 a1, const A2 a2, const A3 a3,
-                         const MemRegion* superRegion);
-  
   template <typename REG>
   const REG* LazyAllocate(REG*& region);
   
index 7fa7515..7619f22 100644 (file)
@@ -160,7 +160,7 @@ public:
   /// valid only if Failed flag is set to false.
   SVal attemptDownCast(SVal Base, QualType DerivedPtrType, bool &Failed);
 
-  const ElementRegion *GetElementZeroRegion(const MemRegion *R, QualType T);
+  const ElementRegion *GetElementZeroRegion(const SubRegion *R, QualType T);
 
   /// castRegion - Used by ExprEngine::VisitCast to handle casts from
   ///  a MemRegion* to a specific location type.  'R' is the region being
@@ -259,8 +259,9 @@ public:
   virtual void iterBindings(Store store, BindingsHandler& f) = 0;
 
 protected:
-  const MemRegion *MakeElementRegion(const MemRegion *baseRegion,
-                                     QualType pointeeTy, uint64_t index = 0);
+  const ElementRegion *MakeElementRegion(const SubRegion *baseRegion,
+                                         QualType pointeeTy,
+                                         uint64_t index = 0);
 
   /// CastRetrievedVal - Used by subclasses of StoreManager to implement
   ///  implicit casts that arise from loads from regions that are reinterpreted
index c667b9e..696cf39 100644 (file)
@@ -153,9 +153,9 @@ void MPIChecker::allRegionsUsedByWait(
   MemRegionManager *const RegionManager = MR->getMemRegionManager();
 
   if (FuncClassifier->isMPI_Waitall(CE.getCalleeIdentifier())) {
-    const MemRegion *SuperRegion{nullptr};
+    const SubRegion *SuperRegion{nullptr};
     if (const ElementRegion *const ER = MR->getAs<ElementRegion>()) {
-      SuperRegion = ER->getSuperRegion();
+      SuperRegion = cast<SubRegion>(ER->getSuperRegion());
     }
 
     // A single request is passed to MPI_Waitall.
index ca2e242..03e0095 100644 (file)
@@ -512,7 +512,8 @@ void ExprEngine::VisitCXXNewExpr(const CXXNewExpr *CNE, ExplodedNode *Pred,
   if (CNE->isArray()) {
     // FIXME: allocating an array requires simulating the constructors.
     // For now, just return a symbolicated region.
-    const MemRegion *NewReg = symVal.castAs<loc::MemRegionVal>().getRegion();
+    const SubRegion *NewReg =
+        symVal.castAs<loc::MemRegionVal>().getRegionAs<SubRegion>();
     QualType ObjTy = CNE->getType()->getAs<PointerType>()->getPointeeType();
     const ElementRegion *EleReg =
       getStoreManager().GetElementZeroRegion(NewReg, ObjTy);
index 83c24f6..7bc186d 100644 (file)
@@ -31,54 +31,56 @@ using namespace ento;
 // MemRegion Construction.
 //===----------------------------------------------------------------------===//
 
-template <typename RegionTy, typename A1>
-RegionTy* MemRegionManager::getSubRegion(const A1 a1,
-                                         const MemRegion *superRegion) {
+template <typename RegionTy, typename SuperTy, typename Arg1Ty>
+RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1,
+                                         const SuperTy *superRegion) {
   llvm::FoldingSetNodeID ID;
-  RegionTy::ProfileRegion(ID, a1, superRegion);
+  RegionTy::ProfileRegion(ID, arg1, superRegion);
   void *InsertPos;
   RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
                                                                    InsertPos));
 
   if (!R) {
     R = A.Allocate<RegionTy>();
-    new (R) RegionTy(a1, superRegion);
+    new (R) RegionTy(arg1, superRegion);
     Regions.InsertNode(R, InsertPos);
   }
 
   return R;
 }
 
-template <typename RegionTy, typename A1, typename A2>
-RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
-                                         const MemRegion *superRegion) {
+template <typename RegionTy, typename SuperTy, typename Arg1Ty, typename Arg2Ty>
+RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
+                                         const SuperTy *superRegion) {
   llvm::FoldingSetNodeID ID;
-  RegionTy::ProfileRegion(ID, a1, a2, superRegion);
+  RegionTy::ProfileRegion(ID, arg1, arg2, superRegion);
   void *InsertPos;
   RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
                                                                    InsertPos));
 
   if (!R) {
     R = A.Allocate<RegionTy>();
-    new (R) RegionTy(a1, a2, superRegion);
+    new (R) RegionTy(arg1, arg2, superRegion);
     Regions.InsertNode(R, InsertPos);
   }
 
   return R;
 }
 
-template <typename RegionTy, typename A1, typename A2, typename A3>
-RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
-                                         const MemRegion *superRegion) {
+template <typename RegionTy, typename SuperTy,
+          typename Arg1Ty, typename Arg2Ty, typename Arg3Ty>
+RegionTy* MemRegionManager::getSubRegion(const Arg1Ty arg1, const Arg2Ty arg2,
+                                         const Arg3Ty arg3,
+                                         const SuperTy *superRegion) {
   llvm::FoldingSetNodeID ID;
-  RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
+  RegionTy::ProfileRegion(ID, arg1, arg2, arg3, superRegion);
   void *InsertPos;
   RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
                                                                    InsertPos));
 
   if (!R) {
     R = A.Allocate<RegionTy>();
-    new (R) RegionTy(a1, a2, a3, superRegion);
+    new (R) RegionTy(arg1, arg2, arg3, superRegion);
     Regions.InsertNode(R, InsertPos);
   }
 
@@ -180,8 +182,8 @@ DefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const {
                                 svalBuilder.getArrayIndexType());
 }
 
-ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg)
-  : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
+ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const SubRegion *sReg)
+    : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {}
 
 const ObjCIvarDecl *ObjCIvarRegion::getDecl() const {
   return cast<ObjCIvarDecl>(D);
@@ -735,12 +737,14 @@ const CodeSpaceRegion *MemRegionManager::getCodeRegion() {
 // Constructing regions.
 //===----------------------------------------------------------------------===//
 const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){
-  return getSubRegion<StringRegion>(Str, getGlobalsRegion());
+  return getSubRegion<StringRegion>(
+      Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
 }
 
 const ObjCStringRegion *
 MemRegionManager::getObjCStringRegion(const ObjCStringLiteral* Str){
-  return getSubRegion<ObjCStringRegion>(Str, getGlobalsRegion());
+  return getSubRegion<ObjCStringRegion>(
+      Str, cast<GlobalInternalSpaceRegion>(getGlobalsRegion()));
 }
 
 /// Look through a chain of LocationContexts to either find the
@@ -869,7 +873,7 @@ const BlockDataRegion *
 MemRegionManager::getBlockDataRegion(const BlockCodeRegion *BC,
                                      const LocationContext *LC,
                                      unsigned blockCount) {
-  const MemRegion *sReg = nullptr;
+  const MemSpaceRegion *sReg = nullptr;
   const BlockDecl *BD = BC->getDecl();
   if (!BD->hasCaptures()) {
     // This handles 'static' blocks.
@@ -902,7 +906,7 @@ MemRegionManager::getCXXStaticTempObjectRegion(const Expr *Ex) {
 const CompoundLiteralRegion*
 MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
                                            const LocationContext *LC) {
-  const MemRegion *sReg = nullptr;
+  const MemSpaceRegion *sReg = nullptr;
 
   if (CL->isFileScope())
     sReg = getGlobalsRegion();
@@ -917,7 +921,7 @@ MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL,
 
 const ElementRegion*
 MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
-                                   const MemRegion* superRegion,
+                                   const SubRegion* superRegion,
                                    ASTContext &Ctx){
   QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
 
@@ -960,13 +964,13 @@ const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) {
 
 const FieldRegion*
 MemRegionManager::getFieldRegion(const FieldDecl *d,
-                                 const MemRegion* superRegion){
+                                 const SubRegion* superRegion){
   return getSubRegion<FieldRegion>(d, superRegion);
 }
 
 const ObjCIvarRegion*
 MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d,
-                                    const MemRegion* superRegion) {
+                                    const SubRegion* superRegion) {
   return getSubRegion<ObjCIvarRegion>(d, superRegion);
 }
 
@@ -1002,7 +1006,7 @@ static bool isValidBaseClass(const CXXRecordDecl *BaseClass,
 
 const CXXBaseObjectRegion *
 MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
-                                         const MemRegion *Super,
+                                         const SubRegion *Super,
                                          bool IsVirtual) {
   if (isa<TypedValueRegion>(Super)) {
     assert(isValidBaseClass(RD, dyn_cast<TypedValueRegion>(Super), IsVirtual));
@@ -1013,7 +1017,7 @@ MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD,
       // are different.
       while (const CXXBaseObjectRegion *Base =
                dyn_cast<CXXBaseObjectRegion>(Super)) {
-        Super = Base->getSuperRegion();
+        Super = cast<SubRegion>(Base->getSuperRegion());
       }
       assert(Super && !isa<MemSpaceRegion>(Super));
     }
index f0c2df4..dd7e9dd 100644 (file)
@@ -1341,7 +1341,8 @@ SVal RegionStoreManager::ArrayToPointer(Loc Array, QualType T) {
   if (!Array.getAs<loc::MemRegionVal>())
     return UnknownVal();
 
-  const MemRegion* R = Array.castAs<loc::MemRegionVal>().getRegion();
+  const SubRegion *R =
+      cast<SubRegion>(Array.castAs<loc::MemRegionVal>().getRegion());
   NonLoc ZeroIdx = svalBuilder.makeZeroArrayIndex();
   return loc::MemRegionVal(MRMgr.getElementRegion(T, ZeroIdx, R, Ctx));
 }
@@ -1384,7 +1385,7 @@ SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T)
         T = SR->getSymbol()->getType();
       }
     }
-    MR = GetElementZeroRegion(MR, T);
+    MR = GetElementZeroRegion(cast<SubRegion>(MR), T);
   }
 
   // FIXME: Perhaps this method should just take a 'const MemRegion*' argument
index 77de0c3..82ce8b4 100644 (file)
@@ -950,7 +950,7 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
   if (const MemRegion *region = lhs.getAsRegion()) {
     rhs = convertToArrayIndex(rhs).castAs<NonLoc>();
     SVal index = UnknownVal();
-    const MemRegion *superR = nullptr;
+    const SubRegion *superR = nullptr;
     // We need to know the type of the pointer in order to add an integer to it.
     // Depending on the type, different amount of bytes is added.
     QualType elementType;
@@ -959,13 +959,13 @@ SVal SimpleSValBuilder::evalBinOpLN(ProgramStateRef state,
       assert(op == BO_Add || op == BO_Sub);
       index = evalBinOpNN(state, op, elemReg->getIndex(), rhs,
                           getArrayIndexType());
-      superR = elemReg->getSuperRegion();
+      superR = cast<SubRegion>(elemReg->getSuperRegion());
       elementType = elemReg->getElementType();
     }
     else if (isa<SubRegion>(region)) {
       assert(op == BO_Add || op == BO_Sub);
       index = (op == BO_Add) ? rhs : evalMinus(rhs);
-      superR = region;
+      superR = cast<SubRegion>(region);
       // TODO: Is this actually reliable? Maybe improving our MemRegion
       // hierarchy to provide typed regions for all non-void pointers would be
       // better. For instance, we cannot extend this towards LocAsInteger
index aca6e3b..ba48a60 100644 (file)
@@ -42,8 +42,9 @@ StoreRef StoreManager::enterStackFrame(Store OldStore,
   return Store;
 }
 
-const MemRegion *StoreManager::MakeElementRegion(const MemRegion *Base,
-                                              QualType EleTy, uint64_t index) {
+const ElementRegion *StoreManager::MakeElementRegion(const SubRegion *Base,
+                                                     QualType EleTy,
+                                                     uint64_t index) {
   NonLoc idx = svalBuilder.makeArrayIndex(index);
   return MRMgr.getElementRegion(EleTy, idx, Base, svalBuilder.getContext());
 }
@@ -52,7 +53,7 @@ StoreRef StoreManager::BindDefault(Store store, const MemRegion *R, SVal V) {
   return StoreRef(store, *this);
 }
 
-const ElementRegion *StoreManager::GetElementZeroRegion(const MemRegion *R,
+const ElementRegion *StoreManager::GetElementZeroRegion(const SubRegion *R,
                                                         QualType T) {
   NonLoc idx = svalBuilder.makeZeroArrayIndex();
   assert(!T.isNull());
@@ -126,7 +127,7 @@ const MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy)
     case MemRegion::VarRegionKind:
     case MemRegion::CXXTempObjectRegionKind:
     case MemRegion::CXXBaseObjectRegionKind:
-      return MakeElementRegion(R, PointeeTy);
+      return MakeElementRegion(cast<SubRegion>(R), PointeeTy);
 
     case MemRegion::ElementRegionKind: {
       // If we are casting from an ElementRegion to another type, the
@@ -171,7 +172,7 @@ const MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy)
         }
 
         // Otherwise, create a new ElementRegion at offset 0.
-        return MakeElementRegion(baseR, PointeeTy);
+        return MakeElementRegion(cast<SubRegion>(baseR), PointeeTy);
       }
 
       // We have a non-zero offset from the base region.  We want to determine
@@ -202,10 +203,11 @@ const MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy)
       if (!newSuperR) {
         // Create an intermediate ElementRegion to represent the raw byte.
         // This will be the super region of the final ElementRegion.
-        newSuperR = MakeElementRegion(baseR, Ctx.CharTy, off.getQuantity());
+        newSuperR = MakeElementRegion(cast<SubRegion>(baseR), Ctx.CharTy,
+                                      off.getQuantity());
       }
 
-      return MakeElementRegion(newSuperR, PointeeTy, newIndex);
+      return MakeElementRegion(cast<SubRegion>(newSuperR), PointeeTy, newIndex);
     }
   }
 
@@ -271,9 +273,8 @@ SVal StoreManager::evalDerivedToBase(SVal Derived, QualType BaseType,
     BaseDecl = BaseType->getAsCXXRecordDecl();
   assert(BaseDecl && "not a C++ object?");
 
-  const MemRegion *BaseReg =
-    MRMgr.getCXXBaseObjectRegion(BaseDecl, DerivedRegVal->getRegion(),
-                                 IsVirtual);
+  const MemRegion *BaseReg = MRMgr.getCXXBaseObjectRegion(
+      BaseDecl, cast<SubRegion>(DerivedRegVal->getRegion()), IsVirtual);
 
   return loc::MemRegionVal(BaseReg);
 }
@@ -390,11 +391,11 @@ SVal StoreManager::getLValueFieldOrIvar(const Decl *D, SVal Base) {
     return Base;
 
   Loc BaseL = Base.castAs<Loc>();
-  const MemRegion* BaseR = nullptr;
+  const SubRegion* BaseR = nullptr;
 
   switch (BaseL.getSubKind()) {
   case loc::MemRegionValKind:
-    BaseR = BaseL.castAs<loc::MemRegionVal>().getRegion();
+    BaseR = cast<SubRegion>(BaseL.castAs<loc::MemRegionVal>().getRegion());
     break;
 
   case loc::GotoLabelKind:
@@ -434,7 +435,8 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
   if (Base.isUnknownOrUndef() || Base.getAs<loc::ConcreteInt>())
     return Base;
 
-  const MemRegion* BaseRegion = Base.castAs<loc::MemRegionVal>().getRegion();
+  const SubRegion *BaseRegion =
+      Base.castAs<loc::MemRegionVal>().getRegionAs<SubRegion>();
 
   // Pointer of any type can be cast and used as array base.
   const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion);
@@ -471,9 +473,8 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
     if (isa<ElementRegion>(BaseRegion->StripCasts()))
       return UnknownVal();
 
-    return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
-                                                    ElemR->getSuperRegion(),
-                                                    Ctx));
+    return loc::MemRegionVal(MRMgr.getElementRegion(
+        elementType, Offset, cast<SubRegion>(ElemR->getSuperRegion()), Ctx));
   }
 
   const llvm::APSInt& OffI = Offset.castAs<nonloc::ConcreteInt>().getValue();
@@ -484,7 +485,7 @@ SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
                                                                     OffI));
 
   // Construct the new ElementRegion.
-  const MemRegion *ArrayR = ElemR->getSuperRegion();
+  const SubRegion *ArrayR = cast<SubRegion>(ElemR->getSuperRegion());
   return loc::MemRegionVal(MRMgr.getElementRegion(elementType, NewIdx, ArrayR,
                                                   Ctx));
 }