clang API Documentation
00001 //== Store.cpp - Interface for maps from Locations to Values ----*- C++ -*--==// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defined the types Store and StoreManager. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "clang/StaticAnalyzer/Core/PathSensitive/Store.h" 00015 #include "clang/AST/CXXInheritance.h" 00016 #include "clang/AST/CharUnits.h" 00017 #include "clang/AST/DeclObjC.h" 00018 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" 00019 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h" 00020 00021 using namespace clang; 00022 using namespace ento; 00023 00024 StoreManager::StoreManager(ProgramStateManager &stateMgr) 00025 : svalBuilder(stateMgr.getSValBuilder()), StateMgr(stateMgr), 00026 MRMgr(svalBuilder.getRegionManager()), Ctx(stateMgr.getContext()) {} 00027 00028 StoreRef StoreManager::enterStackFrame(Store OldStore, 00029 const CallEvent &Call, 00030 const StackFrameContext *LCtx) { 00031 StoreRef Store = StoreRef(OldStore, *this); 00032 00033 SmallVector<CallEvent::FrameBindingTy, 16> InitialBindings; 00034 Call.getInitialStackFrameContents(LCtx, InitialBindings); 00035 00036 for (CallEvent::BindingsTy::iterator I = InitialBindings.begin(), 00037 E = InitialBindings.end(); 00038 I != E; ++I) { 00039 Store = Bind(Store.getStore(), I->first, I->second); 00040 } 00041 00042 return Store; 00043 } 00044 00045 const MemRegion *StoreManager::MakeElementRegion(const MemRegion *Base, 00046 QualType EleTy, uint64_t index) { 00047 NonLoc idx = svalBuilder.makeArrayIndex(index); 00048 return MRMgr.getElementRegion(EleTy, idx, Base, svalBuilder.getContext()); 00049 } 00050 00051 StoreRef StoreManager::BindDefault(Store store, const MemRegion *R, SVal V) { 00052 return StoreRef(store, *this); 00053 } 00054 00055 const ElementRegion *StoreManager::GetElementZeroRegion(const MemRegion *R, 00056 QualType T) { 00057 NonLoc idx = svalBuilder.makeZeroArrayIndex(); 00058 assert(!T.isNull()); 00059 return MRMgr.getElementRegion(T, idx, R, Ctx); 00060 } 00061 00062 const MemRegion *StoreManager::castRegion(const MemRegion *R, QualType CastToTy) { 00063 00064 ASTContext &Ctx = StateMgr.getContext(); 00065 00066 // Handle casts to Objective-C objects. 00067 if (CastToTy->isObjCObjectPointerType()) 00068 return R->StripCasts(); 00069 00070 if (CastToTy->isBlockPointerType()) { 00071 // FIXME: We may need different solutions, depending on the symbol 00072 // involved. Blocks can be casted to/from 'id', as they can be treated 00073 // as Objective-C objects. This could possibly be handled by enhancing 00074 // our reasoning of downcasts of symbolic objects. 00075 if (isa<CodeTextRegion>(R) || isa<SymbolicRegion>(R)) 00076 return R; 00077 00078 // We don't know what to make of it. Return a NULL region, which 00079 // will be interpretted as UnknownVal. 00080 return nullptr; 00081 } 00082 00083 // Now assume we are casting from pointer to pointer. Other cases should 00084 // already be handled. 00085 QualType PointeeTy = CastToTy->getPointeeType(); 00086 QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy); 00087 00088 // Handle casts to void*. We just pass the region through. 00089 if (CanonPointeeTy.getLocalUnqualifiedType() == Ctx.VoidTy) 00090 return R; 00091 00092 // Handle casts from compatible types. 00093 if (R->isBoundable()) 00094 if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) { 00095 QualType ObjTy = Ctx.getCanonicalType(TR->getValueType()); 00096 if (CanonPointeeTy == ObjTy) 00097 return R; 00098 } 00099 00100 // Process region cast according to the kind of the region being cast. 00101 switch (R->getKind()) { 00102 case MemRegion::CXXThisRegionKind: 00103 case MemRegion::GenericMemSpaceRegionKind: 00104 case MemRegion::StackLocalsSpaceRegionKind: 00105 case MemRegion::StackArgumentsSpaceRegionKind: 00106 case MemRegion::HeapSpaceRegionKind: 00107 case MemRegion::UnknownSpaceRegionKind: 00108 case MemRegion::StaticGlobalSpaceRegionKind: 00109 case MemRegion::GlobalInternalSpaceRegionKind: 00110 case MemRegion::GlobalSystemSpaceRegionKind: 00111 case MemRegion::GlobalImmutableSpaceRegionKind: { 00112 llvm_unreachable("Invalid region cast"); 00113 } 00114 00115 case MemRegion::FunctionTextRegionKind: 00116 case MemRegion::BlockTextRegionKind: 00117 case MemRegion::BlockDataRegionKind: 00118 case MemRegion::StringRegionKind: 00119 // FIXME: Need to handle arbitrary downcasts. 00120 case MemRegion::SymbolicRegionKind: 00121 case MemRegion::AllocaRegionKind: 00122 case MemRegion::CompoundLiteralRegionKind: 00123 case MemRegion::FieldRegionKind: 00124 case MemRegion::ObjCIvarRegionKind: 00125 case MemRegion::ObjCStringRegionKind: 00126 case MemRegion::VarRegionKind: 00127 case MemRegion::CXXTempObjectRegionKind: 00128 case MemRegion::CXXBaseObjectRegionKind: 00129 return MakeElementRegion(R, PointeeTy); 00130 00131 case MemRegion::ElementRegionKind: { 00132 // If we are casting from an ElementRegion to another type, the 00133 // algorithm is as follows: 00134 // 00135 // (1) Compute the "raw offset" of the ElementRegion from the 00136 // base region. This is done by calling 'getAsRawOffset()'. 00137 // 00138 // (2a) If we get a 'RegionRawOffset' after calling 00139 // 'getAsRawOffset()', determine if the absolute offset 00140 // can be exactly divided into chunks of the size of the 00141 // casted-pointee type. If so, create a new ElementRegion with 00142 // the pointee-cast type as the new ElementType and the index 00143 // being the offset divded by the chunk size. If not, create 00144 // a new ElementRegion at offset 0 off the raw offset region. 00145 // 00146 // (2b) If we don't a get a 'RegionRawOffset' after calling 00147 // 'getAsRawOffset()', it means that we are at offset 0. 00148 // 00149 // FIXME: Handle symbolic raw offsets. 00150 00151 const ElementRegion *elementR = cast<ElementRegion>(R); 00152 const RegionRawOffset &rawOff = elementR->getAsArrayOffset(); 00153 const MemRegion *baseR = rawOff.getRegion(); 00154 00155 // If we cannot compute a raw offset, throw up our hands and return 00156 // a NULL MemRegion*. 00157 if (!baseR) 00158 return nullptr; 00159 00160 CharUnits off = rawOff.getOffset(); 00161 00162 if (off.isZero()) { 00163 // Edge case: we are at 0 bytes off the beginning of baseR. We 00164 // check to see if type we are casting to is the same as the base 00165 // region. If so, just return the base region. 00166 if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(baseR)) { 00167 QualType ObjTy = Ctx.getCanonicalType(TR->getValueType()); 00168 QualType CanonPointeeTy = Ctx.getCanonicalType(PointeeTy); 00169 if (CanonPointeeTy == ObjTy) 00170 return baseR; 00171 } 00172 00173 // Otherwise, create a new ElementRegion at offset 0. 00174 return MakeElementRegion(baseR, PointeeTy); 00175 } 00176 00177 // We have a non-zero offset from the base region. We want to determine 00178 // if the offset can be evenly divided by sizeof(PointeeTy). If so, 00179 // we create an ElementRegion whose index is that value. Otherwise, we 00180 // create two ElementRegions, one that reflects a raw offset and the other 00181 // that reflects the cast. 00182 00183 // Compute the index for the new ElementRegion. 00184 int64_t newIndex = 0; 00185 const MemRegion *newSuperR = nullptr; 00186 00187 // We can only compute sizeof(PointeeTy) if it is a complete type. 00188 if (!PointeeTy->isIncompleteType()) { 00189 // Compute the size in **bytes**. 00190 CharUnits pointeeTySize = Ctx.getTypeSizeInChars(PointeeTy); 00191 if (!pointeeTySize.isZero()) { 00192 // Is the offset a multiple of the size? If so, we can layer the 00193 // ElementRegion (with elementType == PointeeTy) directly on top of 00194 // the base region. 00195 if (off % pointeeTySize == 0) { 00196 newIndex = off / pointeeTySize; 00197 newSuperR = baseR; 00198 } 00199 } 00200 } 00201 00202 if (!newSuperR) { 00203 // Create an intermediate ElementRegion to represent the raw byte. 00204 // This will be the super region of the final ElementRegion. 00205 newSuperR = MakeElementRegion(baseR, Ctx.CharTy, off.getQuantity()); 00206 } 00207 00208 return MakeElementRegion(newSuperR, PointeeTy, newIndex); 00209 } 00210 } 00211 00212 llvm_unreachable("unreachable"); 00213 } 00214 00215 static bool regionMatchesCXXRecordType(SVal V, QualType Ty) { 00216 const MemRegion *MR = V.getAsRegion(); 00217 if (!MR) 00218 return true; 00219 00220 const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(MR); 00221 if (!TVR) 00222 return true; 00223 00224 const CXXRecordDecl *RD = TVR->getValueType()->getAsCXXRecordDecl(); 00225 if (!RD) 00226 return true; 00227 00228 const CXXRecordDecl *Expected = Ty->getPointeeCXXRecordDecl(); 00229 if (!Expected) 00230 Expected = Ty->getAsCXXRecordDecl(); 00231 00232 return Expected->getCanonicalDecl() == RD->getCanonicalDecl(); 00233 } 00234 00235 SVal StoreManager::evalDerivedToBase(SVal Derived, const CastExpr *Cast) { 00236 // Sanity check to avoid doing the wrong thing in the face of 00237 // reinterpret_cast. 00238 if (!regionMatchesCXXRecordType(Derived, Cast->getSubExpr()->getType())) 00239 return UnknownVal(); 00240 00241 // Walk through the cast path to create nested CXXBaseRegions. 00242 SVal Result = Derived; 00243 for (CastExpr::path_const_iterator I = Cast->path_begin(), 00244 E = Cast->path_end(); 00245 I != E; ++I) { 00246 Result = evalDerivedToBase(Result, (*I)->getType(), (*I)->isVirtual()); 00247 } 00248 return Result; 00249 } 00250 00251 SVal StoreManager::evalDerivedToBase(SVal Derived, const CXXBasePath &Path) { 00252 // Walk through the path to create nested CXXBaseRegions. 00253 SVal Result = Derived; 00254 for (CXXBasePath::const_iterator I = Path.begin(), E = Path.end(); 00255 I != E; ++I) { 00256 Result = evalDerivedToBase(Result, I->Base->getType(), 00257 I->Base->isVirtual()); 00258 } 00259 return Result; 00260 } 00261 00262 SVal StoreManager::evalDerivedToBase(SVal Derived, QualType BaseType, 00263 bool IsVirtual) { 00264 Optional<loc::MemRegionVal> DerivedRegVal = 00265 Derived.getAs<loc::MemRegionVal>(); 00266 if (!DerivedRegVal) 00267 return Derived; 00268 00269 const CXXRecordDecl *BaseDecl = BaseType->getPointeeCXXRecordDecl(); 00270 if (!BaseDecl) 00271 BaseDecl = BaseType->getAsCXXRecordDecl(); 00272 assert(BaseDecl && "not a C++ object?"); 00273 00274 const MemRegion *BaseReg = 00275 MRMgr.getCXXBaseObjectRegion(BaseDecl, DerivedRegVal->getRegion(), 00276 IsVirtual); 00277 00278 return loc::MemRegionVal(BaseReg); 00279 } 00280 00281 /// Returns the static type of the given region, if it represents a C++ class 00282 /// object. 00283 /// 00284 /// This handles both fully-typed regions, where the dynamic type is known, and 00285 /// symbolic regions, where the dynamic type is merely bounded (and even then, 00286 /// only ostensibly!), but does not take advantage of any dynamic type info. 00287 static const CXXRecordDecl *getCXXRecordType(const MemRegion *MR) { 00288 if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(MR)) 00289 return TVR->getValueType()->getAsCXXRecordDecl(); 00290 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) 00291 return SR->getSymbol()->getType()->getPointeeCXXRecordDecl(); 00292 return nullptr; 00293 } 00294 00295 SVal StoreManager::evalDynamicCast(SVal Base, QualType TargetType, 00296 bool &Failed) { 00297 Failed = false; 00298 00299 const MemRegion *MR = Base.getAsRegion(); 00300 if (!MR) 00301 return UnknownVal(); 00302 00303 // Assume the derived class is a pointer or a reference to a CXX record. 00304 TargetType = TargetType->getPointeeType(); 00305 assert(!TargetType.isNull()); 00306 const CXXRecordDecl *TargetClass = TargetType->getAsCXXRecordDecl(); 00307 if (!TargetClass && !TargetType->isVoidType()) 00308 return UnknownVal(); 00309 00310 // Drill down the CXXBaseObject chains, which represent upcasts (casts from 00311 // derived to base). 00312 while (const CXXRecordDecl *MRClass = getCXXRecordType(MR)) { 00313 // If found the derived class, the cast succeeds. 00314 if (MRClass == TargetClass) 00315 return loc::MemRegionVal(MR); 00316 00317 // We skip over incomplete types. They must be the result of an earlier 00318 // reinterpret_cast, as one can only dynamic_cast between types in the same 00319 // class hierarchy. 00320 if (!TargetType->isVoidType() && MRClass->hasDefinition()) { 00321 // Static upcasts are marked as DerivedToBase casts by Sema, so this will 00322 // only happen when multiple or virtual inheritance is involved. 00323 CXXBasePaths Paths(/*FindAmbiguities=*/false, /*RecordPaths=*/true, 00324 /*DetectVirtual=*/false); 00325 if (MRClass->isDerivedFrom(TargetClass, Paths)) 00326 return evalDerivedToBase(loc::MemRegionVal(MR), Paths.front()); 00327 } 00328 00329 if (const CXXBaseObjectRegion *BaseR = dyn_cast<CXXBaseObjectRegion>(MR)) { 00330 // Drill down the chain to get the derived classes. 00331 MR = BaseR->getSuperRegion(); 00332 continue; 00333 } 00334 00335 // If this is a cast to void*, return the region. 00336 if (TargetType->isVoidType()) 00337 return loc::MemRegionVal(MR); 00338 00339 // Strange use of reinterpret_cast can give us paths we don't reason 00340 // about well, by putting in ElementRegions where we'd expect 00341 // CXXBaseObjectRegions. If it's a valid reinterpret_cast (i.e. if the 00342 // derived class has a zero offset from the base class), then it's safe 00343 // to strip the cast; if it's invalid, -Wreinterpret-base-class should 00344 // catch it. In the interest of performance, the analyzer will silently 00345 // do the wrong thing in the invalid case (because offsets for subregions 00346 // will be wrong). 00347 const MemRegion *Uncasted = MR->StripCasts(/*IncludeBaseCasts=*/false); 00348 if (Uncasted == MR) { 00349 // We reached the bottom of the hierarchy and did not find the derived 00350 // class. We we must be casting the base to derived, so the cast should 00351 // fail. 00352 break; 00353 } 00354 00355 MR = Uncasted; 00356 } 00357 00358 // We failed if the region we ended up with has perfect type info. 00359 Failed = isa<TypedValueRegion>(MR); 00360 return UnknownVal(); 00361 } 00362 00363 00364 /// CastRetrievedVal - Used by subclasses of StoreManager to implement 00365 /// implicit casts that arise from loads from regions that are reinterpreted 00366 /// as another region. 00367 SVal StoreManager::CastRetrievedVal(SVal V, const TypedValueRegion *R, 00368 QualType castTy, bool performTestOnly) { 00369 00370 if (castTy.isNull() || V.isUnknownOrUndef()) 00371 return V; 00372 00373 ASTContext &Ctx = svalBuilder.getContext(); 00374 00375 if (performTestOnly) { 00376 // Automatically translate references to pointers. 00377 QualType T = R->getValueType(); 00378 if (const ReferenceType *RT = T->getAs<ReferenceType>()) 00379 T = Ctx.getPointerType(RT->getPointeeType()); 00380 00381 assert(svalBuilder.getContext().hasSameUnqualifiedType(castTy, T)); 00382 return V; 00383 } 00384 00385 return svalBuilder.dispatchCast(V, castTy); 00386 } 00387 00388 SVal StoreManager::getLValueFieldOrIvar(const Decl *D, SVal Base) { 00389 if (Base.isUnknownOrUndef()) 00390 return Base; 00391 00392 Loc BaseL = Base.castAs<Loc>(); 00393 const MemRegion* BaseR = nullptr; 00394 00395 switch (BaseL.getSubKind()) { 00396 case loc::MemRegionKind: 00397 BaseR = BaseL.castAs<loc::MemRegionVal>().getRegion(); 00398 break; 00399 00400 case loc::GotoLabelKind: 00401 // These are anormal cases. Flag an undefined value. 00402 return UndefinedVal(); 00403 00404 case loc::ConcreteIntKind: 00405 // While these seem funny, this can happen through casts. 00406 // FIXME: What we should return is the field offset. For example, 00407 // add the field offset to the integer value. That way funny things 00408 // like this work properly: &(((struct foo *) 0xa)->f) 00409 return Base; 00410 00411 default: 00412 llvm_unreachable("Unhandled Base."); 00413 } 00414 00415 // NOTE: We must have this check first because ObjCIvarDecl is a subclass 00416 // of FieldDecl. 00417 if (const ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(D)) 00418 return loc::MemRegionVal(MRMgr.getObjCIvarRegion(ID, BaseR)); 00419 00420 return loc::MemRegionVal(MRMgr.getFieldRegion(cast<FieldDecl>(D), BaseR)); 00421 } 00422 00423 SVal StoreManager::getLValueIvar(const ObjCIvarDecl *decl, SVal base) { 00424 return getLValueFieldOrIvar(decl, base); 00425 } 00426 00427 SVal StoreManager::getLValueElement(QualType elementType, NonLoc Offset, 00428 SVal Base) { 00429 00430 // If the base is an unknown or undefined value, just return it back. 00431 // FIXME: For absolute pointer addresses, we just return that value back as 00432 // well, although in reality we should return the offset added to that 00433 // value. 00434 if (Base.isUnknownOrUndef() || Base.getAs<loc::ConcreteInt>()) 00435 return Base; 00436 00437 const MemRegion* BaseRegion = Base.castAs<loc::MemRegionVal>().getRegion(); 00438 00439 // Pointer of any type can be cast and used as array base. 00440 const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion); 00441 00442 // Convert the offset to the appropriate size and signedness. 00443 Offset = svalBuilder.convertToArrayIndex(Offset).castAs<NonLoc>(); 00444 00445 if (!ElemR) { 00446 // 00447 // If the base region is not an ElementRegion, create one. 00448 // This can happen in the following example: 00449 // 00450 // char *p = __builtin_alloc(10); 00451 // p[1] = 8; 00452 // 00453 // Observe that 'p' binds to an AllocaRegion. 00454 // 00455 return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset, 00456 BaseRegion, Ctx)); 00457 } 00458 00459 SVal BaseIdx = ElemR->getIndex(); 00460 00461 if (!BaseIdx.getAs<nonloc::ConcreteInt>()) 00462 return UnknownVal(); 00463 00464 const llvm::APSInt &BaseIdxI = 00465 BaseIdx.castAs<nonloc::ConcreteInt>().getValue(); 00466 00467 // Only allow non-integer offsets if the base region has no offset itself. 00468 // FIXME: This is a somewhat arbitrary restriction. We should be using 00469 // SValBuilder here to add the two offsets without checking their types. 00470 if (!Offset.getAs<nonloc::ConcreteInt>()) { 00471 if (isa<ElementRegion>(BaseRegion->StripCasts())) 00472 return UnknownVal(); 00473 00474 return loc::MemRegionVal(MRMgr.getElementRegion(elementType, Offset, 00475 ElemR->getSuperRegion(), 00476 Ctx)); 00477 } 00478 00479 const llvm::APSInt& OffI = Offset.castAs<nonloc::ConcreteInt>().getValue(); 00480 assert(BaseIdxI.isSigned()); 00481 00482 // Compute the new index. 00483 nonloc::ConcreteInt NewIdx(svalBuilder.getBasicValueFactory().getValue(BaseIdxI + 00484 OffI)); 00485 00486 // Construct the new ElementRegion. 00487 const MemRegion *ArrayR = ElemR->getSuperRegion(); 00488 return loc::MemRegionVal(MRMgr.getElementRegion(elementType, NewIdx, ArrayR, 00489 Ctx)); 00490 } 00491 00492 StoreManager::BindingsHandler::~BindingsHandler() {} 00493 00494 bool StoreManager::FindUniqueBinding::HandleBinding(StoreManager& SMgr, 00495 Store store, 00496 const MemRegion* R, 00497 SVal val) { 00498 SymbolRef SymV = val.getAsLocSymbol(); 00499 if (!SymV || SymV != Sym) 00500 return true; 00501 00502 if (Binding) { 00503 First = false; 00504 return false; 00505 } 00506 else 00507 Binding = R; 00508 00509 return true; 00510 }