Store.cpp 19 KB

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