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
5119e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek// FIXME: Merge with the implementation of the same method in MemRegion.cpp
52169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenekstatic bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
536217b80b7a1379b74cced1c076338262c3c980b3Ted Kremenek  if (const RecordType *RT = Ty->getAs<RecordType>()) {
54169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek    const RecordDecl *D = RT->getDecl();
55952b017601f9c82b51119c3a1600f1312a833db9Douglas Gregor    if (!D->getDefinition())
56169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek      return false;
57169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek  }
581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
59169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek  return true;
60169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek}
61169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek
6277a4d5687c2cb3199c689892c9d040a94ff270afTed KremenekStoreRef StoreManager::BindDefault(Store store, const MemRegion *R, SVal V) {
6377a4d5687c2cb3199c689892c9d040a94ff270afTed Kremenek  return StoreRef(store, *this);
6477a4d5687c2cb3199c689892c9d040a94ff270afTed Kremenek}
6577a4d5687c2cb3199c689892c9d040a94ff270afTed Kremenek
66856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xuconst ElementRegion *StoreManager::GetElementZeroRegion(const MemRegion *R,
67856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu                                                        QualType T) {
68c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  NonLoc idx = svalBuilder.makeZeroArrayIndex();
69856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu  assert(!T.isNull());
70856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu  return MRMgr.getElementRegion(T, idx, R, Ctx);
71856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu}
72856c6bcaea56e05255e9f3997ddd56b5c18a14f0Zhongxing Xu
732534528c22260211a073e192c38d0db84c70c327Ted Kremenekconst MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy) {
741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
759c378f705405d37f49795d5e915989de774fe11fTed Kremenek  ASTContext &Ctx = StateMgr.getContext();
761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
77b9a44250c502cf9f9a2c18ccd50f06158dd7357bTed Kremenek  // Handle casts to Objective-C objects.
7819e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek  if (CastToTy->isObjCObjectPointerType())
79479529e679957fbb92b56e116e3c86734429331eZhongxing Xu    return R->StripCasts();
8019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek
8163b9cfe8f2aaec53710b59e565bb8d5afb558b40Ted Kremenek  if (CastToTy->isBlockPointerType()) {
82abd46e13cfd48f2c9bf26d9759edb4366aaa6d5bTed Kremenek    // FIXME: We may need different solutions, depending on the symbol
8363b9cfe8f2aaec53710b59e565bb8d5afb558b40Ted Kremenek    // involved.  Blocks can be casted to/from 'id', as they can be treated
84abd46e13cfd48f2c9bf26d9759edb4366aaa6d5bTed Kremenek    // as Objective-C objects.  This could possibly be handled by enhancing
851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    // our reasoning of downcasts of symbolic objects.
86abd46e13cfd48f2c9bf26d9759edb4366aaa6d5bTed Kremenek    if (isa<CodeTextRegion>(R) || isa<SymbolicRegion>(R))
8709270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xu      return R;
8863b9cfe8f2aaec53710b59e565bb8d5afb558b40Ted Kremenek
8963b9cfe8f2aaec53710b59e565bb8d5afb558b40Ted Kremenek    // We don't know what to make of it.  Return a NULL region, which
9063b9cfe8f2aaec53710b59e565bb8d5afb558b40Ted Kremenek    // will be interpretted as UnknownVal.
916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    return nullptr;
9263b9cfe8f2aaec53710b59e565bb8d5afb558b40Ted Kremenek  }
93411af40d038947b6d2a8ad9549c85c1c4c52d15aTed Kremenek
9448ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek  // Now assume we are casting from pointer to pointer. Other cases should
9548ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek  // already be handled.
96b14175a5371a6c71f3b2dbe4e7aa14803ac38c54Argyrios Kyrtzidis  QualType PointeeTy = CastToTy->getPointeeType();
979a108eb88f93c524dfa5fb2c3fea3896b1eb6525Ted Kremenek  QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy);
989a108eb88f93c524dfa5fb2c3fea3896b1eb6525Ted Kremenek
999a108eb88f93c524dfa5fb2c3fea3896b1eb6525Ted Kremenek  // Handle casts to void*.  We just pass the region through.
100a4923eb7c4b04d360cb2747641a5e92818edf804Douglas Gregor  if (CanonPointeeTy.getLocalUnqualifiedType() == Ctx.VoidTy)
10109270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xu    return R;
1021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1039a108eb88f93c524dfa5fb2c3fea3896b1eb6525Ted Kremenek  // Handle casts from compatible types.
10419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek  if (R->isBoundable())
1059697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek    if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
106018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu      QualType ObjTy = Ctx.getCanonicalType(TR->getValueType());
1079a108eb88f93c524dfa5fb2c3fea3896b1eb6525Ted Kremenek      if (CanonPointeeTy == ObjTy)
10809270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xu        return R;
10919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek    }
11019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek
11148ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek  // Process region cast according to the kind of the region being cast.
112fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek  switch (R->getKind()) {
113de0d26310191215a6d1d189dc419f87af18ce6beTed Kremenek    case MemRegion::CXXThisRegionKind:
11467d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek    case MemRegion::GenericMemSpaceRegionKind:
11567d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek    case MemRegion::StackLocalsSpaceRegionKind:
11667d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek    case MemRegion::StackArgumentsSpaceRegionKind:
11767d1287035767f4f6c8ca0c2bb755990012a44caTed Kremenek    case MemRegion::HeapSpaceRegionKind:
1182b87ae45e129b941d0a4d221c9d4842385a119bdTed Kremenek    case MemRegion::UnknownSpaceRegionKind:
119eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks    case MemRegion::StaticGlobalSpaceRegionKind:
120eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks    case MemRegion::GlobalInternalSpaceRegionKind:
121eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks    case MemRegion::GlobalSystemSpaceRegionKind:
122eb31a76d1cdaaf8874c549dc6bd964ff270d3822Anna Zaks    case MemRegion::GlobalImmutableSpaceRegionKind: {
123b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie      llvm_unreachable("Invalid region cast");
1241eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    }
1251e4a32acfad6a9f4cf555fdbc5c6c44c558b9fcbTed Kremenek
126eb1c7a04509f5d25c09005a6d46bd8bbb3ca88cbTed Kremenek    case MemRegion::FunctionTextRegionKind:
127bf0fe6c5b7bd7bc67b6b3ef0acb22bf4811f2a1bTed Kremenek    case MemRegion::BlockTextRegionKind:
1281e4a32acfad6a9f4cf555fdbc5c6c44c558b9fcbTed Kremenek    case MemRegion::BlockDataRegionKind:
129fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::StringRegionKind:
130fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek      // FIXME: Need to handle arbitrary downcasts.
13119e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek    case MemRegion::SymbolicRegionKind:
13219e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek    case MemRegion::AllocaRegionKind:
133fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::CompoundLiteralRegionKind:
134fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::FieldRegionKind:
135fc8f57c31d8336db0ccb2ce8eb9ebf52228a47c1Ted Kremenek    case MemRegion::ObjCIvarRegionKind:
1364c62b557e269a27515dfca1f754ae936c8fdb824Ted Kremenek    case MemRegion::ObjCStringRegionKind:
1371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    case MemRegion::VarRegionKind:
13802fe28c8a6da29d4ad88d0900c133dcf22d24a75Zhongxing Xu    case MemRegion::CXXTempObjectRegionKind:
13902fe28c8a6da29d4ad88d0900c133dcf22d24a75Zhongxing Xu    case MemRegion::CXXBaseObjectRegionKind:
14009270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xu      return MakeElementRegion(R, PointeeTy);
1411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
14219e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek    case MemRegion::ElementRegionKind: {
14319e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      // If we are casting from an ElementRegion to another type, the
14419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      // algorithm is as follows:
14519e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      //
14619e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      // (1) Compute the "raw offset" of the ElementRegion from the
14719e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      //     base region.  This is done by calling 'getAsRawOffset()'.
14819e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      //
1491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      // (2a) If we get a 'RegionRawOffset' after calling
15019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      //      'getAsRawOffset()', determine if the absolute offset
1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      //      can be exactly divided into chunks of the size of the
1521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      //      casted-pointee type.  If so, create a new ElementRegion with
15319e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      //      the pointee-cast type as the new ElementType and the index
15419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      //      being the offset divded by the chunk size.  If not, create
15519e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      //      a new ElementRegion at offset 0 off the raw offset region.
15619e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      //
15719e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      // (2b) If we don't a get a 'RegionRawOffset' after calling
15819e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      //      'getAsRawOffset()', it means that we are at offset 0.
1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump      //
16019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      // FIXME: Handle symbolic raw offsets.
1611eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16219e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      const ElementRegion *elementR = cast<ElementRegion>(R);
1637caf9b369cba6edaf6eac25121cbc65ee938f14dZhongxing Xu      const RegionRawOffset &rawOff = elementR->getAsArrayOffset();
16419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      const MemRegion *baseR = rawOff.getRegion();
1651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
16619e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      // If we cannot compute a raw offset, throw up our hands and return
16719e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      // a NULL MemRegion*.
16819e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      if (!baseR)
1696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines        return nullptr;
1701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1719ff2b13aee0f89d23ef4820218f9b88bb5e5c1c1Ken Dyck      CharUnits off = rawOff.getOffset();
1721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
173199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck      if (off.isZero()) {
17419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek        // Edge case: we are at 0 bytes off the beginning of baseR.  We
17519e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek        // check to see if type we are casting to is the same as the base
1761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump        // region.  If so, just return the base region.
1779697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek        if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(baseR)) {
178018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu          QualType ObjTy = Ctx.getCanonicalType(TR->getValueType());
17919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek          QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy);
18019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek          if (CanonPointeeTy == ObjTy)
18109270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xu            return baseR;
18219e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek        }
1831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek        // Otherwise, create a new ElementRegion at offset 0.
18509270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xu        return MakeElementRegion(baseR, PointeeTy);
186169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek      }
1871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
18819e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      // We have a non-zero offset from the base region.  We want to determine
18919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      // if the offset can be evenly divided by sizeof(PointeeTy).  If so,
19019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      // we create an ElementRegion whose index is that value.  Otherwise, we
19119e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      // create two ElementRegions, one that reflects a raw offset and the other
19219e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      // that reflects the cast.
1931eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
19419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      // Compute the index for the new ElementRegion.
19519e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      int64_t newIndex = 0;
1966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      const MemRegion *newSuperR = nullptr;
197169077dde4d91270a7495793f1e00b22aa0bc7caTed Kremenek
19819e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      // We can only compute sizeof(PointeeTy) if it is a complete type.
19919e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      if (IsCompleteType(Ctx, PointeeTy)) {
20019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek        // Compute the size in **bytes**.
201199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck        CharUnits pointeeTySize = Ctx.getTypeSizeInChars(PointeeTy);
202974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek        if (!pointeeTySize.isZero()) {
203974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek          // Is the offset a multiple of the size?  If so, we can layer the
204974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek          // ElementRegion (with elementType == PointeeTy) directly on top of
205974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek          // the base region.
206974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek          if (off % pointeeTySize == 0) {
207974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek            newIndex = off / pointeeTySize;
208974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek            newSuperR = baseR;
209974d97b251aaf5a735af83367cd3a930f3eb4333Ted Kremenek          }
21019e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek        }
21119e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      }
2121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21319e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      if (!newSuperR) {
21419e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek        // Create an intermediate ElementRegion to represent the raw byte.
21519e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek        // This will be the super region of the final ElementRegion.
216199c3d6cd16aebbb9c7f0d42af9d922c9628bf70Ken Dyck        newSuperR = MakeElementRegion(baseR, Ctx.CharTy, off.getQuantity());
21719e1f0ba5cec738ce6cebe3fe0e1edc782206494Ted Kremenek      }
2181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
21909270cc1b9cdd4c50012cb7984df8745e05833e5Zhongxing Xu      return MakeElementRegion(newSuperR, PointeeTy, newIndex);
22048ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek    }
22148ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek  }
2221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
223b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie  llvm_unreachable("unreachable");
22448ce7deb86ffb1e028ac9a8e7cddffc32843c26cTed Kremenek}
2251894dce96476dbe58c0e60d47f8987cbeb3d3869Ted Kremenek
226ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rosestatic bool regionMatchesCXXRecordType(SVal V, QualType Ty) {
227ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose  const MemRegion *MR = V.getAsRegion();
228ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose  if (!MR)
229ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose    return true;
230ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose
231ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose  const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(MR);
232ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose  if (!TVR)
233ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose    return true;
234ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose
235ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose  const CXXRecordDecl *RD = TVR->getValueType()->getAsCXXRecordDecl();
236ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose  if (!RD)
237ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose    return true;
238ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose
239ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose  const CXXRecordDecl *Expected = Ty->getPointeeCXXRecordDecl();
240ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose  if (!Expected)
241ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose    Expected = Ty->getAsCXXRecordDecl();
242ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose
243ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose  return Expected->getCanonicalDecl() == RD->getCanonicalDecl();
244ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose}
245ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose
2462c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan RoseSVal StoreManager::evalDerivedToBase(SVal Derived, const CastExpr *Cast) {
247ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose  // Sanity check to avoid doing the wrong thing in the face of
248ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose  // reinterpret_cast.
249ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose  if (!regionMatchesCXXRecordType(Derived, Cast->getSubExpr()->getType()))
250ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose    return UnknownVal();
251ada0d224fcff5ff07c9dd846379592f92ccf5ee7Jordan Rose
2522c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose  // Walk through the cast path to create nested CXXBaseRegions.
2532c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose  SVal Result = Derived;
2542c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose  for (CastExpr::path_const_iterator I = Cast->path_begin(),
2552c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose                                     E = Cast->path_end();
2562c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose       I != E; ++I) {
2574411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose    Result = evalDerivedToBase(Result, (*I)->getType(), (*I)->isVirtual());
2582c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose  }
2592c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose  return Result;
2602c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose}
2612c5f8d79ed128892fa548a3308a938a3a53fbb5eJordan Rose
262aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan RoseSVal StoreManager::evalDerivedToBase(SVal Derived, const CXXBasePath &Path) {
263aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  // Walk through the path to create nested CXXBaseRegions.
264aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  SVal Result = Derived;
265aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  for (CXXBasePath::const_iterator I = Path.begin(), E = Path.end();
266aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose       I != E; ++I) {
2674411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose    Result = evalDerivedToBase(Result, I->Base->getType(),
2684411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose                               I->Base->isVirtual());
269aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  }
270aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  return Result;
271aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose}
272aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose
2734411b423e91da0a2c879b70c0222aeba35f72044Jordan RoseSVal StoreManager::evalDerivedToBase(SVal Derived, QualType BaseType,
2744411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose                                     bool IsVirtual) {
275dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie  Optional<loc::MemRegionVal> DerivedRegVal =
2765251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie      Derived.getAs<loc::MemRegionVal>();
277aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  if (!DerivedRegVal)
278aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose    return Derived;
279aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose
280aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  const CXXRecordDecl *BaseDecl = BaseType->getPointeeCXXRecordDecl();
281aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  if (!BaseDecl)
282aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose    BaseDecl = BaseType->getAsCXXRecordDecl();
283aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  assert(BaseDecl && "not a C++ object?");
284aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose
285aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  const MemRegion *BaseReg =
2864411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose    MRMgr.getCXXBaseObjectRegion(BaseDecl, DerivedRegVal->getRegion(),
2874411b423e91da0a2c879b70c0222aeba35f72044Jordan Rose                                 IsVirtual);
288aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose
289aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  return loc::MemRegionVal(BaseReg);
290aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose}
291aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose
292f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose/// Returns the static type of the given region, if it represents a C++ class
293f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose/// object.
294f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose///
295f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose/// This handles both fully-typed regions, where the dynamic type is known, and
296f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose/// symbolic regions, where the dynamic type is merely bounded (and even then,
297f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose/// only ostensibly!), but does not take advantage of any dynamic type info.
298f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rosestatic const CXXRecordDecl *getCXXRecordType(const MemRegion *MR) {
299f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose  if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(MR))
300f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    return TVR->getValueType()->getAsCXXRecordDecl();
301f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
302f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    return SR->getSymbol()->getType()->getPointeeCXXRecordDecl();
3036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  return nullptr;
304f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose}
305f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose
306f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan RoseSVal StoreManager::evalDynamicCast(SVal Base, QualType TargetType,
307aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose                                   bool &Failed) {
308aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  Failed = false;
309aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose
310f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose  const MemRegion *MR = Base.getAsRegion();
311f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose  if (!MR)
312aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose    return UnknownVal();
313aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose
314aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  // Assume the derived class is a pointer or a reference to a CXX record.
315f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose  TargetType = TargetType->getPointeeType();
316f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose  assert(!TargetType.isNull());
317f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose  const CXXRecordDecl *TargetClass = TargetType->getAsCXXRecordDecl();
318f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose  if (!TargetClass && !TargetType->isVoidType())
319aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose    return UnknownVal();
320aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose
321aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  // Drill down the CXXBaseObject chains, which represent upcasts (casts from
322aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  // derived to base).
323f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose  while (const CXXRecordDecl *MRClass = getCXXRecordType(MR)) {
324aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose    // If found the derived class, the cast succeeds.
325f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    if (MRClass == TargetClass)
326f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose      return loc::MemRegionVal(MR);
327aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose
3289122025df6682a29ba4bdfc4330d2caebb8ea4dePavel Labath    // We skip over incomplete types. They must be the result of an earlier
3299122025df6682a29ba4bdfc4330d2caebb8ea4dePavel Labath    // reinterpret_cast, as one can only dynamic_cast between types in the same
3309122025df6682a29ba4bdfc4330d2caebb8ea4dePavel Labath    // class hierarchy.
3319122025df6682a29ba4bdfc4330d2caebb8ea4dePavel Labath    if (!TargetType->isVoidType() && MRClass->hasDefinition()) {
332aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose      // Static upcasts are marked as DerivedToBase casts by Sema, so this will
333aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose      // only happen when multiple or virtual inheritance is involved.
334aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose      CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true,
335aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose                         /*DetectVirtual=*/false);
336f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose      if (MRClass->isDerivedFrom(TargetClass, Paths))
337f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose        return evalDerivedToBase(loc::MemRegionVal(MR), Paths.front());
338aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose    }
339aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose
340f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    if (const CXXBaseObjectRegion *BaseR = dyn_cast<CXXBaseObjectRegion>(MR)) {
341aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose      // Drill down the chain to get the derived classes.
342f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose      MR = BaseR->getSuperRegion();
343f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose      continue;
344aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose    }
345f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose
346f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    // If this is a cast to void*, return the region.
347f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    if (TargetType->isVoidType())
348f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose      return loc::MemRegionVal(MR);
349f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose
350f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    // Strange use of reinterpret_cast can give us paths we don't reason
351f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    // about well, by putting in ElementRegions where we'd expect
352f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    // CXXBaseObjectRegions. If it's a valid reinterpret_cast (i.e. if the
353f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    // derived class has a zero offset from the base class), then it's safe
354f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    // to strip the cast; if it's invalid, -Wreinterpret-base-class should
355f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    // catch it. In the interest of performance, the analyzer will silently
356f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    // do the wrong thing in the invalid case (because offsets for subregions
357f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    // will be wrong).
358f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    const MemRegion *Uncasted = MR->StripCasts(/*IncludeBaseCasts=*/false);
359f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    if (Uncasted == MR) {
360f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose      // We reached the bottom of the hierarchy and did not find the derived
361f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose      // class. We we must be casting the base to derived, so the cast should
362f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose      // fail.
363f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose      break;
364f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    }
365f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose
366f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose    MR = Uncasted;
367aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  }
368f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose
369f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose  // We failed if the region we ended up with has perfect type info.
370f2edbec1d9817df109304f9c19ae2b34fec1feeaJordan Rose  Failed = isa<TypedValueRegion>(MR);
371aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose  return UnknownVal();
372aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose}
373aa66b08d2d8bbf05bae8c68f58724f754ab57b35Jordan Rose
3741894dce96476dbe58c0e60d47f8987cbeb3d3869Ted Kremenek
3751894dce96476dbe58c0e60d47f8987cbeb3d3869Ted Kremenek/// CastRetrievedVal - Used by subclasses of StoreManager to implement
3761894dce96476dbe58c0e60d47f8987cbeb3d3869Ted Kremenek///  implicit casts that arise from loads from regions that are reinterpreted
3771894dce96476dbe58c0e60d47f8987cbeb3d3869Ted Kremenek///  as another region.
3789697934650354bed2e509d8e7e44f21a1fb00f76Ted KremenekSVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R,
379c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek                                    QualType castTy, bool performTestOnly) {
380852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek
381aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks  if (castTy.isNull() || V.isUnknownOrUndef())
382652be346f74feba027bcbdeb6a3e3f4755a0e62cZhongxing Xu    return V;
383852274d4257134906995cb252fb3dfd2d71deae8Ted Kremenek
384c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  ASTContext &Ctx = svalBuilder.getContext();
3852f4a6b25a7409f6f05e8a5e6864de21a337c8958Zhongxing Xu
386c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek  if (performTestOnly) {
387c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek    // Automatically translate references to pointers.
388018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu    QualType T = R->getValueType();
389c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek    if (const ReferenceType *RT = T->getAs<ReferenceType>())
390c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek      T = Ctx.getPointerType(RT->getPointeeType());
391c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek
392c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek    assert(svalBuilder.getContext().hasSameUnqualifiedType(castTy, T));
393c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek    return V;
394c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek  }
395c50e6df965ff264952d8d5805d151f89c89af302Ted Kremenek
396aace9ef279be3dadd53b481aee568bd7701178b4Anna Zaks  return svalBuilder.dispatchCast(V, castTy);
3971894dce96476dbe58c0e60d47f8987cbeb3d3869Ted Kremenek}
3981894dce96476dbe58c0e60d47f8987cbeb3d3869Ted Kremenek
3999c378f705405d37f49795d5e915989de774fe11fTed KremenekSVal StoreManager::getLValueFieldOrIvar(const Decl *D, SVal Base) {
400c1511e04998e685c9e030323e248363b9633267dZhongxing Xu  if (Base.isUnknownOrUndef())
401c1511e04998e685c9e030323e248363b9633267dZhongxing Xu    return Base;
402c1511e04998e685c9e030323e248363b9633267dZhongxing Xu
4035251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie  Loc BaseL = Base.castAs<Loc>();
4046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  const MemRegion* BaseR = nullptr;
405c1511e04998e685c9e030323e248363b9633267dZhongxing Xu
406c1511e04998e685c9e030323e248363b9633267dZhongxing Xu  switch (BaseL.getSubKind()) {
407c1511e04998e685c9e030323e248363b9633267dZhongxing Xu  case loc::MemRegionKind:
4085251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie    BaseR = BaseL.castAs<loc::MemRegionVal>().getRegion();
409c1511e04998e685c9e030323e248363b9633267dZhongxing Xu    break;
410c1511e04998e685c9e030323e248363b9633267dZhongxing Xu
411c1511e04998e685c9e030323e248363b9633267dZhongxing Xu  case loc::GotoLabelKind:
412c1511e04998e685c9e030323e248363b9633267dZhongxing Xu    // These are anormal cases. Flag an undefined value.
413c1511e04998e685c9e030323e248363b9633267dZhongxing Xu    return UndefinedVal();
414c1511e04998e685c9e030323e248363b9633267dZhongxing Xu
415c1511e04998e685c9e030323e248363b9633267dZhongxing Xu  case loc::ConcreteIntKind:
416c1511e04998e685c9e030323e248363b9633267dZhongxing Xu    // While these seem funny, this can happen through casts.
417c1511e04998e685c9e030323e248363b9633267dZhongxing Xu    // FIXME: What we should return is the field offset.  For example,
418c1511e04998e685c9e030323e248363b9633267dZhongxing Xu    //  add the field offset to the integer value.  That way funny things
419c1511e04998e685c9e030323e248363b9633267dZhongxing Xu    //  like this work properly:  &(((struct foo *) 0xa)->f)
420c1511e04998e685c9e030323e248363b9633267dZhongxing Xu    return Base;
421c1511e04998e685c9e030323e248363b9633267dZhongxing Xu
422c1511e04998e685c9e030323e248363b9633267dZhongxing Xu  default:
423b219cfc4d75f0a03630b7c4509ef791b7e97b2c8David Blaikie    llvm_unreachable("Unhandled Base.");
424c1511e04998e685c9e030323e248363b9633267dZhongxing Xu  }
425c1511e04998e685c9e030323e248363b9633267dZhongxing Xu
426c1511e04998e685c9e030323e248363b9633267dZhongxing Xu  // NOTE: We must have this check first because ObjCIvarDecl is a subclass
427c1511e04998e685c9e030323e248363b9633267dZhongxing Xu  // of FieldDecl.
428c1511e04998e685c9e030323e248363b9633267dZhongxing Xu  if (const ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(D))
429c1511e04998e685c9e030323e248363b9633267dZhongxing Xu    return loc::MemRegionVal(MRMgr.getObjCIvarRegion(ID, BaseR));
430c1511e04998e685c9e030323e248363b9633267dZhongxing Xu
431c1511e04998e685c9e030323e248363b9633267dZhongxing Xu  return loc::MemRegionVal(MRMgr.getFieldRegion(cast<FieldDecl>(D), BaseR));
432c1511e04998e685c9e030323e248363b9633267dZhongxing Xu}
43352535688b1339e0b3898ac0d670052482851a3abZhongxing Xu
434c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin KramerSVal StoreManager::getLValueIvar(const ObjCIvarDecl *decl, SVal base) {
435c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer  return getLValueFieldOrIvar(decl, base);
436c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer}
437c35fb7d67d515659ad2325b4f6ec97c9fe64fb63Benjamin Kramer
43802282acd7a42d06a3178e3102d34a585bd82dd9fTed KremenekSVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
43952535688b1339e0b3898ac0d670052482851a3abZhongxing Xu                                    SVal Base) {
44052535688b1339e0b3898ac0d670052482851a3abZhongxing Xu
44152535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  // If the base is an unknown or undefined value, just return it back.
44252535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  // FIXME: For absolute pointer addresses, we just return that value back as
44352535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  //  well, although in reality we should return the offset added to that
44452535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  //  value.
4455251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie  if (Base.isUnknownOrUndef() || Base.getAs<loc::ConcreteInt>())
44652535688b1339e0b3898ac0d670052482851a3abZhongxing Xu    return Base;
44752535688b1339e0b3898ac0d670052482851a3abZhongxing Xu
4485251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie  const MemRegion* BaseRegion = Base.castAs<loc::MemRegionVal>().getRegion();
44952535688b1339e0b3898ac0d670052482851a3abZhongxing Xu
45052535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  // Pointer of any type can be cast and used as array base.
45152535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion);
45252535688b1339e0b3898ac0d670052482851a3abZhongxing Xu
45352535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  // Convert the offset to the appropriate size and signedness.
4545251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie  Offset = svalBuilder.convertToArrayIndex(Offset).castAs<NonLoc>();
45552535688b1339e0b3898ac0d670052482851a3abZhongxing Xu
45652535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  if (!ElemR) {
45752535688b1339e0b3898ac0d670052482851a3abZhongxing Xu    //
45852535688b1339e0b3898ac0d670052482851a3abZhongxing Xu    // If the base region is not an ElementRegion, create one.
45952535688b1339e0b3898ac0d670052482851a3abZhongxing Xu    // This can happen in the following example:
46052535688b1339e0b3898ac0d670052482851a3abZhongxing Xu    //
46152535688b1339e0b3898ac0d670052482851a3abZhongxing Xu    //   char *p = __builtin_alloc(10);
46252535688b1339e0b3898ac0d670052482851a3abZhongxing Xu    //   p[1] = 8;
46352535688b1339e0b3898ac0d670052482851a3abZhongxing Xu    //
46452535688b1339e0b3898ac0d670052482851a3abZhongxing Xu    //  Observe that 'p' binds to an AllocaRegion.
46552535688b1339e0b3898ac0d670052482851a3abZhongxing Xu    //
46652535688b1339e0b3898ac0d670052482851a3abZhongxing Xu    return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
46752535688b1339e0b3898ac0d670052482851a3abZhongxing Xu                                                    BaseRegion, Ctx));
46852535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  }
46952535688b1339e0b3898ac0d670052482851a3abZhongxing Xu
47052535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  SVal BaseIdx = ElemR->getIndex();
47152535688b1339e0b3898ac0d670052482851a3abZhongxing Xu
4725251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie  if (!BaseIdx.getAs<nonloc::ConcreteInt>())
47352535688b1339e0b3898ac0d670052482851a3abZhongxing Xu    return UnknownVal();
47452535688b1339e0b3898ac0d670052482851a3abZhongxing Xu
4755251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie  const llvm::APSInt &BaseIdxI =
4765251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie      BaseIdx.castAs<nonloc::ConcreteInt>().getValue();
477e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose
478e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose  // Only allow non-integer offsets if the base region has no offset itself.
479e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose  // FIXME: This is a somewhat arbitrary restriction. We should be using
480846eabd187be4bfe992e8bca131166b734d86e0dTed Kremenek  // SValBuilder here to add the two offsets without checking their types.
4815251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie  if (!Offset.getAs<nonloc::ConcreteInt>()) {
482e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose    if (isa<ElementRegion>(BaseRegion->StripCasts()))
483e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose      return UnknownVal();
484e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose
485e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose    return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
486e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose                                                    ElemR->getSuperRegion(),
487e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose                                                    Ctx));
488e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose  }
489e701117b21356d3c60133315b5bdd50232ec6ccaJordy Rose
4905251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie  const llvm::APSInt& OffI = Offset.castAs<nonloc::ConcreteInt>().getValue();
49152535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  assert(BaseIdxI.isSigned());
49252535688b1339e0b3898ac0d670052482851a3abZhongxing Xu
49352535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  // Compute the new index.
494c8413fd03f73084a5c93028f8b4db619fc388087Ted Kremenek  nonloc::ConcreteInt NewIdx(svalBuilder.getBasicValueFactory().getValue(BaseIdxI +
49502282acd7a42d06a3178e3102d34a585bd82dd9fTed Kremenek                                                                    OffI));
49652535688b1339e0b3898ac0d670052482851a3abZhongxing Xu
49752535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  // Construct the new ElementRegion.
49852535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  const MemRegion *ArrayR = ElemR->getSuperRegion();
49952535688b1339e0b3898ac0d670052482851a3abZhongxing Xu  return loc::MemRegionVal(MRMgr.getElementRegion(elementType, NewIdx, ArrayR,
50052535688b1339e0b3898ac0d670052482851a3abZhongxing Xu                                                  Ctx));
50152535688b1339e0b3898ac0d670052482851a3abZhongxing Xu}
502a4c7a4314ffbe402091695874e93d9b0a79c8099Ted Kremenek
503a4c7a4314ffbe402091695874e93d9b0a79c8099Ted KremenekStoreManager::BindingsHandler::~BindingsHandler() {}
504a4c7a4314ffbe402091695874e93d9b0a79c8099Ted Kremenek
50527b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaksbool StoreManager::FindUniqueBinding::HandleBinding(StoreManager& SMgr,
50627b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks                                                    Store store,
50727b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks                                                    const MemRegion* R,
50827b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks                                                    SVal val) {
50927b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks  SymbolRef SymV = val.getAsLocSymbol();
51027b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks  if (!SymV || SymV != Sym)
51127b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks    return true;
51227b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks
51327b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks  if (Binding) {
51427b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks    First = false;
51527b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks    return false;
51627b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks  }
51727b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks  else
51827b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks    Binding = R;
51927b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks
52027b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks  return true;
52127b867ea1c9cb4b40f9b817c303d6df3ee753da9Anna Zaks}
522