Store.cpp 17 KB

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