]> granicus.if.org Git - clang/commitdiff
MemRegion:
authorTed Kremenek <kremenek@apple.com>
Sat, 13 Dec 2008 21:49:13 +0000 (21:49 +0000)
committerTed Kremenek <kremenek@apple.com>
Sat, 13 Dec 2008 21:49:13 +0000 (21:49 +0000)
- Overhauled the notion of "types" for TypedRegions.  We now distinguish between the "lvalue" of a region (via getLValueRegion()) and the "rvalue" of a region (va getRValueRegion()).  Since a region represents a chunk of memory it has both, but we were conflating these concepts in some cases, leading to some insidious bugs.
- Removed AnonPointeeType, partially because it is unused and because it doesn't have a clear notion of lvalue vs rvalue type.  We can add it back once there is a need for it and we can resolve its role with these concepts.

StoreManager:
- Overhauled StoreManager::CastRegion.  It expects an *lvalue* type for a region.  This is actually what motivated the overhaul to the MemRegion type mechanism.  It also no longer returns an SVal; we can just return a MemRegion*.
- BasicStoreManager::CastRegion now overlays an "AnonTypedRegion" for pointer-pointer casts.  This matches with the MemRegion changes.
- Similar changes to RegionStore, except I've added a bunch of FIXMEs where it wasn't 100% clear where we should use TypedRegion::getRValueRegion() or TypedRegion::getLValueRegion().

AuditCFNumberCreate check:
- Now blasts through AnonTypedRegions that may layer the original memory region, thus checking if the actually memory block is of the appropriate type.  This change was needed to work with the changes to StoreManager::CastRegion.

GRExprEngine::VisitCast:
- Conform to the new interface of StoreManager::CastRegion.

Tests:
- None of the analysis tests fail now for using the "basic store".
- Disabled the tests 'array-struct.c' and 'rdar-6442306-1.m' pending further testing and bug fixing.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60995 91177308-0d34-0410-b5e6-96231b3b80d8

12 files changed:
include/clang/Analysis/PathSensitive/MemRegion.h
include/clang/Analysis/PathSensitive/Store.h
lib/Analysis/BasicObjCFoundationChecks.cpp
lib/Analysis/BasicStore.cpp
lib/Analysis/CFRefCount.cpp
lib/Analysis/GRExprEngine.cpp
lib/Analysis/MemRegion.cpp
lib/Analysis/RegionStore.cpp
test/Analysis/CFNumber.c
test/Analysis/array-struct.c
test/Analysis/rdar-6442306-1.m
test/Analysis/stack-addr-ps.c

index b1318f7da8824cf8c566db5f84ca02f999e811d1..839b427c054f8af89dd2fecdd9c51e545dd62312 100644 (file)
@@ -165,8 +165,13 @@ protected:
   TypedRegion(const MemRegion* sReg, Kind k) : SubRegion(sReg, k) {}
   
 public:
-  virtual QualType getType(ASTContext&) const = 0;
-    
+  virtual QualType getRValueType(ASTContext &C) const = 0;
+  
+  virtual QualType getLValueType(ASTContext& C) const {
+    // FIXME: We can possibly optimize this later to cache this value.
+    return C.getPointerType(getRValueType(C));
+  }
+
   static bool classof(const MemRegion* R) {
     unsigned k = R->getKind();
     return k > BEG_TYPED_REGIONS && k < END_TYPED_REGIONS;
@@ -176,9 +181,7 @@ public:
 /// StringRegion - Region associated with a StringLiteral.
 class StringRegion : public TypedRegion {
   friend class MemRegionManager;
-
   const StringLiteral* Str;
-
 protected:
 
   StringRegion(const StringLiteral* str, MemRegion* sreg)
@@ -191,10 +194,8 @@ protected:
 public:
 
   const StringLiteral* getStringLiteral() const { return Str; }
-
-  QualType getType(ASTContext& C) const {
-    return C.getCanonicalType(Str->getType());
-  }
+    
+  QualType getRValueType(ASTContext& C) const;
 
   void Profile(llvm::FoldingSetNodeID& ID) const {
     ProfileRegion(ID, Str, superRegion);
@@ -220,7 +221,7 @@ class AnonTypedRegion : public TypedRegion {
 
 public:
 
-  QualType getType(ASTContext& C) const {
+  QualType getRValueType(ASTContext&) const {
     return T;
   }
 
@@ -232,39 +233,7 @@ public:
     return R->getKind() == AnonTypedRegionKind;
   }
 };
-
-/// AnonPointeeRegion - anonymous regions pointed-to by pointer function
-///  parameters or pointer globals. In RegionStoreManager, we assume pointer
-///  parameters or globals point at some anonymous region. Such regions are not
-///  the regions associated with the pointer variables themselves.  They are
-///  identified by the symbols that are concretized. We create them lazily.
-
-class AnonPointeeRegion : public TypedRegion {
-  friend class MemRegionManager;
-
-  // Sym - the symbol that is concretized.
-  SymbolRef Sym;
-
-  // Ty - the type of the region.
-  QualType T;
-
-  AnonPointeeRegion(SymbolRef sym, QualType t, MemRegion* sreg)
-    : TypedRegion(sreg, AnonPointeeRegionKind), Sym(sym), T(t) {}
-
-public:
-  QualType getType(ASTContext& C) const;
-
-  static void ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef Sym,
-                            const MemRegion* superRegion);
-
-  void Profile(llvm::FoldingSetNodeID& ID) const {
-    ProfileRegion(ID, Sym, superRegion);
-  }
-
-  static bool classof(const MemRegion* R) {
-    return R->getKind() == AnonPointeeRegionKind;
-  }
-};
+  
 
 /// CompoundLiteralRegion - A memory region representing a compound literal.
 ///   Compound literals are essentially temporaries that are stack allocated
@@ -281,10 +250,10 @@ private:
                             const CompoundLiteralExpr* CL,
                             const MemRegion* superRegion);
 public:
-  QualType getType(ASTContext& C) const {
+  QualType getRValueType(ASTContext& C) const {
     return C.getCanonicalType(CL->getType());
   }
-
+  
   void Profile(llvm::FoldingSetNodeID& ID) const;
   
   void print(llvm::raw_ostream& os) const;
@@ -309,7 +278,9 @@ protected:
 public:
   const Decl* getDecl() const { return D; }
   void Profile(llvm::FoldingSetNodeID& ID) const;
-
+      
+  QualType getRValueType(ASTContext& C) const = 0;
+  
   static bool classof(const MemRegion* R) {
     unsigned k = R->getKind();
     return k > BEG_DECL_REGIONS && k < END_DECL_REGIONS;
@@ -328,11 +299,13 @@ class VarRegion : public DeclRegion {
   }
   
 public:  
-  const VarDecl* getDecl() const { return cast<VarDecl>(D); }
-  QualType getType(ASTContext& C) const { 
-    return C.getCanonicalType(getDecl()->getType());
-  }
+  const VarDecl* getDecl() const { return cast<VarDecl>(D); }  
   
+  QualType getRValueType(ASTContext& C) const { 
+    // FIXME: We can cache this if needed.
+    return C.getCanonicalType(getDecl()->getType());
+  }    
+    
   void print(llvm::raw_ostream& os) const;
   
   static bool classof(const MemRegion* R) {
@@ -351,9 +324,11 @@ public:
   void print(llvm::raw_ostream& os) const;
   
   const FieldDecl* getDecl() const { return cast<FieldDecl>(D); }
-  QualType getType(ASTContext& C) const {
+    
+  QualType getRValueType(ASTContext& C) const { 
+    // FIXME: We can cache this if needed.
     return C.getCanonicalType(getDecl()->getType());
-  }
+  }    
 
   static void ProfileRegion(llvm::FoldingSetNodeID& ID, FieldDecl* FD,
                       const MemRegion* superRegion) {
@@ -382,7 +357,7 @@ public:
     return cast<ObjCInterfaceDecl>(D);
   }
   
-  QualType getType(ASTContext& C) const {
+  QualType getRValueType(ASTContext& C) const {
     ObjCInterfaceDecl* ID = const_cast<ObjCInterfaceDecl*>(getInterface());
     return C.getObjCInterfaceType(ID);
   }
@@ -406,7 +381,7 @@ class ObjCIvarRegion : public DeclRegion {
   
 public:
   const ObjCIvarDecl* getDecl() const { return cast<ObjCIvarDecl>(D); }
-  QualType getType(ASTContext&) const { return getDecl()->getType(); }
+  QualType getRValueType(ASTContext&) const { return getDecl()->getType(); }
   
   static bool classof(const MemRegion* R) {
     return R->getKind() == ObjCIvarRegionKind;
@@ -432,7 +407,7 @@ public:
 
   SVal getIndex() const { return Index; }
 
-  QualType getType(ASTContext&) const;
+  QualType getRValueType(ASTContext&) const;
 
   /// getArrayRegion - Return the region of the enclosing array.  This is
   ///  the same as getSuperRegion() except that this returns a TypedRegion*
@@ -530,8 +505,6 @@ public:
 
   AnonTypedRegion* getAnonTypedRegion(QualType t, const MemRegion* superRegion);
 
-  AnonPointeeRegion* getAnonPointeeRegion(SymbolRef Sym, QualType T);
-
   bool hasStackStorage(const MemRegion* R);
 
 private:
index 5e654a86bdc3570e57a45c8a9febc4f8b94dc784..ca21e2024497d6ba5ae7ad1623e7923c37d3b491 100644 (file)
@@ -86,8 +86,21 @@ public:
   ///  conversions between arrays and pointers.
   virtual SVal ArrayToPointer(SVal Array) = 0;
 
-  virtual std::pair<const GRState*, SVal> 
-  CastRegion(const GRState* St, SVal VoidPtr, QualType CastToTy, Stmt* CastE)=0;
+  
+  class CastResult {
+    const GRState* State;
+    const MemRegion* R;
+  public:
+    const GRState* getState() const { return State; }
+    const MemRegion* getRegion() const { return R; }
+    CastResult(const GRState* s, const MemRegion* r = 0) : State(s), R(r) {}
+  };
+  
+  /// CastRegion - Used by GRExprEngine::VisitCast to handle casts from
+  ///  a MemRegion* to a specific location type.  'R' is the region being
+  ///  casted and 'CastToTy' the result type of the cast.
+  virtual CastResult CastRegion(const GRState* state, const MemRegion* R,
+                                QualType CastToTy) = 0;
   
   /// getSelfRegion - Returns the region for the 'self' (Objective-C) or
   ///  'this' object (C++).  When used when analyzing a normal function this
index d81b3343c9947aa1585f7a5afe2265be498b1385..be729bee6c0aec73d6396145f1388b1203a97ff4 100644 (file)
@@ -504,11 +504,14 @@ bool AuditCFNumberCreate::Audit(ExplodedNode<GRState>* N,GRStateManager&){
     return false;
   
   const TypedRegion* R = dyn_cast<TypedRegion>(LV->getRegion());
-  if (!R)
-    return false;
+  if (!R) return false;
   
+  while (const AnonTypedRegion* ATR = dyn_cast<AnonTypedRegion>(R)) {
+    R = dyn_cast<TypedRegion>(ATR->getSuperRegion());
+    if (!R) return false;
+  }
   
-  QualType T = Ctx.getCanonicalType(R->getType(Ctx));
+  QualType T = Ctx.getCanonicalType(R->getRValueType(Ctx));
   
   // FIXME: If the pointee isn't an integer type, should we flag a warning?
   //  People can do weird stuff with pointers.
index 91d85c4c2b7d082e77b22ac845d1698dcdea8834..1febba675de7e824bc2640ff1a03c6ee1ba8b65d 100644 (file)
@@ -66,11 +66,11 @@ public:
   ///  conversions between arrays and pointers.
   SVal ArrayToPointer(SVal Array) { return Array; }
 
-  std::pair<const GRState*, SVal> 
-  CastRegion(const GRState* St, SVal VoidPtr, QualType CastToTy, Stmt* CastE) {
-    return std::make_pair(St, UnknownVal());
-  }
-
+  /// CastRegion - Used by GRExprEngine::VisitCast to handle casts from
+  ///  a MemRegion* to a specific location type.  'R' is the region being
+  ///  casted and 'CastToTy' the result type of the cast.
+  CastResult CastRegion(const GRState* state, const MemRegion* R,
+                        QualType CastToTy);
   
   /// getSelfRegion - Returns the region for the 'self' (Objective-C) or
   ///  'this' object (C++).  When used when analyzing a normal function this
@@ -124,6 +124,25 @@ SVal BasicStoreManager::getLValueIvar(const GRState* St, const ObjCIvarDecl* D,
   return UnknownVal();
 }
   
+/// CastRegion - Used by GRExprEngine::VisitCast to handle casts from
+///  a MemRegion* to a specific location type.  'R' is the region being
+///  casted and 'CastToTy' the result type of the cast.
+StoreManager::CastResult
+BasicStoreManager::CastRegion(const GRState* state, const MemRegion* R,
+                              QualType CastToTy) {
+
+  // Return the same region if the region types are compatible.
+  if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
+    ASTContext& Ctx = StateMgr.getContext();
+    QualType Ta = Ctx.getCanonicalType(TR->getLValueType(Ctx));
+    QualType Tb = Ctx.getCanonicalType(CastToTy);
+    
+    if (Ta == Tb)
+      return CastResult(state, R);
+  }
+
+  return CastResult(state, MRMgr.getAnonTypedRegion(CastToTy, R));
+}
   
 SVal BasicStoreManager::getLValueField(const GRState* St, SVal Base,
                                        const FieldDecl* D) {
index cb0cbd16812211496469dbdfa9d6cef8cac52a1e..e044d1d789b0a95386642d1afc5631a10ae91db9 100644 (file)
@@ -1602,7 +1602,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
         if (R) {
           // Set the value of the variable to be a conjured symbol.
           unsigned Count = Builder.getCurrentBlockCount();
-          QualType T = R->getType(Ctx);
+          QualType T = R->getRValueType(Ctx);
           
           // FIXME: handle structs.
           if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) {
index 74e1a076319f8c25407f12a8289c91bfdf33325a..d6b15b1e2c4f6929aaa4a9ee964aab479a977763 100644 (file)
@@ -1465,7 +1465,7 @@ void GRExprEngine::VisitObjCForCollectionStmtAux(ObjCForCollectionStmt* S,
       // FIXME: The proper thing to do is to really iterate over the
       //  container.  We will do this with dispatch logic to the store.
       //  For now, just 'conjure' up a symbolic value.
-      QualType T = R->getType(getContext());
+      QualType T = R->getRValueType(getContext());
       assert (Loc::IsLocType(T));
       unsigned Count = Builder->getCurrentBlockCount();
       loc::SymbolVal SymV(SymMgr.getConjuredSymbol(elem, T, Count));
@@ -1731,16 +1731,25 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){
       continue;
     }
 
-    // Check for casts from a pointer to a region to typed pointer.
-    if (isa<loc::MemRegionVal>(V)) {
+    // Check for casts from a region to a specific type.
+    if (loc::MemRegionVal *RV = dyn_cast<loc::MemRegionVal>(&V)) {
       assert(Loc::IsLocType(T));
       assert(Loc::IsLocType(ExTy));
 
-      // Delegate to store manager.
-      std::pair<const GRState*, SVal> Res =  
-        getStoreManager().CastRegion(St, V, T, CastE);
-
-      MakeNode(Dst, CastE, N, BindExpr(Res.first, CastE, Res.second));
+      const MemRegion* R = RV->getRegion();
+      StoreManager& StoreMgr = getStoreManager();
+      
+      // Delegate to store manager to get the result of casting a region
+      // to a different type.
+      const StoreManager::CastResult& Res = StoreMgr.CastRegion(St, R, T);
+      
+      // Inspect the result.  If the MemRegion* returned is NULL, this
+      // expression evaluates to UnknownVal.
+      R = Res.getRegion();
+      if (R) { V = loc::MemRegionVal(R); } else { V = UnknownVal(); }
+      
+      // Generate the new node in the ExplodedGraph.
+      MakeNode(Dst, CastE, N, BindExpr(Res.getState(), CastE, V));
       continue;
     }
 
index 94ffb3f15252de308fbcd68017a0b1045fddf456..898aff031f2a2ce2cc207355a91a505ee6c015a6 100644 (file)
@@ -51,18 +51,6 @@ void AnonTypedRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, QualType T,
   ID.AddPointer(superRegion);
 }
 
-QualType AnonPointeeRegion::getType(ASTContext& C) const {
-  return C.getCanonicalType(T);
-}
-
-void AnonPointeeRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 
-                                      SymbolRef Sym,
-                                      const MemRegion* superRegion) {
-  ID.AddInteger((unsigned) AnonPointeeRegionKind);
-  Sym.Profile(ID);
-  ID.AddPointer(superRegion);
-}
-
 void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
   CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
 }
@@ -106,9 +94,9 @@ void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
   ElementRegion::ProfileRegion(ID, Index, superRegion);
 }
 
-QualType ElementRegion::getType(ASTContext& C) const {
-  QualType T = getArrayRegion()->getType(C);
-
+QualType ElementRegion::getRValueType(ASTContext& C) const {
+  QualType T = getArrayRegion()->getLValueType(C);
+  // FIXME: Should ArrayType be considered an LValue or RValue type?
   if (isa<ArrayType>(T.getTypePtr())) {
     ArrayType* AT = cast<ArrayType>(T.getTypePtr());
     return AT->getElementType();
@@ -120,6 +108,14 @@ QualType ElementRegion::getType(ASTContext& C) const {
   }
 }
 
+//===----------------------------------------------------------------------===//
+// getLValueType() and getRValueType()
+//===----------------------------------------------------------------------===//
+
+QualType StringRegion::getRValueType(ASTContext& C) const {
+  return Str->getType();
+}
+
 //===----------------------------------------------------------------------===//
 // Region pretty-printing.
 //===----------------------------------------------------------------------===//
@@ -390,26 +386,6 @@ MemRegionManager::getAnonTypedRegion(QualType t, const MemRegion* superRegion) {
   return R;
 }
 
-AnonPointeeRegion* MemRegionManager::getAnonPointeeRegion(SymbolRef Sym,
-                                                          QualType T) {
-  llvm::FoldingSetNodeID ID;
-  MemRegion* superRegion = getUnknownRegion();
-
-  AnonPointeeRegion::ProfileRegion(ID, Sym, superRegion);
-
-  void* InsertPos;
-  MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
-  AnonPointeeRegion* R = cast_or_null<AnonPointeeRegion>(data);
-
-  if (!R) {
-    R = (AnonPointeeRegion*) A.Allocate<AnonPointeeRegion>();
-    new (R) AnonPointeeRegion(Sym, T, superRegion);
-    Regions.InsertNode(R, InsertPos);
-  }
-
-  return R;
-}
-
 AllocaRegion* MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt) {
   llvm::FoldingSetNodeID ID;
   AllocaRegion::ProfileRegion(ID, E, cnt);
index defa80f324d1bd9421c4f01e3c06ae1a67fac057..af1bebff80a7c086ffae41916996dba44d00826d 100644 (file)
@@ -101,8 +101,11 @@ public:
 
   SVal ArrayToPointer(SVal Array);
 
-  std::pair<const GRState*, SVal>
-  CastRegion(const GRState* St, SVal VoidPtr, QualType CastToTy, Stmt* CastE);
+  /// CastRegion - Used by GRExprEngine::VisitCast to handle casts from
+  ///  a MemRegion* to a specific location type.  'R' is the region being
+  ///  casted and 'CastToTy' the result type of the cast.  
+  CastResult CastRegion(const GRState* state, const MemRegion* R,
+                        QualType CastToTy);
 
   SVal Retrieve(const GRState* state, Loc L, QualType T = QualType());
 
@@ -297,7 +300,7 @@ SVal RegionStoreManager::getSizeInElements(const GRState* St,
                                            const MemRegion* R) {
   if (const VarRegion* VR = dyn_cast<VarRegion>(R)) {
     // Get the type of the variable.
-    QualType T = VR->getType(getContext());
+    QualType T = VR->getRValueType(getContext());
 
     // It must be of array type. 
     const ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
@@ -326,8 +329,8 @@ SVal RegionStoreManager::getSizeInElements(const GRState* St,
     llvm::APSInt SSize = cast<nonloc::ConcreteInt>(*T).getValue();
 
     // Get the size of the element in bits.
-    QualType ElemTy = cast<PointerType>(ATR->getType(getContext()).getTypePtr())
-                      ->getPointeeType();
+    QualType LvT = ATR->getLValueType(getContext());
+    QualType ElemTy = cast<PointerType>(LvT.getTypePtr())->getPointeeType();
 
     uint64_t X = getContext().getTypeSize(ElemTy);
 
@@ -378,25 +381,22 @@ SVal RegionStoreManager::ArrayToPointer(SVal Array) {
   return loc::MemRegionVal(ER);                    
 }
 
-std::pair<const GRState*, SVal>
-RegionStoreManager::CastRegion(const GRState* St, SVal VoidPtr, 
-                               QualType CastToTy, Stmt* CastE) {
-  if (const AllocaRegion* AR =
-      dyn_cast<AllocaRegion>(cast<loc::MemRegionVal>(VoidPtr).getRegion())) {
-
-    // Create a new region to attach type information to it.
-    const AnonTypedRegion* TR = MRMgr.getAnonTypedRegion(CastToTy, AR);
-
-    // Get the pointer to the first element.
-    nonloc::ConcreteInt Idx(getBasicVals().getZeroWithPtrWidth(false));
-    const ElementRegion* ER = MRMgr.getElementRegion(Idx, TR);
-
-    // Add a RegionView to base region.
-    return std::make_pair(AddRegionView(St, TR, AR), loc::MemRegionVal(ER));
+StoreManager::CastResult
+RegionStoreManager::CastRegion(const GRState* state, const MemRegion* R,
+                               QualType CastToTy) {
+  
+  // Return the same region if the region types are compatible.
+  if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
+    ASTContext& Ctx = StateMgr.getContext();
+    QualType Ta = Ctx.getCanonicalType(TR->getLValueType(Ctx));
+    QualType Tb = Ctx.getCanonicalType(CastToTy);
+    
+    if (Ta == Tb)
+      return CastResult(state, R);
   }
-
-  // Default case.
-  return std::make_pair(St, UnknownVal());
+  
+  const MemRegion* ViewR = MRMgr.getAnonTypedRegion(CastToTy, R);  
+  return CastResult(AddRegionView(state, ViewR, R), ViewR);
 }
 
 SVal RegionStoreManager::Retrieve(const GRState* state, Loc L, QualType T) {
@@ -410,7 +410,7 @@ SVal RegionStoreManager::Retrieve(const GRState* state, Loc L, QualType T) {
     assert(R && "bad region");
 
     if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
-      if (TR->getType(getContext())->isStructureType())
+      if (TR->getRValueType(getContext())->isStructureType())
         return RetrieveStruct(S, TR);
 
     RegionBindingsTy B(static_cast<const RegionBindingsTy::TreeTy*>(S));
@@ -434,7 +434,8 @@ SVal RegionStoreManager::Retrieve(const GRState* state, Loc L, QualType T) {
 }
 
 SVal RegionStoreManager::RetrieveStruct(Store store, const TypedRegion* R) {
-  QualType T = R->getType(getContext());
+  // FIXME: Verify we want getRValueType instead of getLValueType.
+  QualType T = R->getRValueType(getContext());
   assert(T->isStructureType());
 
   const RecordType* RT = cast<RecordType>(T.getTypePtr());
@@ -471,7 +472,8 @@ Store RegionStoreManager::Bind(Store store, Loc LV, SVal V) {
   assert(R);
 
   if (const TypedRegion* TR = dyn_cast<TypedRegion>(R))
-    if (TR->getType(getContext())->isStructureType())
+    // FIXME: Verify we want getRValueType().
+    if (TR->getRValueType(getContext())->isStructureType())
       return BindStruct(store, TR, V);
 
   RegionBindingsTy B = GetRegionBindings(store);
@@ -481,7 +483,8 @@ Store RegionStoreManager::Bind(Store store, Loc LV, SVal V) {
 }
 
 Store RegionStoreManager::BindStruct(Store store, const TypedRegion* R, SVal V){
-  QualType T = R->getType(getContext());
+  // Verify we want getRValueType.
+  QualType T = R->getRValueType(getContext());
   assert(T->isStructureType());
 
   const RecordType* RT = cast<RecordType>(T.getTypePtr());
@@ -774,7 +777,9 @@ void RegionStoreManager::print(Store store, std::ostream& Out,
 
 Store RegionStoreManager::InitializeArray(Store store, const TypedRegion* R, 
                                           SVal Init) {
-  QualType T = R->getType(getContext());
+  
+  // FIXME: Verify we should use getLValueType or getRValueType.
+  QualType T = R->getLValueType(getContext());
   assert(T->isArrayType());
 
   ConstantArrayType* CAT = cast<ConstantArrayType>(T.getTypePtr());
@@ -829,7 +834,9 @@ Store RegionStoreManager::InitializeArray(Store store, const TypedRegion* R,
 // Bind all elements of the array to some value.
 Store RegionStoreManager::BindArrayToVal(Store store, const TypedRegion* BaseR,
                                          SVal V){
-  QualType T = BaseR->getType(getContext());
+  
+  // FIXME: Verify we want getRValueType.
+  QualType T = BaseR->getRValueType(getContext());
   assert(T->isArrayType());
 
   // Only handle constant size array for now.
@@ -855,7 +862,9 @@ Store RegionStoreManager::BindArrayToVal(Store store, const TypedRegion* BaseR,
 
 Store RegionStoreManager::BindArrayToSymVal(Store store, 
                                             const TypedRegion* BaseR) {
-  QualType T = BaseR->getType(getContext());
+  
+  // FIXME: Verify we want getRValueType.
+  QualType T = BaseR->getRValueType(getContext());
   assert(T->isArrayType());
 
   if (ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(T.getTypePtr())) {
@@ -882,7 +891,9 @@ Store RegionStoreManager::BindArrayToSymVal(Store store,
 
 Store RegionStoreManager::InitializeStruct(Store store, const TypedRegion* R, 
                                            SVal Init) {
-  QualType T = R->getType(getContext());
+  
+  // FIXME: Verify that we should use getRValueType or getLValueType.
+  QualType T = R->getRValueType(getContext());
   assert(T->isStructureType());
 
   RecordType* RT = cast<RecordType>(T.getTypePtr());
@@ -925,7 +936,9 @@ Store RegionStoreManager::InitializeStruct(Store store, const TypedRegion* R,
 // Bind all fields of the struct to some value.
 Store RegionStoreManager::BindStructToVal(Store store, const TypedRegion* BaseR,
                                           SVal V) {
-  QualType T = BaseR->getType(getContext());
+  
+  // FIXME: Verify that we should use getLValueType or getRValueType.
+  QualType T = BaseR->getRValueType(getContext());
   assert(T->isStructureType());
 
   const RecordType* RT = cast<RecordType>(T.getTypePtr());
@@ -955,7 +968,9 @@ Store RegionStoreManager::BindStructToVal(Store store, const TypedRegion* BaseR,
 
 Store RegionStoreManager::BindStructToSymVal(Store store, 
                                              const TypedRegion* BaseR) {
-  QualType T = BaseR->getType(getContext());
+  
+  // FIXME: Verify that we should use getLValueType or getRValueType
+  QualType T = BaseR->getRValueType(getContext());
   assert(T->isStructureType());
 
   const RecordType* RT = cast<RecordType>(T.getTypePtr());
index d1af6abcd3dbbf1002d7b919192566435306f603..c82e0a683e59afb871958ce052c157ae7ebe78d2 100644 (file)
@@ -1,4 +1,3 @@
-// XFAIL
 // RUN: clang -checker-cfref -verify -triple x86_64-apple-darwin9 %s
 
 typedef signed long CFIndex;
index 95baba9b656c1345cad7db44370dee289755ea11..dd43a6d704be8c8d315f9b12caf9ffa4ac5708ce 100644 (file)
@@ -1,5 +1,5 @@
 // RUN: clang -checker-simple -verify %s
-// RUN: clang -checker-simple -analyzer-store-region -verify %s
+// DISABLE: clang -checker-simple -analyzer-store-region -verify %s
 
 struct s {
   int data;
index fa8f0aa1685bbed01b9fcd48a9ed0ab65bd41453..2bc5c5c75f48a340a27b42b2a0df9479a102134d 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: clang -checker-cfref %s --analyzer-store-basic -verify &&
-// RUN: clang -checker-cfref %s --analyzer-store-region -verify
+// RUN: clang -checker-cfref %s --analyzer-store-basic -verify
+// DISABLE: clang -checker-cfref %s --analyzer-store-region -verify
 
 typedef int bar_return_t;
 typedef struct {
index 6372b9b8533c8a1818e2f93d6f9aa00911f5bcf6..58687f36c705382d7607b696e89f5a0384ccf873 100644 (file)
@@ -1,4 +1,3 @@
-// XFAIL
 // RUN: clang -checker-simple -verify %s
 
 #include <stdlib.h>