Store.cpp revision 169077dde4d91270a7495793f1e00b22aa0bc7ca
1c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek//== Store.cpp - Interface for maps from Locations to Values ----*- C++ -*--==// 2c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek// 3c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek// The LLVM Compiler Infrastructure 4c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek// 5c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek// This file is distributed under the University of Illinois Open Source 6c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek// License. See LICENSE.TXT for details. 7c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek// 8c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek//===----------------------------------------------------------------------===// 9c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek// 10c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek// This file defined the types Store and StoreManager. 11c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek// 12c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek//===----------------------------------------------------------------------===// 13c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek 14c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek#include "clang/Analysis/PathSensitive/Store.h" 15c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek#include "clang/Analysis/PathSensitive/GRState.h" 16c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek 17c62abc1012feb0b15eff091b02c176649766a347Ted Kremenekusing namespace clang; 18c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek 1948ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed KremenekStoreManager::StoreManager(GRStateManager &stateMgr, bool useNewCastRegion) 20c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek : ValMgr(stateMgr.getValueManager()), 21c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek StateMgr(stateMgr), 2248ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek UseNewCastRegion(useNewCastRegion), 23c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek MRMgr(ValMgr.getRegionManager()) {} 24c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek 25c62abc1012feb0b15eff091b02c176649766a347Ted KremenekStoreManager::CastResult 26411af40d038947b6d2a8ad9549c85c1c4c52d15aTed KremenekStoreManager::MakeElementRegion(const GRState *state, const MemRegion *region, 27411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek QualType pointeeTy, QualType castToTy) { 28411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek 29411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek // Record the cast type of the region. 30411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek state = setCastType(state, region, castToTy); 31411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek 32411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek // Create a new ElementRegion at offset 0. 33411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek SVal idx = ValMgr.makeZeroArrayIndex(); 34411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek return CastResult(state, MRMgr.getElementRegion(pointeeTy, idx, region, 35411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek ValMgr.getContext())); 36411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek} 37411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek 38169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenekstatic bool IsCompleteType(ASTContext &Ctx, QualType Ty) { 39169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek if (const RecordType *RT = Ty->getAsRecordType()) { 40169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek const RecordDecl *D = RT->getDecl(); 41169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek if (!D->getDefinition(Ctx)) 42169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek return false; 43169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek } 44169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek 45169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek return true; 46169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek} 47169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek 48411af40d038947b6d2a8ad9549c85c1c4c52d15aTed KremenekStoreManager::CastResult 4948ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed KremenekStoreManager::NewCastRegion(const GRState *state, const MemRegion* R, 5048ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek QualType CastToTy) { 5148ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek 5248ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek ASTContext& Ctx = StateMgr.getContext(); 5348ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek 5448ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek // We need to know the real type of CastToTy. 5548ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek QualType ToTy = Ctx.getCanonicalType(CastToTy); 56411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek 57b9a44250c502cf9f9a2c18ccd50f06158dd7357bTed Kremenek // Handle casts to Objective-C objects. 58fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek if (Ctx.isObjCObjectPointerType(CastToTy)) { 59fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek state = setCastType(state, R, CastToTy); 60145918ca119904b6abe8b41aae0cbbf9a7247905Ted Kremenek return CastResult(state, R); 61145918ca119904b6abe8b41aae0cbbf9a7247905Ted Kremenek } 62411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek 6348ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek // Now assume we are casting from pointer to pointer. Other cases should 6448ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek // already be handled. 65fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek QualType PointeeTy = CastToTy->getAsPointerType()->getPointeeType(); 66169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek 6748ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek // Process region cast according to the kind of the region being cast. 68fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek switch (R->getKind()) { 69fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::BEG_TYPED_REGIONS: 70fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::MemSpaceRegionKind: 71fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::BEG_DECL_REGIONS: 72fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::END_DECL_REGIONS: 73fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::END_TYPED_REGIONS: 74fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::TypedViewRegionKind: { 75fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek assert(0 && "Invalid region cast"); 76fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek break; 7748ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek } 78fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek 79fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::CodeTextRegionKind: { 80fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek // CodeTextRegion should be cast to only function pointer type. 81fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek assert(CastToTy->isFunctionPointerType() || CastToTy->isBlockPointerType() 82fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek || (CastToTy->isPointerType() && 83fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek CastToTy->getAsPointerType()->getPointeeType()->isVoidType())); 84fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek break; 85fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek } 86fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek 87fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::StringRegionKind: 88fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek // Handle casts of string literals. 89fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek return MakeElementRegion(state, R, PointeeTy, CastToTy); 90fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek 91fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::ObjCObjectRegionKind: 92fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::SymbolicRegionKind: 93fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek // FIXME: Need to handle arbitrary downcasts. 94fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::AllocaRegionKind: { 95fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek state = setCastType(state, R, CastToTy); 96fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek break; 97fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek } 98fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek 99fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::CompoundLiteralRegionKind: 100fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::ElementRegionKind: 101fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::FieldRegionKind: 102fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::ObjCIvarRegionKind: 103fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::VarRegionKind: { 104db5f266be075aba0f4ca1690e358245a726c9c61Ted Kremenek // VarRegion, ElementRegion, and FieldRegion has an inherent type. 105db5f266be075aba0f4ca1690e358245a726c9c61Ted Kremenek // Normally they should not be cast. We only layer an ElementRegion when 106db5f266be075aba0f4ca1690e358245a726c9c61Ted Kremenek // the cast-to pointee type is of smaller size. In other cases, we return 107db5f266be075aba0f4ca1690e358245a726c9c61Ted Kremenek // the original VarRegion. 108fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek 109169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek // If the pointee or object type is incomplete, do compute their sizes, 110169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek // and return the original region. 111fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek QualType ObjTy = cast<TypedRegion>(R)->getValueType(Ctx); 112169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek 113169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek if (!IsCompleteType(Ctx, PointeeTy) || !IsCompleteType(Ctx, ObjTy)) { 114169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek state = setCastType(state, R, ToTy); 115169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek break; 116169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek } 117169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek 118fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek uint64_t PointeeTySize = Ctx.getTypeSize(PointeeTy); 119fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek uint64_t ObjTySize = Ctx.getTypeSize(ObjTy); 120fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek 121fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek if ((PointeeTySize > 0 && PointeeTySize < ObjTySize) || 122fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek (ObjTy->isAggregateType() && PointeeTy->isScalarType()) || 123fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek ObjTySize == 0 /* R has 'void*' type. */) 124fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek return MakeElementRegion(state, R, PointeeTy, ToTy); 125fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek 12648ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek state = setCastType(state, R, ToTy); 127fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek break; 12848ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek } 12948ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek } 13048ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek 131fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek return CastResult(state, R); 13248ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek} 13348ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek 13448ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek 13548ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed KremenekStoreManager::CastResult 13648ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed KremenekStoreManager::OldCastRegion(const GRState* state, const MemRegion* R, 137fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek QualType CastToTy) { 138c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek 13930d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek ASTContext& Ctx = StateMgr.getContext(); 14030d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek 14130d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek // We need to know the real type of CastToTy. 14230d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek QualType ToTy = Ctx.getCanonicalType(CastToTy); 14330d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek 144c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek // Return the same region if the region types are compatible. 145c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) { 146ff6978263439e21d795b0602fabcb38488ef8441Zhongxing Xu QualType Ta = Ctx.getCanonicalType(TR->getLocationType(Ctx)); 14730d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek 14830d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek if (Ta == ToTy) 149c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek return CastResult(state, R); 150c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek } 151c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek 152fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek if (const PointerType* PTy = dyn_cast<PointerType>(ToTy.getTypePtr())) { 153fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek // Check if we are casting to 'void*'. 154fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek // FIXME: Handle arbitrary upcasts. 155fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek QualType Pointee = PTy->getPointeeType(); 156fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek if (Pointee->isVoidType()) { 157ca4e1b765abd796b07dc6a78a9cb1711f467a8ccTed Kremenek while (true) { 1584253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek if (const TypedViewRegion *TR = dyn_cast<TypedViewRegion>(R)) { 1594253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // Casts to void* removes TypedViewRegion. This happens when: 1604253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // 1614253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // void foo(void*); 1624253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // ... 1634253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // void bar() { 1644253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // int x; 1654253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // foo(&x); 1664253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // } 1674253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // 1684253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek R = TR->removeViews(); 1694253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek continue; 1704253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek } 1714253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek else if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { 1724253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // Casts to void* also removes ElementRegions. This happens when: 1734253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // 1744253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // void foo(void*); 1754253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // ... 1764253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // void bar() { 1774253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // int x; 1784253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // foo((char*)&x); 1794253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // } 1804253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek // 1814253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek R = ER->getSuperRegion(); 1824253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek continue; 1834253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek } 184145918ca119904b6abe8b41aae0cbbf9a7247905Ted Kremenek 185145918ca119904b6abe8b41aae0cbbf9a7247905Ted Kremenek break; 1864253051c16d0c2a5ae13af3d22383b61071ecb4cTed Kremenek } 18730d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek 18830d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek return CastResult(state, R); 18930d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek } 190fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek else if (Pointee->isIntegerType()) { 191fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek // FIXME: At some point, it stands to reason that this 'dyn_cast' should 192fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek // become a 'cast' and that 'R' will always be a TypedRegion. 193fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) { 194fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek // Check if we are casting to a region with an integer type. We now 195fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek // the types aren't the same, so we construct an ElementRegion. 196cd9392ff7336a2cd5547305ba83a65e63b4f6ff8Ted Kremenek SVal Idx = ValMgr.makeZeroArrayIndex(); 19720bd746306ecdc61125800d53ff7e07321704064Ted Kremenek 19820bd746306ecdc61125800d53ff7e07321704064Ted Kremenek // If the super region is an element region, strip it away. 19920bd746306ecdc61125800d53ff7e07321704064Ted Kremenek // FIXME: Is this the right thing to do in all cases? 20019cfa2bde3f5845c22eef2d1b9ee4a0ac9e33f7bTed Kremenek const MemRegion *Base = isa<ElementRegion>(TR) ? TR->getSuperRegion() 20119cfa2bde3f5845c22eef2d1b9ee4a0ac9e33f7bTed Kremenek : TR; 202143b2fc6fd3945c250b333383749010c2c8e3a4cZhongxing Xu ElementRegion* ER = MRMgr.getElementRegion(Pointee, Idx, Base, 20319cfa2bde3f5845c22eef2d1b9ee4a0ac9e33f7bTed Kremenek StateMgr.getContext()); 204fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek return CastResult(state, ER); 205fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek } 206fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek } 207fd6b4f3de2ef7bb7b9b33dd252078c53ada43977Ted Kremenek } 20830d1b99e4429bc27a7801bab7be6c2c04e77a648Ted Kremenek 209a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek // FIXME: Need to handle arbitrary downcasts. 210a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek // FIXME: Handle the case where a TypedViewRegion (layering a SymbolicRegion 211a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek // or an AllocaRegion is cast to another view, thus causing the memory 212a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek // to be re-used for a different purpose. 213a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek if (isa<SymbolicRegion>(R) || isa<AllocaRegion>(R)) { 214a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek const MemRegion* ViewR = MRMgr.getTypedViewRegion(CastToTy, R); 215a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek return CastResult(AddRegionView(state, ViewR, R), ViewR); 216a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek } 217a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek 218a8607d13c8df25a8c10d46db016d26f9e327418dTed Kremenek return CastResult(state, R); 219c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek} 22043e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu 22143e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xuconst GRState *StoreManager::InvalidateRegion(const GRState *state, 222313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu const MemRegion *R, 22343e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu const Expr *E, unsigned Count) { 224313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu ASTContext& Ctx = StateMgr.getContext(); 225313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu 22643e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu if (!R->isBoundable()) 22743e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu return state; 22843e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu 229313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu if (isa<AllocaRegion>(R) || isa<SymbolicRegion>(R)) { 230313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu // Invalidate the alloca region by setting its default value to 231313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu // conjured symbol. The type of the symbol is irrelavant. 232313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu SVal V = ValMgr.getConjuredSymbolVal(E, Ctx.IntTy, Count); 233313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu state = setDefaultValue(state, R, V); 234313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu return state; 235313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu } 236313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu 237313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu const TypedRegion *TR = cast<TypedRegion>(R); 238313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu 239313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu QualType T = TR->getValueType(Ctx); 24043e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu 24143e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())) { 24243e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu SVal V = ValMgr.getConjuredSymbolVal(E, T, Count); 243313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu return Bind(state, ValMgr.makeLoc(TR), V); 24443e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu } 24543e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu else if (const RecordType *RT = T->getAsStructureType()) { 24643e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu // FIXME: handle structs with default region value. 24743e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu const RecordDecl *RD = RT->getDecl()->getDefinition(Ctx); 24843e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu 24943e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu // No record definition. There is nothing we can do. 25043e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu if (!RD) 25143e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu return state; 25243e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu 25343e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu // Iterate through the fields and construct new symbols. 25443e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu for (RecordDecl::field_iterator FI=RD->field_begin(), 25543e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu FE=RD->field_end(); FI!=FE; ++FI) { 25643e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu 25743e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu // For now just handle scalar fields. 25843e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu FieldDecl *FD = *FI; 25943e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu QualType FT = FD->getType(); 260313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu const FieldRegion* FR = MRMgr.getFieldRegion(FD, TR); 26143e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu 26243e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu if (Loc::IsLocType(FT) || 26343e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu (FT->isIntegerType() && FT->isScalarType())) { 26443e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu SVal V = ValMgr.getConjuredSymbolVal(E, FT, Count); 26543e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu state = state->bindLoc(ValMgr.makeLoc(FR), V); 26643e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu } 26743e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu else if (FT->isStructureType()) { 26843e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu // set the default value of the struct field to conjured 26943e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu // symbol. Note that the type of the symbol is irrelavant. 27043e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu // We cannot use the type of the struct otherwise ValMgr won't 27143e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu // give us the conjured symbol. 27243e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu SVal V = ValMgr.getConjuredSymbolVal(E, Ctx.IntTy, Count); 27343e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu state = setDefaultValue(state, FR, V); 27443e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu } 27543e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu } 27643e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu } else if (const ArrayType *AT = Ctx.getAsArrayType(T)) { 27743e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu // Set the default value of the array to conjured symbol. 27843e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu SVal V = ValMgr.getConjuredSymbolVal(E, AT->getElementType(), 27943e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu Count); 280313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu state = setDefaultValue(state, TR, V); 28143e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu } else { 28243e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu // Just blast away other values. 283313b6dab9efcce465b68da0fed7bf422b6e5c375Zhongxing Xu state = Bind(state, ValMgr.makeLoc(TR), UnknownVal()); 28443e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu } 28543e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu 28643e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu return state; 28743e2aafea1cdeca3a3fc849b41a92cc18e001ac0Zhongxing Xu} 288