diff options
-rw-r--r-- | include/clang/Analysis/PathSensitive/MemRegion.h | 85 | ||||
-rw-r--r-- | include/clang/Analysis/PathSensitive/Store.h | 17 | ||||
-rw-r--r-- | lib/Analysis/BasicObjCFoundationChecks.cpp | 9 | ||||
-rw-r--r-- | lib/Analysis/BasicStore.cpp | 29 | ||||
-rw-r--r-- | lib/Analysis/CFRefCount.cpp | 2 | ||||
-rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 25 | ||||
-rw-r--r-- | lib/Analysis/MemRegion.cpp | 46 | ||||
-rw-r--r-- | lib/Analysis/RegionStore.cpp | 81 | ||||
-rw-r--r-- | test/Analysis/CFNumber.c | 1 | ||||
-rw-r--r-- | test/Analysis/array-struct.c | 2 | ||||
-rw-r--r-- | test/Analysis/rdar-6442306-1.m | 4 | ||||
-rw-r--r-- | test/Analysis/stack-addr-ps.c | 1 |
12 files changed, 154 insertions, 148 deletions
diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h index b1318f7da8..839b427c05 100644 --- a/include/clang/Analysis/PathSensitive/MemRegion.h +++ b/include/clang/Analysis/PathSensitive/MemRegion.h @@ -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: diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index 5e654a86bd..ca21e20244 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -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 diff --git a/lib/Analysis/BasicObjCFoundationChecks.cpp b/lib/Analysis/BasicObjCFoundationChecks.cpp index d81b3343c9..be729bee6c 100644 --- a/lib/Analysis/BasicObjCFoundationChecks.cpp +++ b/lib/Analysis/BasicObjCFoundationChecks.cpp @@ -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. diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index 91d85c4c2b..1febba675d 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -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) { diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index cb0cbd1681..e044d1d789 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -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())) { diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 74e1a07631..d6b15b1e2c 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -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; } diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp index 94ffb3f152..898aff031f 100644 --- a/lib/Analysis/MemRegion.cpp +++ b/lib/Analysis/MemRegion.cpp @@ -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(); @@ -121,6 +109,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); diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index defa80f324..af1bebff80 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -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()); diff --git a/test/Analysis/CFNumber.c b/test/Analysis/CFNumber.c index d1af6abcd3..c82e0a683e 100644 --- a/test/Analysis/CFNumber.c +++ b/test/Analysis/CFNumber.c @@ -1,4 +1,3 @@ -// XFAIL // RUN: clang -checker-cfref -verify -triple x86_64-apple-darwin9 %s typedef signed long CFIndex; diff --git a/test/Analysis/array-struct.c b/test/Analysis/array-struct.c index 95baba9b65..dd43a6d704 100644 --- a/test/Analysis/array-struct.c +++ b/test/Analysis/array-struct.c @@ -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; diff --git a/test/Analysis/rdar-6442306-1.m b/test/Analysis/rdar-6442306-1.m index fa8f0aa168..2bc5c5c75f 100644 --- a/test/Analysis/rdar-6442306-1.m +++ b/test/Analysis/rdar-6442306-1.m @@ -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 { diff --git a/test/Analysis/stack-addr-ps.c b/test/Analysis/stack-addr-ps.c index 6372b9b853..58687f36c7 100644 --- a/test/Analysis/stack-addr-ps.c +++ b/test/Analysis/stack-addr-ps.c @@ -1,4 +1,3 @@ -// XFAIL // RUN: clang -checker-simple -verify %s #include <stdlib.h> |