Store.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. //===- Store.cpp - Interface for maps from Locations to Values ------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This file defined the types Store and StoreManager.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h"
  13. #include "clang/AST/ASTContext.h"
  14. #include "clang/AST/CXXInheritance.h"
  15. #include "clang/AST/CharUnits.h"
  16. #include "clang/AST/Decl.h"
  17. #include "clang/AST/DeclCXX.h"
  18. #include "clang/AST/DeclObjC.h"
  19. #include "clang/AST/Expr.h"
  20. #include "clang/AST/Type.h"
  21. #include "clang/Basic/LLVM.h"
  22. #include "clang/StaticAnalyzer/Core/PathSensitive/BasicValueFactory.h"
  23. #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
  24. #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
  25. #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
  26. #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
  27. #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
  28. #include "clang/StaticAnalyzer/Core/PathSensitive/StoreRef.h"
  29. #include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
  30. #include "llvm/ADT/APSInt.h"
  31. #include "llvm/ADT/Optional.h"
  32. #include "llvm/ADT/SmallVector.h"
  33. #include "llvm/Support/Casting.h"
  34. #include "llvm/Support/ErrorHandling.h"
  35. #include <cassert>
  36. #include <cstdint>
  37. using namespace clang;
  38. using namespace ento;
  39. StoreManager::StoreManager(ProgramStateManager &stateMgr)
  40. : svalBuilder(stateMgr.getSValBuilder()), StateMgr(stateMgr),
  41. MRMgr(svalBuilder.getRegionManager()), Ctx(stateMgr.getContext()) {}
  42. StoreRef StoreManager::enterStackFrame(Store OldStore,
  43. const CallEvent &Call,
  44. const StackFrameContext *LCtx) {
  45. StoreRef Store = StoreRef(OldStore, *this);
  46. SmallVector<CallEvent::FrameBindingTy, 16> InitialBindings;
  47. Call.getInitialStackFrameContents(LCtx, InitialBindings);
  48. for (const auto &I : InitialBindings)
  49. Store = Bind(Store.getStore(), I.first.castAs<Loc>(), I.second);
  50. return Store;
  51. }
  52. const ElementRegion *StoreManager::MakeElementRegion(const SubRegion *Base,
  53. QualType EleTy,
  54. uint64_t index) {
  55. NonLoc idx = svalBuilder.makeArrayIndex(index);
  56. return MRMgr.getElementRegion(EleTy, idx, Base, svalBuilder.getContext());
  57. }
  58. const ElementRegion *StoreManager::GetElementZeroRegion(const SubRegion *R,
  59. QualType T) {
  60. NonLoc idx = svalBuilder.makeZeroArrayIndex();
  61. assert(!T.isNull());
  62. return MRMgr.getElementRegion(T, idx, R, Ctx);
  63. }
  64. const MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy) {
  65. ASTContext &Ctx = StateMgr.getContext();
  66. // Handle casts to Objective-C objects.
  67. if (CastToTy->isObjCObjectPointerType())
  68. return R->StripCasts();
  69. if (CastToTy->isBlockPointerType()) {
  70. // FIXME: We may need different solutions, depending on the symbol
  71. // involved. Blocks can be casted to/from 'id', as they can be treated
  72. // as Objective-C objects. This could possibly be handled by enhancing
  73. // our reasoning of downcasts of symbolic objects.
  74. if (isa<CodeTextRegion>(R) || isa<SymbolicRegion>(R))
  75. return R;
  76. // We don't know what to make of it. Return a NULL region, which
  77. // will be interpreted as UnknownVal.
  78. return nullptr;
  79. }
  80. // Now assume we are casting from pointer to pointer. Other cases should
  81. // already be handled.
  82. QualType PointeeTy = CastToTy->getPointeeType();
  83. QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy);
  84. // Handle casts to void*. We just pass the region through.
  85. if (CanonPointeeTy.getLocalUnqualifiedType() == Ctx.VoidTy)
  86. return R;
  87. // Handle casts from compatible types.
  88. if (R->isBoundable())
  89. if (const auto *TR = dyn_cast<TypedValueRegion>(R)) {
  90. QualType ObjTy = Ctx.getCanonicalType(TR->getValueType());
  91. if (CanonPointeeTy == ObjTy)
  92. return R;
  93. }
  94. // Process region cast according to the kind of the region being cast.
  95. switch (R->getKind()) {
  96. case MemRegion::CXXThisRegionKind:
  97. case MemRegion::CodeSpaceRegionKind:
  98. case MemRegion::StackLocalsSpaceRegionKind:
  99. case MemRegion::StackArgumentsSpaceRegionKind:
  100. case MemRegion::HeapSpaceRegionKind:
  101. case MemRegion::UnknownSpaceRegionKind:
  102. case MemRegion::StaticGlobalSpaceRegionKind:
  103. case MemRegion::GlobalInternalSpaceRegionKind:
  104. case MemRegion::GlobalSystemSpaceRegionKind:
  105. case MemRegion::GlobalImmutableSpaceRegionKind: {
  106. llvm_unreachable("Invalid region cast");
  107. }
  108. case MemRegion::FunctionCodeRegionKind:
  109. case MemRegion::BlockCodeRegionKind:
  110. case MemRegion::BlockDataRegionKind:
  111. case MemRegion::StringRegionKind:
  112. // FIXME: Need to handle arbitrary downcasts.
  113. case MemRegion::SymbolicRegionKind:
  114. case MemRegion::AllocaRegionKind:
  115. case MemRegion::CompoundLiteralRegionKind:
  116. case MemRegion::FieldRegionKind:
  117. case MemRegion::ObjCIvarRegionKind:
  118. case MemRegion::ObjCStringRegionKind:
  119. case MemRegion::VarRegionKind:
  120. case MemRegion::CXXTempObjectRegionKind:
  121. case MemRegion::CXXBaseObjectRegionKind:
  122. case MemRegion::CXXDerivedObjectRegionKind:
  123. return MakeElementRegion(cast<SubRegion>(R), PointeeTy);
  124. case MemRegion::ElementRegionKind: {
  125. // If we are casting from an ElementRegion to another type, the
  126. // algorithm is as follows:
  127. //
  128. // (1) Compute the "raw offset" of the ElementRegion from the
  129. // base region. This is done by calling 'getAsRawOffset()'.
  130. //
  131. // (2a) If we get a 'RegionRawOffset' after calling
  132. // 'getAsRawOffset()', determine if the absolute offset
  133. // can be exactly divided into chunks of the size of the
  134. // casted-pointee type. If so, create a new ElementRegion with
  135. // the pointee-cast type as the new ElementType and the index
  136. // being the offset divded by the chunk size. If not, create
  137. // a new ElementRegion at offset 0 off the raw offset region.
  138. //
  139. // (2b) If we don't a get a 'RegionRawOffset' after calling
  140. // 'getAsRawOffset()', it means that we are at offset 0.
  141. //
  142. // FIXME: Handle symbolic raw offsets.
  143. const ElementRegion *elementR = cast<ElementRegion>(R);
  144. const RegionRawOffset &rawOff = elementR->getAsArrayOffset();
  145. const MemRegion *baseR = rawOff.getRegion();
  146. // If we cannot compute a raw offset, throw up our hands and return
  147. // a NULL MemRegion*.
  148. if (!baseR)
  149. return nullptr;
  150. CharUnits off = rawOff.getOffset();
  151. if (off.isZero()) {
  152. // Edge case: we are at 0 bytes off the beginning of baseR. We
  153. // check to see if type we are casting to is the same as the base
  154. // region. If so, just return the base region.
  155. if (const auto *TR = dyn_cast<TypedValueRegion>(baseR)) {
  156. QualType ObjTy = Ctx.getCanonicalType(TR->getValueType());
  157. QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy);
  158. if (CanonPointeeTy == ObjTy)
  159. return baseR;
  160. }
  161. // Otherwise, create a new ElementRegion at offset 0.
  162. return MakeElementRegion(cast<SubRegion>(baseR), PointeeTy);
  163. }
  164. // We have a non-zero offset from the base region. We want to determine
  165. // if the offset can be evenly divided by sizeof(PointeeTy). If so,
  166. // we create an ElementRegion whose index is that value. Otherwise, we
  167. // create two ElementRegions, one that reflects a raw offset and the other
  168. // that reflects the cast.
  169. // Compute the index for the new ElementRegion.
  170. int64_t newIndex = 0;
  171. const MemRegion *newSuperR = nullptr;
  172. // We can only compute sizeof(PointeeTy) if it is a complete type.
  173. if (!PointeeTy->isIncompleteType()) {
  174. // Compute the size in **bytes**.
  175. CharUnits pointeeTySize = Ctx.getTypeSizeInChars(PointeeTy);
  176. if (!pointeeTySize.isZero()) {
  177. // Is the offset a multiple of the size? If so, we can layer the
  178. // ElementRegion (with elementType == PointeeTy) directly on top of
  179. // the base region.
  180. if (off % pointeeTySize == 0) {
  181. newIndex = off / pointeeTySize;
  182. newSuperR = baseR;
  183. }
  184. }
  185. }
  186. if (!newSuperR) {
  187. // Create an intermediate ElementRegion to represent the raw byte.
  188. // This will be the super region of the final ElementRegion.
  189. newSuperR = MakeElementRegion(cast<SubRegion>(baseR), Ctx.CharTy,
  190. off.getQuantity());
  191. }
  192. return MakeElementRegion(cast<SubRegion>(newSuperR), PointeeTy, newIndex);
  193. }
  194. }
  195. llvm_unreachable("unreachable");
  196. }
  197. static bool regionMatchesCXXRecordType(SVal V, QualType Ty) {
  198. const MemRegion *MR = V.getAsRegion();
  199. if (!MR)
  200. return true;
  201. const auto *TVR = dyn_cast<TypedValueRegion>(MR);
  202. if (!TVR)
  203. return true;
  204. const CXXRecordDecl *RD = TVR->getValueType()->getAsCXXRecordDecl();
  205. if (!RD)
  206. return true;
  207. const CXXRecordDecl *Expected = Ty->getPointeeCXXRecordDecl();
  208. if (!Expected)
  209. Expected = Ty->getAsCXXRecordDecl();
  210. return Expected->getCanonicalDecl() == RD->getCanonicalDecl();
  211. }
  212. SVal StoreManager::evalDerivedToBase(SVal Derived, const CastExpr *Cast) {
  213. // Sanity check to avoid doing the wrong thing in the face of
  214. // reinterpret_cast.
  215. if (!regionMatchesCXXRecordType(Derived, Cast->getSubExpr()->getType()))
  216. return UnknownVal();
  217. // Walk through the cast path to create nested CXXBaseRegions.
  218. SVal Result = Derived;
  219. for (CastExpr::path_const_iterator I = Cast->path_begin(),
  220. E = Cast->path_end();
  221. I != E; ++I) {
  222. Result = evalDerivedToBase(Result, (*I)->getType(), (*I)->isVirtual());
  223. }
  224. return Result;
  225. }
  226. SVal StoreManager::evalDerivedToBase(SVal Derived, const CXXBasePath &Path) {
  227. // Walk through the path to create nested CXXBaseRegions.
  228. SVal Result = Derived;
  229. for (const auto &I : Path)
  230. Result = evalDerivedToBase(Result, I.Base->getType(),
  231. I.Base->isVirtual());
  232. return Result;
  233. }
  234. SVal StoreManager::evalDerivedToBase(SVal Derived, QualType BaseType,
  235. bool IsVirtual) {
  236. const MemRegion *DerivedReg = Derived.getAsRegion();
  237. if (!DerivedReg)
  238. return Derived;
  239. const CXXRecordDecl *BaseDecl = BaseType->getPointeeCXXRecordDecl();
  240. if (!BaseDecl)
  241. BaseDecl = BaseType->getAsCXXRecordDecl();
  242. assert(BaseDecl && "not a C++ object?");
  243. if (const auto *AlreadyDerivedReg =
  244. dyn_cast<CXXDerivedObjectRegion>(DerivedReg)) {
  245. if (const auto *SR =
  246. dyn_cast<SymbolicRegion>(AlreadyDerivedReg->getSuperRegion()))
  247. if (SR->getSymbol()->getType()->getPointeeCXXRecordDecl() == BaseDecl)
  248. return loc::MemRegionVal(SR);
  249. DerivedReg = AlreadyDerivedReg->getSuperRegion();
  250. }
  251. const MemRegion *BaseReg = MRMgr.getCXXBaseObjectRegion(
  252. BaseDecl, cast<SubRegion>(DerivedReg), IsVirtual);
  253. return loc::MemRegionVal(BaseReg);
  254. }
  255. /// Returns the static type of the given region, if it represents a C++ class
  256. /// object.
  257. ///
  258. /// This handles both fully-typed regions, where the dynamic type is known, and
  259. /// symbolic regions, where the dynamic type is merely bounded (and even then,
  260. /// only ostensibly!), but does not take advantage of any dynamic type info.
  261. static const CXXRecordDecl *getCXXRecordType(const MemRegion *MR) {
  262. if (const auto *TVR = dyn_cast<TypedValueRegion>(MR))
  263. return TVR->getValueType()->getAsCXXRecordDecl();
  264. if (const auto *SR = dyn_cast<SymbolicRegion>(MR))
  265. return SR->getSymbol()->getType()->getPointeeCXXRecordDecl();
  266. return nullptr;
  267. }
  268. SVal StoreManager::attemptDownCast(SVal Base, QualType TargetType,
  269. bool &Failed) {
  270. Failed = false;
  271. const MemRegion *MR = Base.getAsRegion();
  272. if (!MR)
  273. return UnknownVal();
  274. // Assume the derived class is a pointer or a reference to a CXX record.
  275. TargetType = TargetType->getPointeeType();
  276. assert(!TargetType.isNull());
  277. const CXXRecordDecl *TargetClass = TargetType->getAsCXXRecordDecl();
  278. if (!TargetClass && !TargetType->isVoidType())
  279. return UnknownVal();
  280. // Drill down the CXXBaseObject chains, which represent upcasts (casts from
  281. // derived to base).
  282. while (const CXXRecordDecl *MRClass = getCXXRecordType(MR)) {
  283. // If found the derived class, the cast succeeds.
  284. if (MRClass == TargetClass)
  285. return loc::MemRegionVal(MR);
  286. // We skip over incomplete types. They must be the result of an earlier
  287. // reinterpret_cast, as one can only dynamic_cast between types in the same
  288. // class hierarchy.
  289. if (!TargetType->isVoidType() && MRClass->hasDefinition()) {
  290. // Static upcasts are marked as DerivedToBase casts by Sema, so this will
  291. // only happen when multiple or virtual inheritance is involved.
  292. CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true,
  293. /*DetectVirtual=*/false);
  294. if (MRClass->isDerivedFrom(TargetClass, Paths))
  295. return evalDerivedToBase(loc::MemRegionVal(MR), Paths.front());
  296. }
  297. if (const auto *BaseR = dyn_cast<CXXBaseObjectRegion>(MR)) {
  298. // Drill down the chain to get the derived classes.
  299. MR = BaseR->getSuperRegion();
  300. continue;
  301. }
  302. // If this is a cast to void*, return the region.
  303. if (TargetType->isVoidType())
  304. return loc::MemRegionVal(MR);
  305. // Strange use of reinterpret_cast can give us paths we don't reason
  306. // about well, by putting in ElementRegions where we'd expect
  307. // CXXBaseObjectRegions. If it's a valid reinterpret_cast (i.e. if the
  308. // derived class has a zero offset from the base class), then it's safe
  309. // to strip the cast; if it's invalid, -Wreinterpret-base-class should
  310. // catch it. In the interest of performance, the analyzer will silently
  311. // do the wrong thing in the invalid case (because offsets for subregions
  312. // will be wrong).
  313. const MemRegion *Uncasted = MR->StripCasts(/*IncludeBaseCasts=*/false);
  314. if (Uncasted == MR) {
  315. // We reached the bottom of the hierarchy and did not find the derived
  316. // class. We must be casting the base to derived, so the cast should
  317. // fail.
  318. break;
  319. }
  320. MR = Uncasted;
  321. }
  322. // If we're casting a symbolic base pointer to a derived class, use
  323. // CXXDerivedObjectRegion to represent the cast. If it's a pointer to an
  324. // unrelated type, it must be a weird reinterpret_cast and we have to
  325. // be fine with ElementRegion. TODO: Should we instead make
  326. // Derived{TargetClass, Element{SourceClass, SR}}?
  327. if (const auto *SR = dyn_cast<SymbolicRegion>(MR)) {
  328. QualType T = SR->getSymbol()->getType();
  329. const CXXRecordDecl *SourceClass = T->getPointeeCXXRecordDecl();
  330. if (TargetClass && SourceClass && TargetClass->isDerivedFrom(SourceClass))
  331. return loc::MemRegionVal(
  332. MRMgr.getCXXDerivedObjectRegion(TargetClass, SR));
  333. return loc::MemRegionVal(GetElementZeroRegion(SR, TargetType));
  334. }
  335. // We failed if the region we ended up with has perfect type info.
  336. Failed = isa<TypedValueRegion>(MR);
  337. return UnknownVal();
  338. }
  339. /// CastRetrievedVal - Used by subclasses of StoreManager to implement
  340. /// implicit casts that arise from loads from regions that are reinterpreted
  341. /// as another region.
  342. SVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R,
  343. QualType castTy) {
  344. if (castTy.isNull() || V.isUnknownOrUndef())
  345. return V;
  346. // The dispatchCast() call below would convert the int into a float.
  347. // What we want, however, is a bit-by-bit reinterpretation of the int
  348. // as a float, which usually yields nothing garbage. For now skip casts
  349. // from ints to floats.
  350. // TODO: What other combinations of types are affected?
  351. if (castTy->isFloatingType()) {
  352. SymbolRef Sym = V.getAsSymbol();
  353. if (Sym && !Sym->getType()->isFloatingType())
  354. return UnknownVal();
  355. }
  356. // When retrieving symbolic pointer and expecting a non-void pointer,
  357. // wrap them into element regions of the expected type if necessary.
  358. // SValBuilder::dispatchCast() doesn't do that, but it is necessary to
  359. // make sure that the retrieved value makes sense, because there's no other
  360. // cast in the AST that would tell us to cast it to the correct pointer type.
  361. // We might need to do that for non-void pointers as well.
  362. // FIXME: We really need a single good function to perform casts for us
  363. // correctly every time we need it.
  364. if (castTy->isPointerType() && !castTy->isVoidPointerType())
  365. if (const auto *SR = dyn_cast_or_null<SymbolicRegion>(V.getAsRegion()))
  366. if (SR->getSymbol()->getType().getCanonicalType() !=
  367. castTy.getCanonicalType())
  368. return loc::MemRegionVal(castRegion(SR, castTy));
  369. return svalBuilder.dispatchCast(V, castTy);
  370. }
  371. SVal StoreManager::getLValueFieldOrIvar(const Decl *D, SVal Base) {
  372. if (Base.isUnknownOrUndef())
  373. return Base;
  374. Loc BaseL = Base.castAs<Loc>();
  375. const SubRegion* BaseR = nullptr;
  376. switch (BaseL.getSubKind()) {
  377. case loc::MemRegionValKind:
  378. BaseR = cast<SubRegion>(BaseL.castAs<loc::MemRegionVal>().getRegion());
  379. break;
  380. case loc::GotoLabelKind:
  381. // These are anormal cases. Flag an undefined value.
  382. return UndefinedVal();
  383. case loc::ConcreteIntKind:
  384. // While these seem funny, this can happen through casts.
  385. // FIXME: What we should return is the field offset, not base. For example,
  386. // add the field offset to the integer value. That way things
  387. // like this work properly: &(((struct foo *) 0xa)->f)
  388. // However, that's not easy to fix without reducing our abilities
  389. // to catch null pointer dereference. Eg., ((struct foo *)0x0)->f = 7
  390. // is a null dereference even though we're dereferencing offset of f
  391. // rather than null. Coming up with an approach that computes offsets
  392. // over null pointers properly while still being able to catch null
  393. // dereferences might be worth it.
  394. return Base;
  395. default:
  396. llvm_unreachable("Unhandled Base.");
  397. }
  398. // NOTE: We must have this check first because ObjCIvarDecl is a subclass
  399. // of FieldDecl.
  400. if (const auto *ID = dyn_cast<ObjCIvarDecl>(D))
  401. return loc::MemRegionVal(MRMgr.getObjCIvarRegion(ID, BaseR));
  402. return loc::MemRegionVal(MRMgr.getFieldRegion(cast<FieldDecl>(D), BaseR));
  403. }
  404. SVal StoreManager::getLValueIvar(const ObjCIvarDecl *decl, SVal base) {
  405. return getLValueFieldOrIvar(decl, base);
  406. }
  407. SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset,
  408. SVal Base) {
  409. // If the base is an unknown or undefined value, just return it back.
  410. // FIXME: For absolute pointer addresses, we just return that value back as
  411. // well, although in reality we should return the offset added to that
  412. // value. See also the similar FIXME in getLValueFieldOrIvar().
  413. if (Base.isUnknownOrUndef() || Base.getAs<loc::ConcreteInt>())
  414. return Base;
  415. if (Base.getAs<loc::GotoLabel>())
  416. return UnknownVal();
  417. const SubRegion *BaseRegion =
  418. Base.castAs<loc::MemRegionVal>().getRegionAs<SubRegion>();
  419. // Pointer of any type can be cast and used as array base.
  420. const auto *ElemR = dyn_cast<ElementRegion>(BaseRegion);
  421. // Convert the offset to the appropriate size and signedness.
  422. Offset = svalBuilder.convertToArrayIndex(Offset).castAs<NonLoc>();
  423. if (!ElemR) {
  424. // If the base region is not an ElementRegion, create one.
  425. // This can happen in the following example:
  426. //
  427. // char *p = __builtin_alloc(10);
  428. // p[1] = 8;
  429. //
  430. // Observe that 'p' binds to an AllocaRegion.
  431. return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset,
  432. BaseRegion, Ctx));
  433. }
  434. SVal BaseIdx = ElemR->getIndex();
  435. if (!BaseIdx.getAs<nonloc::ConcreteInt>())
  436. return UnknownVal();
  437. const llvm::APSInt &BaseIdxI =
  438. BaseIdx.castAs<nonloc::ConcreteInt>().getValue();
  439. // Only allow non-integer offsets if the base region has no offset itself.
  440. // FIXME: This is a somewhat arbitrary restriction. We should be using
  441. // SValBuilder here to add the two offsets without checking their types.
  442. if (!Offset.getAs<nonloc::ConcreteInt>()) {
  443. if (isa<ElementRegion>(BaseRegion->StripCasts()))
  444. return UnknownVal();
  445. return loc::MemRegionVal(MRMgr.getElementRegion(
  446. elementType, Offset, cast<SubRegion>(ElemR->getSuperRegion()), Ctx));
  447. }
  448. const llvm::APSInt& OffI = Offset.castAs<nonloc::ConcreteInt>().getValue();
  449. assert(BaseIdxI.isSigned());
  450. // Compute the new index.
  451. nonloc::ConcreteInt NewIdx(svalBuilder.getBasicValueFactory().getValue(BaseIdxI +
  452. OffI));
  453. // Construct the new ElementRegion.
  454. const SubRegion *ArrayR = cast<SubRegion>(ElemR->getSuperRegion());
  455. return loc::MemRegionVal(MRMgr.getElementRegion(elementType, NewIdx, ArrayR,
  456. Ctx));
  457. }
  458. StoreManager::BindingsHandler::~BindingsHandler() = default;
  459. bool StoreManager::FindUniqueBinding::HandleBinding(StoreManager& SMgr,
  460. Store store,
  461. const MemRegion* R,
  462. SVal val) {
  463. SymbolRef SymV = val.getAsLocSymbol();
  464. if (!SymV || SymV != Sym)
  465. return true;
  466. if (Binding) {
  467. First = false;
  468. return false;
  469. }
  470. else
  471. Binding = R;
  472. return true;
  473. }