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