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 149b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" 15aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose#include "clang/AST/CXXInheritance.h" 1655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/CharUnits.h" 17c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer#include "clang/AST/DeclObjC.h" 1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 20c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek 21c62abc1012feb0b15eff091b02c176649766a347Ted Kremenekusing namespace clang; 229ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento; 23c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek 2418c66fdc3c4008d335885695fe36fb5353c5f672Ted KremenekStoreManager::StoreManager(ProgramStateManager &stateMgr) 25c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek : svalBuilder(stateMgr.getSValBuilder()), StateMgr(stateMgr), 26c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek MRMgr(svalBuilder.getRegionManager()), Ctx(stateMgr.getContext()) {} 27c62abc1012feb0b15eff091b02c176649766a347Ted Kremenek 28e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan RoseStoreRef StoreManager::enterStackFrame(Store OldStore, 29e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose const CallEvent &Call, 30e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose const StackFrameContext *LCtx) { 31e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose StoreRef Store = StoreRef(OldStore, *this); 32e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose 33ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose SmallVector<CallEvent::FrameBindingTy, 16> InitialBindings; 34ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose Call.getInitialStackFrameContents(LCtx, InitialBindings); 35e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose 36ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose for (CallEvent::BindingsTy::iterator I = InitialBindings.begin(), 37ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose E = InitialBindings.end(); 38ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose I != E; ++I) { 39ef15831780b705475e7b237ac16418e9b53cb7a6Jordan Rose Store = Bind(Store.getStore(), I->first, I->second); 40e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose } 41e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose 42e54cfc7b9990acffd0a8a4ba381717b4bb9f3011Jordan Rose return Store; 43ff59efd65bb1f2f8d005079597f814a3c8381f95Jordy Rose} 44ff59efd65bb1f2f8d005079597f814a3c8381f95Jordy Rose 4509270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xuconst MemRegion *StoreManager::MakeElementRegion(const MemRegion *Base, 46652be346f74feba027bcbdeb6a3e3f4755a0e62cZhongxing Xu QualType EleTy, uint64_t index) { 47c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek NonLoc idx = svalBuilder.makeArrayIndex(index); 48c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek return MRMgr.getElementRegion(EleTy, idx, Base, svalBuilder.getContext()); 49411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek} 50411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek 5177a4d5687c2cb3199c689892c9d040a94ff270afTed KremenekStoreRef StoreManager::BindDefault(Store store, const MemRegion *R, SVal V) { 5277a4d5687c2cb3199c689892c9d040a94ff270afTed Kremenek return StoreRef(store, *this); 5377a4d5687c2cb3199c689892c9d040a94ff270afTed Kremenek} 5477a4d5687c2cb3199c689892c9d040a94ff270afTed Kremenek 5587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainarconst ElementRegion *StoreManager::GetElementZeroRegion(const MemRegion *R, 56856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu QualType T) { 57c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek NonLoc idx = svalBuilder.makeZeroArrayIndex(); 58856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu assert(!T.isNull()); 59856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu return MRMgr.getElementRegion(T, idx, R, Ctx); 60856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu} 61856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu 622534528c22260211a073e192c38d0db84c70c327Ted Kremenekconst MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy) { 631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 649c378f705405d37f49795d5e915989de774fe11fTed Kremenek ASTContext &Ctx = StateMgr.getContext(); 651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 66b9a44250c502cf9f9a2c18ccd50f06158dd7357bTed Kremenek // Handle casts to Objective-C objects. 6719e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek if (CastToTy->isObjCObjectPointerType()) 68479529e679957fbb92b56e116e3c86734429331eZhongxing Xu return R->StripCasts(); 6919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 7063b9cfe8f2aaec53710b59e565bb8d5afb558b40Ted Kremenek if (CastToTy->isBlockPointerType()) { 71abd46e13cfd48f2c9bf26d9759edb4366aaa6d5bTed Kremenek // FIXME: We may need different solutions, depending on the symbol 7263b9cfe8f2aaec53710b59e565bb8d5afb558b40Ted Kremenek // involved. Blocks can be casted to/from 'id', as they can be treated 73abd46e13cfd48f2c9bf26d9759edb4366aaa6d5bTed Kremenek // as Objective-C objects. This could possibly be handled by enhancing 741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // our reasoning of downcasts of symbolic objects. 75abd46e13cfd48f2c9bf26d9759edb4366aaa6d5bTed Kremenek if (isa<CodeTextRegion>(R) || isa<SymbolicRegion>(R)) 7609270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xu return R; 7763b9cfe8f2aaec53710b59e565bb8d5afb558b40Ted Kremenek 7863b9cfe8f2aaec53710b59e565bb8d5afb558b40Ted Kremenek // We don't know what to make of it. Return a NULL region, which 7963b9cfe8f2aaec53710b59e565bb8d5afb558b40Ted Kremenek // will be interpretted as UnknownVal. 806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 8163b9cfe8f2aaec53710b59e565bb8d5afb558b40Ted Kremenek } 82411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek 8348ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek // Now assume we are casting from pointer to pointer. Other cases should 8448ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek // already be handled. 85b14175a5371a6c71f3b2dbe4e7aa14803ac38c54Argyrios Kyrtzidis QualType PointeeTy = CastToTy->getPointeeType(); 869a108eb88f93c524dfa5fb2c3fea3896b1eb6525Ted Kremenek QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy); 879a108eb88f93c524dfa5fb2c3fea3896b1eb6525Ted Kremenek 889a108eb88f93c524dfa5fb2c3fea3896b1eb6525Ted Kremenek // Handle casts to void*. We just pass the region through. 89a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor if (CanonPointeeTy.getLocalUnqualifiedType() == Ctx.VoidTy) 9009270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xu return R; 911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 929a108eb88f93c524dfa5fb2c3fea3896b1eb6525Ted Kremenek // Handle casts from compatible types. 9319e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek if (R->isBoundable()) 949697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) { 95018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu QualType ObjTy = Ctx.getCanonicalType(TR->getValueType()); 969a108eb88f93c524dfa5fb2c3fea3896b1eb6525Ted Kremenek if (CanonPointeeTy == ObjTy) 9709270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xu return R; 9819e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek } 9919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek 10048ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek // Process region cast according to the kind of the region being cast. 101fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek switch (R->getKind()) { 102de0d26310191215a6d1d189dc419f87af18ce6beTed Kremenek case MemRegion::CXXThisRegionKind: 1034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar case MemRegion::CodeSpaceRegionKind: 10467d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek case MemRegion::StackLocalsSpaceRegionKind: 10567d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek case MemRegion::StackArgumentsSpaceRegionKind: 10667d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek case MemRegion::HeapSpaceRegionKind: 1072b87ae45e129b941d0a4d221c9d4842385a119bdTed Kremenek case MemRegion::UnknownSpaceRegionKind: 108eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks case MemRegion::StaticGlobalSpaceRegionKind: 109eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks case MemRegion::GlobalInternalSpaceRegionKind: 110eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks case MemRegion::GlobalSystemSpaceRegionKind: 111eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks case MemRegion::GlobalImmutableSpaceRegionKind: { 112b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Invalid region cast"); 1131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 1141e4a32acfad6a9f4cf555fdbc5c6c44c558b9fcbTed Kremenek 1154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar case MemRegion::FunctionCodeRegionKind: 1164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar case MemRegion::BlockCodeRegionKind: 1171e4a32acfad6a9f4cf555fdbc5c6c44c558b9fcbTed Kremenek case MemRegion::BlockDataRegionKind: 118fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::StringRegionKind: 119fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek // FIXME: Need to handle arbitrary downcasts. 12019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek case MemRegion::SymbolicRegionKind: 12119e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek case MemRegion::AllocaRegionKind: 122fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::CompoundLiteralRegionKind: 123fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::FieldRegionKind: 124fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek case MemRegion::ObjCIvarRegionKind: 1254c62b557e269a27515dfca1f754ae936c8fdb824Ted Kremenek case MemRegion::ObjCStringRegionKind: 1261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump case MemRegion::VarRegionKind: 12702fe28c8a6da29d4ad88d0900c133dcf22d24a75Zhongxing Xu case MemRegion::CXXTempObjectRegionKind: 12802fe28c8a6da29d4ad88d0900c133dcf22d24a75Zhongxing Xu case MemRegion::CXXBaseObjectRegionKind: 12909270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xu return MakeElementRegion(R, PointeeTy); 1301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13119e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek case MemRegion::ElementRegionKind: { 13219e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // If we are casting from an ElementRegion to another type, the 13319e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // algorithm is as follows: 13419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // 13519e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // (1) Compute the "raw offset" of the ElementRegion from the 13619e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // base region. This is done by calling 'getAsRawOffset()'. 13719e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // 1381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // (2a) If we get a 'RegionRawOffset' after calling 13919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // 'getAsRawOffset()', determine if the absolute offset 1401eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // can be exactly divided into chunks of the size of the 1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // casted-pointee type. If so, create a new ElementRegion with 14219e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // the pointee-cast type as the new ElementType and the index 14319e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // being the offset divded by the chunk size. If not, create 14419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // a new ElementRegion at offset 0 off the raw offset region. 14519e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // 14619e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // (2b) If we don't a get a 'RegionRawOffset' after calling 14719e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // 'getAsRawOffset()', it means that we are at offset 0. 1481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // 14919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // FIXME: Handle symbolic raw offsets. 1501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15119e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek const ElementRegion *elementR = cast<ElementRegion>(R); 1527caf9b369cba6edaf6eac25121cbc65ee938f14dZhongxing Xu const RegionRawOffset &rawOff = elementR->getAsArrayOffset(); 15319e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek const MemRegion *baseR = rawOff.getRegion(); 1541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15519e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // If we cannot compute a raw offset, throw up our hands and return 15619e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // a NULL MemRegion*. 15719e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek if (!baseR) 1586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1609ff2b13aee0f89d23ef4820218f9b88bb5e5c1c1Ken Dyck CharUnits off = rawOff.getOffset(); 1611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 162199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck if (off.isZero()) { 16319e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // Edge case: we are at 0 bytes off the beginning of baseR. We 16419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // check to see if type we are casting to is the same as the base 1651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump // region. If so, just return the base region. 1669697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(baseR)) { 167018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu QualType ObjTy = Ctx.getCanonicalType(TR->getValueType()); 16819e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy); 16919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek if (CanonPointeeTy == ObjTy) 17009270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xu return baseR; 17119e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek } 1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17319e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // Otherwise, create a new ElementRegion at offset 0. 17409270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xu return MakeElementRegion(baseR, PointeeTy); 175169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek } 1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 17719e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // We have a non-zero offset from the base region. We want to determine 17819e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // if the offset can be evenly divided by sizeof(PointeeTy). If so, 17919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // we create an ElementRegion whose index is that value. Otherwise, we 18019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // create two ElementRegions, one that reflects a raw offset and the other 18119e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // that reflects the cast. 1821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 18319e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // Compute the index for the new ElementRegion. 18419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek int64_t newIndex = 0; 1856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const MemRegion *newSuperR = nullptr; 186169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek 18719e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // We can only compute sizeof(PointeeTy) if it is a complete type. 188176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines if (!PointeeTy->isIncompleteType()) { 18919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // Compute the size in **bytes**. 190199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck CharUnits pointeeTySize = Ctx.getTypeSizeInChars(PointeeTy); 191974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek if (!pointeeTySize.isZero()) { 192974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek // Is the offset a multiple of the size? If so, we can layer the 193974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek // ElementRegion (with elementType == PointeeTy) directly on top of 194974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek // the base region. 195974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek if (off % pointeeTySize == 0) { 196974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek newIndex = off / pointeeTySize; 197974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek newSuperR = baseR; 198974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek } 19919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek } 20019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek } 2011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20219e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek if (!newSuperR) { 20319e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // Create an intermediate ElementRegion to represent the raw byte. 20419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek // This will be the super region of the final ElementRegion. 205199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck newSuperR = MakeElementRegion(baseR, Ctx.CharTy, off.getQuantity()); 20619e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek } 2071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 20809270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xu return MakeElementRegion(newSuperR, PointeeTy, newIndex); 20948ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek } 21048ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek } 2111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 212b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("unreachable"); 21348ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek} 2141894dce96476dbe58c0e60d47f8987cbeb3d3869Ted Kremenek 215ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rosestatic bool regionMatchesCXXRecordType(SVal V, QualType Ty) { 216ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose const MemRegion *MR = V.getAsRegion(); 217ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose if (!MR) 218ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose return true; 219ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose 220ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(MR); 221ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose if (!TVR) 222ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose return true; 223ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose 224ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose const CXXRecordDecl *RD = TVR->getValueType()->getAsCXXRecordDecl(); 225ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose if (!RD) 226ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose return true; 227ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose 228ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose const CXXRecordDecl *Expected = Ty->getPointeeCXXRecordDecl(); 229ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose if (!Expected) 230ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose Expected = Ty->getAsCXXRecordDecl(); 231ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose 232ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose return Expected->getCanonicalDecl() == RD->getCanonicalDecl(); 233ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose} 234ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose 2352c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan RoseSVal StoreManager::evalDerivedToBase(SVal Derived, const CastExpr *Cast) { 236ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose // Sanity check to avoid doing the wrong thing in the face of 237ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose // reinterpret_cast. 238ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose if (!regionMatchesCXXRecordType(Derived, Cast->getSubExpr()->getType())) 239ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose return UnknownVal(); 240ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose 2412c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose // Walk through the cast path to create nested CXXBaseRegions. 2422c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose SVal Result = Derived; 2432c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose for (CastExpr::path_const_iterator I = Cast->path_begin(), 2442c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose E = Cast->path_end(); 2452c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose I != E; ++I) { 2464411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose Result = evalDerivedToBase(Result, (*I)->getType(), (*I)->isVirtual()); 2472c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose } 2482c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose return Result; 2492c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose} 2502c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose 251aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan RoseSVal StoreManager::evalDerivedToBase(SVal Derived, const CXXBasePath &Path) { 252aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose // Walk through the path to create nested CXXBaseRegions. 253aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose SVal Result = Derived; 254aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose for (CXXBasePath::const_iterator I = Path.begin(), E = Path.end(); 255aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose I != E; ++I) { 2564411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose Result = evalDerivedToBase(Result, I->Base->getType(), 2574411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose I->Base->isVirtual()); 258aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose } 259aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose return Result; 260aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose} 261aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose 2624411b423e91da0a2c879b70c0222aeba35f72044Jordan RoseSVal StoreManager::evalDerivedToBase(SVal Derived, QualType BaseType, 2634411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose bool IsVirtual) { 264dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie Optional<loc::MemRegionVal> DerivedRegVal = 2655251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie Derived.getAs<loc::MemRegionVal>(); 266aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose if (!DerivedRegVal) 267aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose return Derived; 268aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose 269aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose const CXXRecordDecl *BaseDecl = BaseType->getPointeeCXXRecordDecl(); 270aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose if (!BaseDecl) 271aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose BaseDecl = BaseType->getAsCXXRecordDecl(); 272aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose assert(BaseDecl && "not a C++ object?"); 273aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose 274aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose const MemRegion *BaseReg = 2754411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose MRMgr.getCXXBaseObjectRegion(BaseDecl, DerivedRegVal->getRegion(), 2764411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose IsVirtual); 277aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose 278aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose return loc::MemRegionVal(BaseReg); 279aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose} 280aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose 281f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose/// Returns the static type of the given region, if it represents a C++ class 282f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose/// object. 283f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose/// 284f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose/// This handles both fully-typed regions, where the dynamic type is known, and 285f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose/// symbolic regions, where the dynamic type is merely bounded (and even then, 286f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose/// only ostensibly!), but does not take advantage of any dynamic type info. 287f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rosestatic const CXXRecordDecl *getCXXRecordType(const MemRegion *MR) { 288f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(MR)) 289f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose return TVR->getValueType()->getAsCXXRecordDecl(); 290f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) 291f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose return SR->getSymbol()->getType()->getPointeeCXXRecordDecl(); 2926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 293f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose} 294f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose 295f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan RoseSVal StoreManager::evalDynamicCast(SVal Base, QualType TargetType, 296aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose bool &Failed) { 297aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose Failed = false; 298aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose 299f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose const MemRegion *MR = Base.getAsRegion(); 300f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose if (!MR) 301aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose return UnknownVal(); 302aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose 303aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose // Assume the derived class is a pointer or a reference to a CXX record. 304f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose TargetType = TargetType->getPointeeType(); 305f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose assert(!TargetType.isNull()); 306f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose const CXXRecordDecl *TargetClass = TargetType->getAsCXXRecordDecl(); 307f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose if (!TargetClass && !TargetType->isVoidType()) 308aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose return UnknownVal(); 309aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose 310aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose // Drill down the CXXBaseObject chains, which represent upcasts (casts from 311aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose // derived to base). 312f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose while (const CXXRecordDecl *MRClass = getCXXRecordType(MR)) { 313aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose // If found the derived class, the cast succeeds. 314f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose if (MRClass == TargetClass) 315f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose return loc::MemRegionVal(MR); 316aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose 3179122025df6682a29ba4bdfc4330d2caebb8ea4dePavel Labath // We skip over incomplete types. They must be the result of an earlier 3189122025df6682a29ba4bdfc4330d2caebb8ea4dePavel Labath // reinterpret_cast, as one can only dynamic_cast between types in the same 3199122025df6682a29ba4bdfc4330d2caebb8ea4dePavel Labath // class hierarchy. 3209122025df6682a29ba4bdfc4330d2caebb8ea4dePavel Labath if (!TargetType->isVoidType() && MRClass->hasDefinition()) { 321aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose // Static upcasts are marked as DerivedToBase casts by Sema, so this will 322aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose // only happen when multiple or virtual inheritance is involved. 323aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true, 324aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose /*DetectVirtual=*/false); 325f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose if (MRClass->isDerivedFrom(TargetClass, Paths)) 326f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose return evalDerivedToBase(loc::MemRegionVal(MR), Paths.front()); 327aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose } 328aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose 329f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose if (const CXXBaseObjectRegion *BaseR = dyn_cast<CXXBaseObjectRegion>(MR)) { 330aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose // Drill down the chain to get the derived classes. 331f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose MR = BaseR->getSuperRegion(); 332f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose continue; 333aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose } 334f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose 335f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose // If this is a cast to void*, return the region. 336f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose if (TargetType->isVoidType()) 337f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose return loc::MemRegionVal(MR); 338f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose 339f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose // Strange use of reinterpret_cast can give us paths we don't reason 340f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose // about well, by putting in ElementRegions where we'd expect 341f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose // CXXBaseObjectRegions. If it's a valid reinterpret_cast (i.e. if the 342f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose // derived class has a zero offset from the base class), then it's safe 343f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose // to strip the cast; if it's invalid, -Wreinterpret-base-class should 344f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose // catch it. In the interest of performance, the analyzer will silently 345f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose // do the wrong thing in the invalid case (because offsets for subregions 346f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose // will be wrong). 347f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose const MemRegion *Uncasted = MR->StripCasts(/*IncludeBaseCasts=*/false); 348f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose if (Uncasted == MR) { 349f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose // We reached the bottom of the hierarchy and did not find the derived 350f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose // class. We we must be casting the base to derived, so the cast should 351f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose // fail. 352f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose break; 353f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose } 354f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose 355f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose MR = Uncasted; 356aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose } 357f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose 358f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose // We failed if the region we ended up with has perfect type info. 359f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose Failed = isa<TypedValueRegion>(MR); 360aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose return UnknownVal(); 361aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose} 362aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose 3631894dce96476dbe58c0e60d47f8987cbeb3d3869Ted Kremenek 3641894dce96476dbe58c0e60d47f8987cbeb3d3869Ted Kremenek/// CastRetrievedVal - Used by subclasses of StoreManager to implement 3651894dce96476dbe58c0e60d47f8987cbeb3d3869Ted Kremenek/// implicit casts that arise from loads from regions that are reinterpreted 3661894dce96476dbe58c0e60d47f8987cbeb3d3869Ted Kremenek/// as another region. 3679697934650354bed2e509d8e7e44f21a1fb00f76Ted KremenekSVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R, 368c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek QualType castTy, bool performTestOnly) { 36987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 370aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks if (castTy.isNull() || V.isUnknownOrUndef()) 371652be346f74feba027bcbdeb6a3e3f4755a0e62cZhongxing Xu return V; 37287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 373c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek ASTContext &Ctx = svalBuilder.getContext(); 3742f4a6b25a7409f6f05e8a5e6864de21a337c8958Zhongxing Xu 37587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar if (performTestOnly) { 376c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek // Automatically translate references to pointers. 377018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu QualType T = R->getValueType(); 378c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek if (const ReferenceType *RT = T->getAs<ReferenceType>()) 379c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek T = Ctx.getPointerType(RT->getPointeeType()); 38087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 381c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek assert(svalBuilder.getContext().hasSameUnqualifiedType(castTy, T)); 382c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek return V; 383c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek } 38487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar 385aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks return svalBuilder.dispatchCast(V, castTy); 3861894dce96476dbe58c0e60d47f8987cbeb3d3869Ted Kremenek} 3871894dce96476dbe58c0e60d47f8987cbeb3d3869Ted Kremenek 3889c378f705405d37f49795d5e915989de774fe11fTed KremenekSVal StoreManager::getLValueFieldOrIvar(const Decl *D, SVal Base) { 389c1511e04998e685c9e030323e248363b9633267dZhongxing Xu if (Base.isUnknownOrUndef()) 390c1511e04998e685c9e030323e248363b9633267dZhongxing Xu return Base; 391c1511e04998e685c9e030323e248363b9633267dZhongxing Xu 3925251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie Loc BaseL = Base.castAs<Loc>(); 3936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines const MemRegion* BaseR = nullptr; 394c1511e04998e685c9e030323e248363b9633267dZhongxing Xu 395c1511e04998e685c9e030323e248363b9633267dZhongxing Xu switch (BaseL.getSubKind()) { 3964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar case loc::MemRegionValKind: 3975251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie BaseR = BaseL.castAs<loc::MemRegionVal>().getRegion(); 398c1511e04998e685c9e030323e248363b9633267dZhongxing Xu break; 399c1511e04998e685c9e030323e248363b9633267dZhongxing Xu 400c1511e04998e685c9e030323e248363b9633267dZhongxing Xu case loc::GotoLabelKind: 401c1511e04998e685c9e030323e248363b9633267dZhongxing Xu // These are anormal cases. Flag an undefined value. 402c1511e04998e685c9e030323e248363b9633267dZhongxing Xu return UndefinedVal(); 403c1511e04998e685c9e030323e248363b9633267dZhongxing Xu 404c1511e04998e685c9e030323e248363b9633267dZhongxing Xu case loc::ConcreteIntKind: 405c1511e04998e685c9e030323e248363b9633267dZhongxing Xu // While these seem funny, this can happen through casts. 406c1511e04998e685c9e030323e248363b9633267dZhongxing Xu // FIXME: What we should return is the field offset. For example, 407c1511e04998e685c9e030323e248363b9633267dZhongxing Xu // add the field offset to the integer value. That way funny things 408c1511e04998e685c9e030323e248363b9633267dZhongxing Xu // like this work properly: &(((struct foo *) 0xa)->f) 409c1511e04998e685c9e030323e248363b9633267dZhongxing Xu return Base; 410c1511e04998e685c9e030323e248363b9633267dZhongxing Xu 411c1511e04998e685c9e030323e248363b9633267dZhongxing Xu default: 412b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie llvm_unreachable("Unhandled Base."); 413c1511e04998e685c9e030323e248363b9633267dZhongxing Xu } 414c1511e04998e685c9e030323e248363b9633267dZhongxing Xu 415c1511e04998e685c9e030323e248363b9633267dZhongxing Xu // NOTE: We must have this check first because ObjCIvarDecl is a subclass 416c1511e04998e685c9e030323e248363b9633267dZhongxing Xu // of FieldDecl. 417c1511e04998e685c9e030323e248363b9633267dZhongxing Xu if (const ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(D)) 418c1511e04998e685c9e030323e248363b9633267dZhongxing Xu return loc::MemRegionVal(MRMgr.getObjCIvarRegion(ID, BaseR)); 419c1511e04998e685c9e030323e248363b9633267dZhongxing Xu 420c1511e04998e685c9e030323e248363b9633267dZhongxing Xu return loc::MemRegionVal(MRMgr.getFieldRegion(cast<FieldDecl>(D), BaseR)); 421c1511e04998e685c9e030323e248363b9633267dZhongxing Xu} 42252535688b1339e0b3898ac0d670052482851a3abZhongxing Xu 423c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin KramerSVal StoreManager::getLValueIvar(const ObjCIvarDecl *decl, SVal base) { 424c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer return getLValueFieldOrIvar(decl, base); 425c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer} 426c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer 42787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga NainarSVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset, 42852535688b1339e0b3898ac0d670052482851a3abZhongxing Xu SVal Base) { 42952535688b1339e0b3898ac0d670052482851a3abZhongxing Xu 43052535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // If the base is an unknown or undefined value, just return it back. 43152535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // FIXME: For absolute pointer addresses, we just return that value back as 43252535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // well, although in reality we should return the offset added to that 43352535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // value. 4345251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie if (Base.isUnknownOrUndef() || Base.getAs<loc::ConcreteInt>()) 43552535688b1339e0b3898ac0d670052482851a3abZhongxing Xu return Base; 43652535688b1339e0b3898ac0d670052482851a3abZhongxing Xu 4375251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie const MemRegion* BaseRegion = Base.castAs<loc::MemRegionVal>().getRegion(); 43852535688b1339e0b3898ac0d670052482851a3abZhongxing Xu 43952535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // Pointer of any type can be cast and used as array base. 44052535688b1339e0b3898ac0d670052482851a3abZhongxing Xu const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion); 44152535688b1339e0b3898ac0d670052482851a3abZhongxing Xu 44252535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // Convert the offset to the appropriate size and signedness. 4435251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie Offset = svalBuilder.convertToArrayIndex(Offset).castAs<NonLoc>(); 44452535688b1339e0b3898ac0d670052482851a3abZhongxing Xu 44552535688b1339e0b3898ac0d670052482851a3abZhongxing Xu if (!ElemR) { 44652535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // 44752535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // If the base region is not an ElementRegion, create one. 44852535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // This can happen in the following example: 44952535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // 45052535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // char *p = __builtin_alloc(10); 45152535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // p[1] = 8; 45252535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // 45352535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // Observe that 'p' binds to an AllocaRegion. 45452535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // 45552535688b1339e0b3898ac0d670052482851a3abZhongxing Xu return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset, 45652535688b1339e0b3898ac0d670052482851a3abZhongxing Xu BaseRegion, Ctx)); 45752535688b1339e0b3898ac0d670052482851a3abZhongxing Xu } 45852535688b1339e0b3898ac0d670052482851a3abZhongxing Xu 45952535688b1339e0b3898ac0d670052482851a3abZhongxing Xu SVal BaseIdx = ElemR->getIndex(); 46052535688b1339e0b3898ac0d670052482851a3abZhongxing Xu 4615251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie if (!BaseIdx.getAs<nonloc::ConcreteInt>()) 46252535688b1339e0b3898ac0d670052482851a3abZhongxing Xu return UnknownVal(); 46352535688b1339e0b3898ac0d670052482851a3abZhongxing Xu 4645251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie const llvm::APSInt &BaseIdxI = 4655251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie BaseIdx.castAs<nonloc::ConcreteInt>().getValue(); 466e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose 467e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose // Only allow non-integer offsets if the base region has no offset itself. 468e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose // FIXME: This is a somewhat arbitrary restriction. We should be using 469846eabd187be4bfe992e8bca131166b734d86e0dTed Kremenek // SValBuilder here to add the two offsets without checking their types. 4705251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie if (!Offset.getAs<nonloc::ConcreteInt>()) { 471e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose if (isa<ElementRegion>(BaseRegion->StripCasts())) 472e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose return UnknownVal(); 473e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose 474e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset, 475e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose ElemR->getSuperRegion(), 476e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose Ctx)); 477e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose } 478e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose 4795251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie const llvm::APSInt& OffI = Offset.castAs<nonloc::ConcreteInt>().getValue(); 48052535688b1339e0b3898ac0d670052482851a3abZhongxing Xu assert(BaseIdxI.isSigned()); 48152535688b1339e0b3898ac0d670052482851a3abZhongxing Xu 48252535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // Compute the new index. 483c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek nonloc::ConcreteInt NewIdx(svalBuilder.getBasicValueFactory().getValue(BaseIdxI + 48402282acd7a42d06a3178e3102d34a585bd82dd9fTed Kremenek OffI)); 48552535688b1339e0b3898ac0d670052482851a3abZhongxing Xu 48652535688b1339e0b3898ac0d670052482851a3abZhongxing Xu // Construct the new ElementRegion. 48752535688b1339e0b3898ac0d670052482851a3abZhongxing Xu const MemRegion *ArrayR = ElemR->getSuperRegion(); 48852535688b1339e0b3898ac0d670052482851a3abZhongxing Xu return loc::MemRegionVal(MRMgr.getElementRegion(elementType, NewIdx, ArrayR, 48952535688b1339e0b3898ac0d670052482851a3abZhongxing Xu Ctx)); 49052535688b1339e0b3898ac0d670052482851a3abZhongxing Xu} 491a4c7a4314ffbe402091695874e93d9b0a79c8099Ted Kremenek 492a4c7a4314ffbe402091695874e93d9b0a79c8099Ted KremenekStoreManager::BindingsHandler::~BindingsHandler() {} 493a4c7a4314ffbe402091695874e93d9b0a79c8099Ted Kremenek 49427b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaksbool StoreManager::FindUniqueBinding::HandleBinding(StoreManager& SMgr, 49527b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks Store store, 49627b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks const MemRegion* R, 49727b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks SVal val) { 49827b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks SymbolRef SymV = val.getAsLocSymbol(); 49927b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks if (!SymV || SymV != Sym) 50027b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks return true; 50127b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks 50227b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks if (Binding) { 50327b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks First = false; 50427b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks return false; 50527b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks } 50627b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks else 50727b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks Binding = R; 50827b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks 50927b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks return true; 51027b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks} 511