clang API Documentation
00001 //== MemRegion.cpp - Abstract memory regions for static analysis --*- 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 defines MemRegion and its subclasses. MemRegion defines a 00011 // partially-typed abstraction of memory useful for path-sensitive dataflow 00012 // analyses. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h" 00017 #include "clang/AST/Attr.h" 00018 #include "clang/AST/CharUnits.h" 00019 #include "clang/AST/DeclObjC.h" 00020 #include "clang/AST/RecordLayout.h" 00021 #include "clang/Analysis/AnalysisContext.h" 00022 #include "clang/Analysis/Support/BumpVector.h" 00023 #include "clang/Basic/SourceManager.h" 00024 #include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h" 00025 #include "llvm/Support/raw_ostream.h" 00026 00027 using namespace clang; 00028 using namespace ento; 00029 00030 //===----------------------------------------------------------------------===// 00031 // MemRegion Construction. 00032 //===----------------------------------------------------------------------===// 00033 00034 template<typename RegionTy> struct MemRegionManagerTrait; 00035 00036 template <typename RegionTy, typename A1> 00037 RegionTy* MemRegionManager::getRegion(const A1 a1) { 00038 00039 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion = 00040 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1); 00041 00042 llvm::FoldingSetNodeID ID; 00043 RegionTy::ProfileRegion(ID, a1, superRegion); 00044 void *InsertPos; 00045 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 00046 InsertPos)); 00047 00048 if (!R) { 00049 R = (RegionTy*) A.Allocate<RegionTy>(); 00050 new (R) RegionTy(a1, superRegion); 00051 Regions.InsertNode(R, InsertPos); 00052 } 00053 00054 return R; 00055 } 00056 00057 template <typename RegionTy, typename A1> 00058 RegionTy* MemRegionManager::getSubRegion(const A1 a1, 00059 const MemRegion *superRegion) { 00060 llvm::FoldingSetNodeID ID; 00061 RegionTy::ProfileRegion(ID, a1, superRegion); 00062 void *InsertPos; 00063 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 00064 InsertPos)); 00065 00066 if (!R) { 00067 R = (RegionTy*) A.Allocate<RegionTy>(); 00068 new (R) RegionTy(a1, superRegion); 00069 Regions.InsertNode(R, InsertPos); 00070 } 00071 00072 return R; 00073 } 00074 00075 template <typename RegionTy, typename A1, typename A2> 00076 RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) { 00077 00078 const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion = 00079 MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2); 00080 00081 llvm::FoldingSetNodeID ID; 00082 RegionTy::ProfileRegion(ID, a1, a2, superRegion); 00083 void *InsertPos; 00084 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 00085 InsertPos)); 00086 00087 if (!R) { 00088 R = (RegionTy*) A.Allocate<RegionTy>(); 00089 new (R) RegionTy(a1, a2, superRegion); 00090 Regions.InsertNode(R, InsertPos); 00091 } 00092 00093 return R; 00094 } 00095 00096 template <typename RegionTy, typename A1, typename A2> 00097 RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, 00098 const MemRegion *superRegion) { 00099 00100 llvm::FoldingSetNodeID ID; 00101 RegionTy::ProfileRegion(ID, a1, a2, superRegion); 00102 void *InsertPos; 00103 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 00104 InsertPos)); 00105 00106 if (!R) { 00107 R = (RegionTy*) A.Allocate<RegionTy>(); 00108 new (R) RegionTy(a1, a2, superRegion); 00109 Regions.InsertNode(R, InsertPos); 00110 } 00111 00112 return R; 00113 } 00114 00115 template <typename RegionTy, typename A1, typename A2, typename A3> 00116 RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3, 00117 const MemRegion *superRegion) { 00118 00119 llvm::FoldingSetNodeID ID; 00120 RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion); 00121 void *InsertPos; 00122 RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID, 00123 InsertPos)); 00124 00125 if (!R) { 00126 R = (RegionTy*) A.Allocate<RegionTy>(); 00127 new (R) RegionTy(a1, a2, a3, superRegion); 00128 Regions.InsertNode(R, InsertPos); 00129 } 00130 00131 return R; 00132 } 00133 00134 //===----------------------------------------------------------------------===// 00135 // Object destruction. 00136 //===----------------------------------------------------------------------===// 00137 00138 MemRegion::~MemRegion() {} 00139 00140 MemRegionManager::~MemRegionManager() { 00141 // All regions and their data are BumpPtrAllocated. No need to call 00142 // their destructors. 00143 } 00144 00145 //===----------------------------------------------------------------------===// 00146 // Basic methods. 00147 //===----------------------------------------------------------------------===// 00148 00149 bool SubRegion::isSubRegionOf(const MemRegion* R) const { 00150 const MemRegion* r = getSuperRegion(); 00151 while (r != nullptr) { 00152 if (r == R) 00153 return true; 00154 if (const SubRegion* sr = dyn_cast<SubRegion>(r)) 00155 r = sr->getSuperRegion(); 00156 else 00157 break; 00158 } 00159 return false; 00160 } 00161 00162 MemRegionManager* SubRegion::getMemRegionManager() const { 00163 const SubRegion* r = this; 00164 do { 00165 const MemRegion *superRegion = r->getSuperRegion(); 00166 if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) { 00167 r = sr; 00168 continue; 00169 } 00170 return superRegion->getMemRegionManager(); 00171 } while (1); 00172 } 00173 00174 const StackFrameContext *VarRegion::getStackFrame() const { 00175 const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace()); 00176 return SSR ? SSR->getStackFrame() : nullptr; 00177 } 00178 00179 //===----------------------------------------------------------------------===// 00180 // Region extents. 00181 //===----------------------------------------------------------------------===// 00182 00183 DefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const { 00184 ASTContext &Ctx = svalBuilder.getContext(); 00185 QualType T = getDesugaredValueType(Ctx); 00186 00187 if (isa<VariableArrayType>(T)) 00188 return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this)); 00189 if (T->isIncompleteType()) 00190 return UnknownVal(); 00191 00192 CharUnits size = Ctx.getTypeSizeInChars(T); 00193 QualType sizeTy = svalBuilder.getArrayIndexType(); 00194 return svalBuilder.makeIntVal(size.getQuantity(), sizeTy); 00195 } 00196 00197 DefinedOrUnknownSVal FieldRegion::getExtent(SValBuilder &svalBuilder) const { 00198 // Force callers to deal with bitfields explicitly. 00199 if (getDecl()->isBitField()) 00200 return UnknownVal(); 00201 00202 DefinedOrUnknownSVal Extent = DeclRegion::getExtent(svalBuilder); 00203 00204 // A zero-length array at the end of a struct often stands for dynamically- 00205 // allocated extra memory. 00206 if (Extent.isZeroConstant()) { 00207 QualType T = getDesugaredValueType(svalBuilder.getContext()); 00208 00209 if (isa<ConstantArrayType>(T)) 00210 return UnknownVal(); 00211 } 00212 00213 return Extent; 00214 } 00215 00216 DefinedOrUnknownSVal AllocaRegion::getExtent(SValBuilder &svalBuilder) const { 00217 return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this)); 00218 } 00219 00220 DefinedOrUnknownSVal SymbolicRegion::getExtent(SValBuilder &svalBuilder) const { 00221 return nonloc::SymbolVal(svalBuilder.getSymbolManager().getExtentSymbol(this)); 00222 } 00223 00224 DefinedOrUnknownSVal StringRegion::getExtent(SValBuilder &svalBuilder) const { 00225 return svalBuilder.makeIntVal(getStringLiteral()->getByteLength()+1, 00226 svalBuilder.getArrayIndexType()); 00227 } 00228 00229 ObjCIvarRegion::ObjCIvarRegion(const ObjCIvarDecl *ivd, const MemRegion* sReg) 00230 : DeclRegion(ivd, sReg, ObjCIvarRegionKind) {} 00231 00232 const ObjCIvarDecl *ObjCIvarRegion::getDecl() const { 00233 return cast<ObjCIvarDecl>(D); 00234 } 00235 00236 QualType ObjCIvarRegion::getValueType() const { 00237 return getDecl()->getType(); 00238 } 00239 00240 QualType CXXBaseObjectRegion::getValueType() const { 00241 return QualType(getDecl()->getTypeForDecl(), 0); 00242 } 00243 00244 //===----------------------------------------------------------------------===// 00245 // FoldingSet profiling. 00246 //===----------------------------------------------------------------------===// 00247 00248 void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const { 00249 ID.AddInteger((unsigned)getKind()); 00250 } 00251 00252 void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const { 00253 ID.AddInteger((unsigned)getKind()); 00254 ID.AddPointer(getStackFrame()); 00255 } 00256 00257 void StaticGlobalSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const { 00258 ID.AddInteger((unsigned)getKind()); 00259 ID.AddPointer(getCodeRegion()); 00260 } 00261 00262 void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 00263 const StringLiteral* Str, 00264 const MemRegion* superRegion) { 00265 ID.AddInteger((unsigned) StringRegionKind); 00266 ID.AddPointer(Str); 00267 ID.AddPointer(superRegion); 00268 } 00269 00270 void ObjCStringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 00271 const ObjCStringLiteral* Str, 00272 const MemRegion* superRegion) { 00273 ID.AddInteger((unsigned) ObjCStringRegionKind); 00274 ID.AddPointer(Str); 00275 ID.AddPointer(superRegion); 00276 } 00277 00278 void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 00279 const Expr *Ex, unsigned cnt, 00280 const MemRegion *superRegion) { 00281 ID.AddInteger((unsigned) AllocaRegionKind); 00282 ID.AddPointer(Ex); 00283 ID.AddInteger(cnt); 00284 ID.AddPointer(superRegion); 00285 } 00286 00287 void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const { 00288 ProfileRegion(ID, Ex, Cnt, superRegion); 00289 } 00290 00291 void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const { 00292 CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion); 00293 } 00294 00295 void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 00296 const CompoundLiteralExpr *CL, 00297 const MemRegion* superRegion) { 00298 ID.AddInteger((unsigned) CompoundLiteralRegionKind); 00299 ID.AddPointer(CL); 00300 ID.AddPointer(superRegion); 00301 } 00302 00303 void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, 00304 const PointerType *PT, 00305 const MemRegion *sRegion) { 00306 ID.AddInteger((unsigned) CXXThisRegionKind); 00307 ID.AddPointer(PT); 00308 ID.AddPointer(sRegion); 00309 } 00310 00311 void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const { 00312 CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion); 00313 } 00314 00315 void ObjCIvarRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 00316 const ObjCIvarDecl *ivd, 00317 const MemRegion* superRegion) { 00318 DeclRegion::ProfileRegion(ID, ivd, superRegion, ObjCIvarRegionKind); 00319 } 00320 00321 void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl *D, 00322 const MemRegion* superRegion, Kind k) { 00323 ID.AddInteger((unsigned) k); 00324 ID.AddPointer(D); 00325 ID.AddPointer(superRegion); 00326 } 00327 00328 void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const { 00329 DeclRegion::ProfileRegion(ID, D, superRegion, getKind()); 00330 } 00331 00332 void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const { 00333 VarRegion::ProfileRegion(ID, getDecl(), superRegion); 00334 } 00335 00336 void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym, 00337 const MemRegion *sreg) { 00338 ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind); 00339 ID.Add(sym); 00340 ID.AddPointer(sreg); 00341 } 00342 00343 void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const { 00344 SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion()); 00345 } 00346 00347 void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 00348 QualType ElementType, SVal Idx, 00349 const MemRegion* superRegion) { 00350 ID.AddInteger(MemRegion::ElementRegionKind); 00351 ID.Add(ElementType); 00352 ID.AddPointer(superRegion); 00353 Idx.Profile(ID); 00354 } 00355 00356 void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const { 00357 ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion); 00358 } 00359 00360 void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 00361 const NamedDecl *FD, 00362 const MemRegion*) { 00363 ID.AddInteger(MemRegion::FunctionTextRegionKind); 00364 ID.AddPointer(FD); 00365 } 00366 00367 void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const { 00368 FunctionTextRegion::ProfileRegion(ID, FD, superRegion); 00369 } 00370 00371 void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 00372 const BlockDecl *BD, CanQualType, 00373 const AnalysisDeclContext *AC, 00374 const MemRegion*) { 00375 ID.AddInteger(MemRegion::BlockTextRegionKind); 00376 ID.AddPointer(BD); 00377 } 00378 00379 void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const { 00380 BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion); 00381 } 00382 00383 void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, 00384 const BlockTextRegion *BC, 00385 const LocationContext *LC, 00386 unsigned BlkCount, 00387 const MemRegion *sReg) { 00388 ID.AddInteger(MemRegion::BlockDataRegionKind); 00389 ID.AddPointer(BC); 00390 ID.AddPointer(LC); 00391 ID.AddInteger(BlkCount); 00392 ID.AddPointer(sReg); 00393 } 00394 00395 void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const { 00396 BlockDataRegion::ProfileRegion(ID, BC, LC, BlockCount, getSuperRegion()); 00397 } 00398 00399 void CXXTempObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, 00400 Expr const *Ex, 00401 const MemRegion *sReg) { 00402 ID.AddPointer(Ex); 00403 ID.AddPointer(sReg); 00404 } 00405 00406 void CXXTempObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const { 00407 ProfileRegion(ID, Ex, getSuperRegion()); 00408 } 00409 00410 void CXXBaseObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID, 00411 const CXXRecordDecl *RD, 00412 bool IsVirtual, 00413 const MemRegion *SReg) { 00414 ID.AddPointer(RD); 00415 ID.AddBoolean(IsVirtual); 00416 ID.AddPointer(SReg); 00417 } 00418 00419 void CXXBaseObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const { 00420 ProfileRegion(ID, getDecl(), isVirtual(), superRegion); 00421 } 00422 00423 //===----------------------------------------------------------------------===// 00424 // Region anchors. 00425 //===----------------------------------------------------------------------===// 00426 00427 void GlobalsSpaceRegion::anchor() { } 00428 void HeapSpaceRegion::anchor() { } 00429 void UnknownSpaceRegion::anchor() { } 00430 void StackLocalsSpaceRegion::anchor() { } 00431 void StackArgumentsSpaceRegion::anchor() { } 00432 void TypedRegion::anchor() { } 00433 void TypedValueRegion::anchor() { } 00434 void CodeTextRegion::anchor() { } 00435 void SubRegion::anchor() { } 00436 00437 //===----------------------------------------------------------------------===// 00438 // Region pretty-printing. 00439 //===----------------------------------------------------------------------===// 00440 00441 void MemRegion::dump() const { 00442 dumpToStream(llvm::errs()); 00443 } 00444 00445 std::string MemRegion::getString() const { 00446 std::string s; 00447 llvm::raw_string_ostream os(s); 00448 dumpToStream(os); 00449 return os.str(); 00450 } 00451 00452 void MemRegion::dumpToStream(raw_ostream &os) const { 00453 os << "<Unknown Region>"; 00454 } 00455 00456 void AllocaRegion::dumpToStream(raw_ostream &os) const { 00457 os << "alloca{" << (const void*) Ex << ',' << Cnt << '}'; 00458 } 00459 00460 void FunctionTextRegion::dumpToStream(raw_ostream &os) const { 00461 os << "code{" << getDecl()->getDeclName().getAsString() << '}'; 00462 } 00463 00464 void BlockTextRegion::dumpToStream(raw_ostream &os) const { 00465 os << "block_code{" << (const void*) this << '}'; 00466 } 00467 00468 void BlockDataRegion::dumpToStream(raw_ostream &os) const { 00469 os << "block_data{" << BC; 00470 os << "; "; 00471 for (BlockDataRegion::referenced_vars_iterator 00472 I = referenced_vars_begin(), 00473 E = referenced_vars_end(); I != E; ++I) 00474 os << "(" << I.getCapturedRegion() << "," << 00475 I.getOriginalRegion() << ") "; 00476 os << '}'; 00477 } 00478 00479 void CompoundLiteralRegion::dumpToStream(raw_ostream &os) const { 00480 // FIXME: More elaborate pretty-printing. 00481 os << "{ " << (const void*) CL << " }"; 00482 } 00483 00484 void CXXTempObjectRegion::dumpToStream(raw_ostream &os) const { 00485 os << "temp_object{" << getValueType().getAsString() << ',' 00486 << (const void*) Ex << '}'; 00487 } 00488 00489 void CXXBaseObjectRegion::dumpToStream(raw_ostream &os) const { 00490 os << "base{" << superRegion << ',' << getDecl()->getName() << '}'; 00491 } 00492 00493 void CXXThisRegion::dumpToStream(raw_ostream &os) const { 00494 os << "this"; 00495 } 00496 00497 void ElementRegion::dumpToStream(raw_ostream &os) const { 00498 os << "element{" << superRegion << ',' 00499 << Index << ',' << getElementType().getAsString() << '}'; 00500 } 00501 00502 void FieldRegion::dumpToStream(raw_ostream &os) const { 00503 os << superRegion << "->" << *getDecl(); 00504 } 00505 00506 void ObjCIvarRegion::dumpToStream(raw_ostream &os) const { 00507 os << "ivar{" << superRegion << ',' << *getDecl() << '}'; 00508 } 00509 00510 void StringRegion::dumpToStream(raw_ostream &os) const { 00511 assert(Str != nullptr && "Expecting non-null StringLiteral"); 00512 Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts())); 00513 } 00514 00515 void ObjCStringRegion::dumpToStream(raw_ostream &os) const { 00516 assert(Str != nullptr && "Expecting non-null ObjCStringLiteral"); 00517 Str->printPretty(os, nullptr, PrintingPolicy(getContext().getLangOpts())); 00518 } 00519 00520 void SymbolicRegion::dumpToStream(raw_ostream &os) const { 00521 os << "SymRegion{" << sym << '}'; 00522 } 00523 00524 void VarRegion::dumpToStream(raw_ostream &os) const { 00525 os << *cast<VarDecl>(D); 00526 } 00527 00528 void RegionRawOffset::dump() const { 00529 dumpToStream(llvm::errs()); 00530 } 00531 00532 void RegionRawOffset::dumpToStream(raw_ostream &os) const { 00533 os << "raw_offset{" << getRegion() << ',' << getOffset().getQuantity() << '}'; 00534 } 00535 00536 void StaticGlobalSpaceRegion::dumpToStream(raw_ostream &os) const { 00537 os << "StaticGlobalsMemSpace{" << CR << '}'; 00538 } 00539 00540 void GlobalInternalSpaceRegion::dumpToStream(raw_ostream &os) const { 00541 os << "GlobalInternalSpaceRegion"; 00542 } 00543 00544 void GlobalSystemSpaceRegion::dumpToStream(raw_ostream &os) const { 00545 os << "GlobalSystemSpaceRegion"; 00546 } 00547 00548 void GlobalImmutableSpaceRegion::dumpToStream(raw_ostream &os) const { 00549 os << "GlobalImmutableSpaceRegion"; 00550 } 00551 00552 void HeapSpaceRegion::dumpToStream(raw_ostream &os) const { 00553 os << "HeapSpaceRegion"; 00554 } 00555 00556 void UnknownSpaceRegion::dumpToStream(raw_ostream &os) const { 00557 os << "UnknownSpaceRegion"; 00558 } 00559 00560 void StackArgumentsSpaceRegion::dumpToStream(raw_ostream &os) const { 00561 os << "StackArgumentsSpaceRegion"; 00562 } 00563 00564 void StackLocalsSpaceRegion::dumpToStream(raw_ostream &os) const { 00565 os << "StackLocalsSpaceRegion"; 00566 } 00567 00568 bool MemRegion::canPrintPretty() const { 00569 return canPrintPrettyAsExpr(); 00570 } 00571 00572 bool MemRegion::canPrintPrettyAsExpr() const { 00573 return false; 00574 } 00575 00576 void MemRegion::printPretty(raw_ostream &os) const { 00577 assert(canPrintPretty() && "This region cannot be printed pretty."); 00578 os << "'"; 00579 printPrettyAsExpr(os); 00580 os << "'"; 00581 return; 00582 } 00583 00584 void MemRegion::printPrettyAsExpr(raw_ostream &os) const { 00585 llvm_unreachable("This region cannot be printed pretty."); 00586 return; 00587 } 00588 00589 bool VarRegion::canPrintPrettyAsExpr() const { 00590 return true; 00591 } 00592 00593 void VarRegion::printPrettyAsExpr(raw_ostream &os) const { 00594 os << getDecl()->getName(); 00595 } 00596 00597 bool ObjCIvarRegion::canPrintPrettyAsExpr() const { 00598 return true; 00599 } 00600 00601 void ObjCIvarRegion::printPrettyAsExpr(raw_ostream &os) const { 00602 os << getDecl()->getName(); 00603 } 00604 00605 bool FieldRegion::canPrintPretty() const { 00606 return true; 00607 } 00608 00609 bool FieldRegion::canPrintPrettyAsExpr() const { 00610 return superRegion->canPrintPrettyAsExpr(); 00611 } 00612 00613 void FieldRegion::printPrettyAsExpr(raw_ostream &os) const { 00614 assert(canPrintPrettyAsExpr()); 00615 superRegion->printPrettyAsExpr(os); 00616 os << "." << getDecl()->getName(); 00617 } 00618 00619 void FieldRegion::printPretty(raw_ostream &os) const { 00620 if (canPrintPrettyAsExpr()) { 00621 os << "\'"; 00622 printPrettyAsExpr(os); 00623 os << "'"; 00624 } else { 00625 os << "field " << "\'" << getDecl()->getName() << "'"; 00626 } 00627 return; 00628 } 00629 00630 bool CXXBaseObjectRegion::canPrintPrettyAsExpr() const { 00631 return superRegion->canPrintPrettyAsExpr(); 00632 } 00633 00634 void CXXBaseObjectRegion::printPrettyAsExpr(raw_ostream &os) const { 00635 superRegion->printPrettyAsExpr(os); 00636 } 00637 00638 //===----------------------------------------------------------------------===// 00639 // MemRegionManager methods. 00640 //===----------------------------------------------------------------------===// 00641 00642 template <typename REG> 00643 const REG *MemRegionManager::LazyAllocate(REG*& region) { 00644 if (!region) { 00645 region = (REG*) A.Allocate<REG>(); 00646 new (region) REG(this); 00647 } 00648 00649 return region; 00650 } 00651 00652 template <typename REG, typename ARG> 00653 const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) { 00654 if (!region) { 00655 region = (REG*) A.Allocate<REG>(); 00656 new (region) REG(this, a); 00657 } 00658 00659 return region; 00660 } 00661 00662 const StackLocalsSpaceRegion* 00663 MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) { 00664 assert(STC); 00665 StackLocalsSpaceRegion *&R = StackLocalsSpaceRegions[STC]; 00666 00667 if (R) 00668 return R; 00669 00670 R = A.Allocate<StackLocalsSpaceRegion>(); 00671 new (R) StackLocalsSpaceRegion(this, STC); 00672 return R; 00673 } 00674 00675 const StackArgumentsSpaceRegion * 00676 MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) { 00677 assert(STC); 00678 StackArgumentsSpaceRegion *&R = StackArgumentsSpaceRegions[STC]; 00679 00680 if (R) 00681 return R; 00682 00683 R = A.Allocate<StackArgumentsSpaceRegion>(); 00684 new (R) StackArgumentsSpaceRegion(this, STC); 00685 return R; 00686 } 00687 00688 const GlobalsSpaceRegion 00689 *MemRegionManager::getGlobalsRegion(MemRegion::Kind K, 00690 const CodeTextRegion *CR) { 00691 if (!CR) { 00692 if (K == MemRegion::GlobalSystemSpaceRegionKind) 00693 return LazyAllocate(SystemGlobals); 00694 if (K == MemRegion::GlobalImmutableSpaceRegionKind) 00695 return LazyAllocate(ImmutableGlobals); 00696 assert(K == MemRegion::GlobalInternalSpaceRegionKind); 00697 return LazyAllocate(InternalGlobals); 00698 } 00699 00700 assert(K == MemRegion::StaticGlobalSpaceRegionKind); 00701 StaticGlobalSpaceRegion *&R = StaticsGlobalSpaceRegions[CR]; 00702 if (R) 00703 return R; 00704 00705 R = A.Allocate<StaticGlobalSpaceRegion>(); 00706 new (R) StaticGlobalSpaceRegion(this, CR); 00707 return R; 00708 } 00709 00710 const HeapSpaceRegion *MemRegionManager::getHeapRegion() { 00711 return LazyAllocate(heap); 00712 } 00713 00714 const MemSpaceRegion *MemRegionManager::getUnknownRegion() { 00715 return LazyAllocate(unknown); 00716 } 00717 00718 const MemSpaceRegion *MemRegionManager::getCodeRegion() { 00719 return LazyAllocate(code); 00720 } 00721 00722 //===----------------------------------------------------------------------===// 00723 // Constructing regions. 00724 //===----------------------------------------------------------------------===// 00725 const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str){ 00726 return getSubRegion<StringRegion>(Str, getGlobalsRegion()); 00727 } 00728 00729 const ObjCStringRegion * 00730 MemRegionManager::getObjCStringRegion(const ObjCStringLiteral* Str){ 00731 return getSubRegion<ObjCStringRegion>(Str, getGlobalsRegion()); 00732 } 00733 00734 /// Look through a chain of LocationContexts to either find the 00735 /// StackFrameContext that matches a DeclContext, or find a VarRegion 00736 /// for a variable captured by a block. 00737 static llvm::PointerUnion<const StackFrameContext *, const VarRegion *> 00738 getStackOrCaptureRegionForDeclContext(const LocationContext *LC, 00739 const DeclContext *DC, 00740 const VarDecl *VD) { 00741 while (LC) { 00742 if (const StackFrameContext *SFC = dyn_cast<StackFrameContext>(LC)) { 00743 if (cast<DeclContext>(SFC->getDecl()) == DC) 00744 return SFC; 00745 } 00746 if (const BlockInvocationContext *BC = 00747 dyn_cast<BlockInvocationContext>(LC)) { 00748 const BlockDataRegion *BR = 00749 static_cast<const BlockDataRegion*>(BC->getContextData()); 00750 // FIXME: This can be made more efficient. 00751 for (BlockDataRegion::referenced_vars_iterator 00752 I = BR->referenced_vars_begin(), 00753 E = BR->referenced_vars_end(); I != E; ++I) { 00754 if (const VarRegion *VR = dyn_cast<VarRegion>(I.getOriginalRegion())) 00755 if (VR->getDecl() == VD) 00756 return cast<VarRegion>(I.getCapturedRegion()); 00757 } 00758 } 00759 00760 LC = LC->getParent(); 00761 } 00762 return (const StackFrameContext *)nullptr; 00763 } 00764 00765 const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D, 00766 const LocationContext *LC) { 00767 const MemRegion *sReg = nullptr; 00768 00769 if (D->hasGlobalStorage() && !D->isStaticLocal()) { 00770 00771 // First handle the globals defined in system headers. 00772 if (C.getSourceManager().isInSystemHeader(D->getLocation())) { 00773 // Whitelist the system globals which often DO GET modified, assume the 00774 // rest are immutable. 00775 if (D->getName().find("errno") != StringRef::npos) 00776 sReg = getGlobalsRegion(MemRegion::GlobalSystemSpaceRegionKind); 00777 else 00778 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); 00779 00780 // Treat other globals as GlobalInternal unless they are constants. 00781 } else { 00782 QualType GQT = D->getType(); 00783 const Type *GT = GQT.getTypePtrOrNull(); 00784 // TODO: We could walk the complex types here and see if everything is 00785 // constified. 00786 if (GT && GQT.isConstQualified() && GT->isArithmeticType()) 00787 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); 00788 else 00789 sReg = getGlobalsRegion(); 00790 } 00791 00792 // Finally handle static locals. 00793 } else { 00794 // FIXME: Once we implement scope handling, we will need to properly lookup 00795 // 'D' to the proper LocationContext. 00796 const DeclContext *DC = D->getDeclContext(); 00797 llvm::PointerUnion<const StackFrameContext *, const VarRegion *> V = 00798 getStackOrCaptureRegionForDeclContext(LC, DC, D); 00799 00800 if (V.is<const VarRegion*>()) 00801 return V.get<const VarRegion*>(); 00802 00803 const StackFrameContext *STC = V.get<const StackFrameContext*>(); 00804 00805 if (!STC) 00806 sReg = getUnknownRegion(); 00807 else { 00808 if (D->hasLocalStorage()) { 00809 sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D) 00810 ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC)) 00811 : static_cast<const MemRegion*>(getStackLocalsRegion(STC)); 00812 } 00813 else { 00814 assert(D->isStaticLocal()); 00815 const Decl *STCD = STC->getDecl(); 00816 if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD)) 00817 sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, 00818 getFunctionTextRegion(cast<NamedDecl>(STCD))); 00819 else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) { 00820 // FIXME: The fallback type here is totally bogus -- though it should 00821 // never be queried, it will prevent uniquing with the real 00822 // BlockTextRegion. Ideally we'd fix the AST so that we always had a 00823 // signature. 00824 QualType T; 00825 if (const TypeSourceInfo *TSI = BD->getSignatureAsWritten()) 00826 T = TSI->getType(); 00827 else 00828 T = getContext().getFunctionNoProtoType(getContext().VoidTy); 00829 00830 const BlockTextRegion *BTR = 00831 getBlockTextRegion(BD, C.getCanonicalType(T), 00832 STC->getAnalysisDeclContext()); 00833 sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, 00834 BTR); 00835 } 00836 else { 00837 sReg = getGlobalsRegion(); 00838 } 00839 } 00840 } 00841 } 00842 00843 return getSubRegion<VarRegion>(D, sReg); 00844 } 00845 00846 const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D, 00847 const MemRegion *superR) { 00848 return getSubRegion<VarRegion>(D, superR); 00849 } 00850 00851 const BlockDataRegion * 00852 MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC, 00853 const LocationContext *LC, 00854 unsigned blockCount) { 00855 const MemRegion *sReg = nullptr; 00856 const BlockDecl *BD = BC->getDecl(); 00857 if (!BD->hasCaptures()) { 00858 // This handles 'static' blocks. 00859 sReg = getGlobalsRegion(MemRegion::GlobalImmutableSpaceRegionKind); 00860 } 00861 else { 00862 if (LC) { 00863 // FIXME: Once we implement scope handling, we want the parent region 00864 // to be the scope. 00865 const StackFrameContext *STC = LC->getCurrentStackFrame(); 00866 assert(STC); 00867 sReg = getStackLocalsRegion(STC); 00868 } 00869 else { 00870 // We allow 'LC' to be NULL for cases where want BlockDataRegions 00871 // without context-sensitivity. 00872 sReg = getUnknownRegion(); 00873 } 00874 } 00875 00876 return getSubRegion<BlockDataRegion>(BC, LC, blockCount, sReg); 00877 } 00878 00879 const CXXTempObjectRegion * 00880 MemRegionManager::getCXXStaticTempObjectRegion(const Expr *Ex) { 00881 return getSubRegion<CXXTempObjectRegion>( 00882 Ex, getGlobalsRegion(MemRegion::GlobalInternalSpaceRegionKind, nullptr)); 00883 } 00884 00885 const CompoundLiteralRegion* 00886 MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr *CL, 00887 const LocationContext *LC) { 00888 00889 const MemRegion *sReg = nullptr; 00890 00891 if (CL->isFileScope()) 00892 sReg = getGlobalsRegion(); 00893 else { 00894 const StackFrameContext *STC = LC->getCurrentStackFrame(); 00895 assert(STC); 00896 sReg = getStackLocalsRegion(STC); 00897 } 00898 00899 return getSubRegion<CompoundLiteralRegion>(CL, sReg); 00900 } 00901 00902 const ElementRegion* 00903 MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx, 00904 const MemRegion* superRegion, 00905 ASTContext &Ctx){ 00906 00907 QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType(); 00908 00909 llvm::FoldingSetNodeID ID; 00910 ElementRegion::ProfileRegion(ID, T, Idx, superRegion); 00911 00912 void *InsertPos; 00913 MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos); 00914 ElementRegion* R = cast_or_null<ElementRegion>(data); 00915 00916 if (!R) { 00917 R = (ElementRegion*) A.Allocate<ElementRegion>(); 00918 new (R) ElementRegion(T, Idx, superRegion); 00919 Regions.InsertNode(R, InsertPos); 00920 } 00921 00922 return R; 00923 } 00924 00925 const FunctionTextRegion * 00926 MemRegionManager::getFunctionTextRegion(const NamedDecl *FD) { 00927 return getSubRegion<FunctionTextRegion>(FD, getCodeRegion()); 00928 } 00929 00930 const BlockTextRegion * 00931 MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy, 00932 AnalysisDeclContext *AC) { 00933 return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion()); 00934 } 00935 00936 00937 /// getSymbolicRegion - Retrieve or create a "symbolic" memory region. 00938 const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) { 00939 return getSubRegion<SymbolicRegion>(sym, getUnknownRegion()); 00940 } 00941 00942 const SymbolicRegion *MemRegionManager::getSymbolicHeapRegion(SymbolRef Sym) { 00943 return getSubRegion<SymbolicRegion>(Sym, getHeapRegion()); 00944 } 00945 00946 const FieldRegion* 00947 MemRegionManager::getFieldRegion(const FieldDecl *d, 00948 const MemRegion* superRegion){ 00949 return getSubRegion<FieldRegion>(d, superRegion); 00950 } 00951 00952 const ObjCIvarRegion* 00953 MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl *d, 00954 const MemRegion* superRegion) { 00955 return getSubRegion<ObjCIvarRegion>(d, superRegion); 00956 } 00957 00958 const CXXTempObjectRegion* 00959 MemRegionManager::getCXXTempObjectRegion(Expr const *E, 00960 LocationContext const *LC) { 00961 const StackFrameContext *SFC = LC->getCurrentStackFrame(); 00962 assert(SFC); 00963 return getSubRegion<CXXTempObjectRegion>(E, getStackLocalsRegion(SFC)); 00964 } 00965 00966 /// Checks whether \p BaseClass is a valid virtual or direct non-virtual base 00967 /// class of the type of \p Super. 00968 static bool isValidBaseClass(const CXXRecordDecl *BaseClass, 00969 const TypedValueRegion *Super, 00970 bool IsVirtual) { 00971 BaseClass = BaseClass->getCanonicalDecl(); 00972 00973 const CXXRecordDecl *Class = Super->getValueType()->getAsCXXRecordDecl(); 00974 if (!Class) 00975 return true; 00976 00977 if (IsVirtual) 00978 return Class->isVirtuallyDerivedFrom(BaseClass); 00979 00980 for (const auto &I : Class->bases()) { 00981 if (I.getType()->getAsCXXRecordDecl()->getCanonicalDecl() == BaseClass) 00982 return true; 00983 } 00984 00985 return false; 00986 } 00987 00988 const CXXBaseObjectRegion * 00989 MemRegionManager::getCXXBaseObjectRegion(const CXXRecordDecl *RD, 00990 const MemRegion *Super, 00991 bool IsVirtual) { 00992 if (isa<TypedValueRegion>(Super)) { 00993 assert(isValidBaseClass(RD, dyn_cast<TypedValueRegion>(Super), IsVirtual)); 00994 (void)&isValidBaseClass; 00995 00996 if (IsVirtual) { 00997 // Virtual base regions should not be layered, since the layout rules 00998 // are different. 00999 while (const CXXBaseObjectRegion *Base = 01000 dyn_cast<CXXBaseObjectRegion>(Super)) { 01001 Super = Base->getSuperRegion(); 01002 } 01003 assert(Super && !isa<MemSpaceRegion>(Super)); 01004 } 01005 } 01006 01007 return getSubRegion<CXXBaseObjectRegion>(RD, IsVirtual, Super); 01008 } 01009 01010 const CXXThisRegion* 01011 MemRegionManager::getCXXThisRegion(QualType thisPointerTy, 01012 const LocationContext *LC) { 01013 const StackFrameContext *STC = LC->getCurrentStackFrame(); 01014 assert(STC); 01015 const PointerType *PT = thisPointerTy->getAs<PointerType>(); 01016 assert(PT); 01017 return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC)); 01018 } 01019 01020 const AllocaRegion* 01021 MemRegionManager::getAllocaRegion(const Expr *E, unsigned cnt, 01022 const LocationContext *LC) { 01023 const StackFrameContext *STC = LC->getCurrentStackFrame(); 01024 assert(STC); 01025 return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC)); 01026 } 01027 01028 const MemSpaceRegion *MemRegion::getMemorySpace() const { 01029 const MemRegion *R = this; 01030 const SubRegion* SR = dyn_cast<SubRegion>(this); 01031 01032 while (SR) { 01033 R = SR->getSuperRegion(); 01034 SR = dyn_cast<SubRegion>(R); 01035 } 01036 01037 return dyn_cast<MemSpaceRegion>(R); 01038 } 01039 01040 bool MemRegion::hasStackStorage() const { 01041 return isa<StackSpaceRegion>(getMemorySpace()); 01042 } 01043 01044 bool MemRegion::hasStackNonParametersStorage() const { 01045 return isa<StackLocalsSpaceRegion>(getMemorySpace()); 01046 } 01047 01048 bool MemRegion::hasStackParametersStorage() const { 01049 return isa<StackArgumentsSpaceRegion>(getMemorySpace()); 01050 } 01051 01052 bool MemRegion::hasGlobalsOrParametersStorage() const { 01053 const MemSpaceRegion *MS = getMemorySpace(); 01054 return isa<StackArgumentsSpaceRegion>(MS) || 01055 isa<GlobalsSpaceRegion>(MS); 01056 } 01057 01058 // getBaseRegion strips away all elements and fields, and get the base region 01059 // of them. 01060 const MemRegion *MemRegion::getBaseRegion() const { 01061 const MemRegion *R = this; 01062 while (true) { 01063 switch (R->getKind()) { 01064 case MemRegion::ElementRegionKind: 01065 case MemRegion::FieldRegionKind: 01066 case MemRegion::ObjCIvarRegionKind: 01067 case MemRegion::CXXBaseObjectRegionKind: 01068 R = cast<SubRegion>(R)->getSuperRegion(); 01069 continue; 01070 default: 01071 break; 01072 } 01073 break; 01074 } 01075 return R; 01076 } 01077 01078 bool MemRegion::isSubRegionOf(const MemRegion *R) const { 01079 return false; 01080 } 01081 01082 //===----------------------------------------------------------------------===// 01083 // View handling. 01084 //===----------------------------------------------------------------------===// 01085 01086 const MemRegion *MemRegion::StripCasts(bool StripBaseCasts) const { 01087 const MemRegion *R = this; 01088 while (true) { 01089 switch (R->getKind()) { 01090 case ElementRegionKind: { 01091 const ElementRegion *ER = cast<ElementRegion>(R); 01092 if (!ER->getIndex().isZeroConstant()) 01093 return R; 01094 R = ER->getSuperRegion(); 01095 break; 01096 } 01097 case CXXBaseObjectRegionKind: 01098 if (!StripBaseCasts) 01099 return R; 01100 R = cast<CXXBaseObjectRegion>(R)->getSuperRegion(); 01101 break; 01102 default: 01103 return R; 01104 } 01105 } 01106 } 01107 01108 const SymbolicRegion *MemRegion::getSymbolicBase() const { 01109 const SubRegion *SubR = dyn_cast<SubRegion>(this); 01110 01111 while (SubR) { 01112 if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(SubR)) 01113 return SymR; 01114 SubR = dyn_cast<SubRegion>(SubR->getSuperRegion()); 01115 } 01116 return nullptr; 01117 } 01118 01119 RegionRawOffset ElementRegion::getAsArrayOffset() const { 01120 CharUnits offset = CharUnits::Zero(); 01121 const ElementRegion *ER = this; 01122 const MemRegion *superR = nullptr; 01123 ASTContext &C = getContext(); 01124 01125 // FIXME: Handle multi-dimensional arrays. 01126 01127 while (ER) { 01128 superR = ER->getSuperRegion(); 01129 01130 // FIXME: generalize to symbolic offsets. 01131 SVal index = ER->getIndex(); 01132 if (Optional<nonloc::ConcreteInt> CI = index.getAs<nonloc::ConcreteInt>()) { 01133 // Update the offset. 01134 int64_t i = CI->getValue().getSExtValue(); 01135 01136 if (i != 0) { 01137 QualType elemType = ER->getElementType(); 01138 01139 // If we are pointing to an incomplete type, go no further. 01140 if (elemType->isIncompleteType()) { 01141 superR = ER; 01142 break; 01143 } 01144 01145 CharUnits size = C.getTypeSizeInChars(elemType); 01146 offset += (i * size); 01147 } 01148 01149 // Go to the next ElementRegion (if any). 01150 ER = dyn_cast<ElementRegion>(superR); 01151 continue; 01152 } 01153 01154 return nullptr; 01155 } 01156 01157 assert(superR && "super region cannot be NULL"); 01158 return RegionRawOffset(superR, offset); 01159 } 01160 01161 01162 /// Returns true if \p Base is an immediate base class of \p Child 01163 static bool isImmediateBase(const CXXRecordDecl *Child, 01164 const CXXRecordDecl *Base) { 01165 // Note that we do NOT canonicalize the base class here, because 01166 // ASTRecordLayout doesn't either. If that leads us down the wrong path, 01167 // so be it; at least we won't crash. 01168 for (const auto &I : Child->bases()) { 01169 if (I.getType()->getAsCXXRecordDecl() == Base) 01170 return true; 01171 } 01172 01173 return false; 01174 } 01175 01176 RegionOffset MemRegion::getAsOffset() const { 01177 const MemRegion *R = this; 01178 const MemRegion *SymbolicOffsetBase = nullptr; 01179 int64_t Offset = 0; 01180 01181 while (1) { 01182 switch (R->getKind()) { 01183 case GenericMemSpaceRegionKind: 01184 case StackLocalsSpaceRegionKind: 01185 case StackArgumentsSpaceRegionKind: 01186 case HeapSpaceRegionKind: 01187 case UnknownSpaceRegionKind: 01188 case StaticGlobalSpaceRegionKind: 01189 case GlobalInternalSpaceRegionKind: 01190 case GlobalSystemSpaceRegionKind: 01191 case GlobalImmutableSpaceRegionKind: 01192 // Stores can bind directly to a region space to set a default value. 01193 assert(Offset == 0 && !SymbolicOffsetBase); 01194 goto Finish; 01195 01196 case FunctionTextRegionKind: 01197 case BlockTextRegionKind: 01198 case BlockDataRegionKind: 01199 // These will never have bindings, but may end up having values requested 01200 // if the user does some strange casting. 01201 if (Offset != 0) 01202 SymbolicOffsetBase = R; 01203 goto Finish; 01204 01205 case SymbolicRegionKind: 01206 case AllocaRegionKind: 01207 case CompoundLiteralRegionKind: 01208 case CXXThisRegionKind: 01209 case StringRegionKind: 01210 case ObjCStringRegionKind: 01211 case VarRegionKind: 01212 case CXXTempObjectRegionKind: 01213 // Usual base regions. 01214 goto Finish; 01215 01216 case ObjCIvarRegionKind: 01217 // This is a little strange, but it's a compromise between 01218 // ObjCIvarRegions having unknown compile-time offsets (when using the 01219 // non-fragile runtime) and yet still being distinct, non-overlapping 01220 // regions. Thus we treat them as "like" base regions for the purposes 01221 // of computing offsets. 01222 goto Finish; 01223 01224 case CXXBaseObjectRegionKind: { 01225 const CXXBaseObjectRegion *BOR = cast<CXXBaseObjectRegion>(R); 01226 R = BOR->getSuperRegion(); 01227 01228 QualType Ty; 01229 bool RootIsSymbolic = false; 01230 if (const TypedValueRegion *TVR = dyn_cast<TypedValueRegion>(R)) { 01231 Ty = TVR->getDesugaredValueType(getContext()); 01232 } else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) { 01233 // If our base region is symbolic, we don't know what type it really is. 01234 // Pretend the type of the symbol is the true dynamic type. 01235 // (This will at least be self-consistent for the life of the symbol.) 01236 Ty = SR->getSymbol()->getType()->getPointeeType(); 01237 RootIsSymbolic = true; 01238 } 01239 01240 const CXXRecordDecl *Child = Ty->getAsCXXRecordDecl(); 01241 if (!Child) { 01242 // We cannot compute the offset of the base class. 01243 SymbolicOffsetBase = R; 01244 } 01245 01246 if (RootIsSymbolic) { 01247 // Base layers on symbolic regions may not be type-correct. 01248 // Double-check the inheritance here, and revert to a symbolic offset 01249 // if it's invalid (e.g. due to a reinterpret_cast). 01250 if (BOR->isVirtual()) { 01251 if (!Child->isVirtuallyDerivedFrom(BOR->getDecl())) 01252 SymbolicOffsetBase = R; 01253 } else { 01254 if (!isImmediateBase(Child, BOR->getDecl())) 01255 SymbolicOffsetBase = R; 01256 } 01257 } 01258 01259 // Don't bother calculating precise offsets if we already have a 01260 // symbolic offset somewhere in the chain. 01261 if (SymbolicOffsetBase) 01262 continue; 01263 01264 CharUnits BaseOffset; 01265 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(Child); 01266 if (BOR->isVirtual()) 01267 BaseOffset = Layout.getVBaseClassOffset(BOR->getDecl()); 01268 else 01269 BaseOffset = Layout.getBaseClassOffset(BOR->getDecl()); 01270 01271 // The base offset is in chars, not in bits. 01272 Offset += BaseOffset.getQuantity() * getContext().getCharWidth(); 01273 break; 01274 } 01275 case ElementRegionKind: { 01276 const ElementRegion *ER = cast<ElementRegion>(R); 01277 R = ER->getSuperRegion(); 01278 01279 QualType EleTy = ER->getValueType(); 01280 if (EleTy->isIncompleteType()) { 01281 // We cannot compute the offset of the base class. 01282 SymbolicOffsetBase = R; 01283 continue; 01284 } 01285 01286 SVal Index = ER->getIndex(); 01287 if (Optional<nonloc::ConcreteInt> CI = 01288 Index.getAs<nonloc::ConcreteInt>()) { 01289 // Don't bother calculating precise offsets if we already have a 01290 // symbolic offset somewhere in the chain. 01291 if (SymbolicOffsetBase) 01292 continue; 01293 01294 int64_t i = CI->getValue().getSExtValue(); 01295 // This type size is in bits. 01296 Offset += i * getContext().getTypeSize(EleTy); 01297 } else { 01298 // We cannot compute offset for non-concrete index. 01299 SymbolicOffsetBase = R; 01300 } 01301 break; 01302 } 01303 case FieldRegionKind: { 01304 const FieldRegion *FR = cast<FieldRegion>(R); 01305 R = FR->getSuperRegion(); 01306 01307 const RecordDecl *RD = FR->getDecl()->getParent(); 01308 if (RD->isUnion() || !RD->isCompleteDefinition()) { 01309 // We cannot compute offset for incomplete type. 01310 // For unions, we could treat everything as offset 0, but we'd rather 01311 // treat each field as a symbolic offset so they aren't stored on top 01312 // of each other, since we depend on things in typed regions actually 01313 // matching their types. 01314 SymbolicOffsetBase = R; 01315 } 01316 01317 // Don't bother calculating precise offsets if we already have a 01318 // symbolic offset somewhere in the chain. 01319 if (SymbolicOffsetBase) 01320 continue; 01321 01322 // Get the field number. 01323 unsigned idx = 0; 01324 for (RecordDecl::field_iterator FI = RD->field_begin(), 01325 FE = RD->field_end(); FI != FE; ++FI, ++idx) 01326 if (FR->getDecl() == *FI) 01327 break; 01328 01329 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 01330 // This is offset in bits. 01331 Offset += Layout.getFieldOffset(idx); 01332 break; 01333 } 01334 } 01335 } 01336 01337 Finish: 01338 if (SymbolicOffsetBase) 01339 return RegionOffset(SymbolicOffsetBase, RegionOffset::Symbolic); 01340 return RegionOffset(R, Offset); 01341 } 01342 01343 //===----------------------------------------------------------------------===// 01344 // BlockDataRegion 01345 //===----------------------------------------------------------------------===// 01346 01347 std::pair<const VarRegion *, const VarRegion *> 01348 BlockDataRegion::getCaptureRegions(const VarDecl *VD) { 01349 MemRegionManager &MemMgr = *getMemRegionManager(); 01350 const VarRegion *VR = nullptr; 01351 const VarRegion *OriginalVR = nullptr; 01352 01353 if (!VD->hasAttr<BlocksAttr>() && VD->hasLocalStorage()) { 01354 VR = MemMgr.getVarRegion(VD, this); 01355 OriginalVR = MemMgr.getVarRegion(VD, LC); 01356 } 01357 else { 01358 if (LC) { 01359 VR = MemMgr.getVarRegion(VD, LC); 01360 OriginalVR = VR; 01361 } 01362 else { 01363 VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion()); 01364 OriginalVR = MemMgr.getVarRegion(VD, LC); 01365 } 01366 } 01367 return std::make_pair(VR, OriginalVR); 01368 } 01369 01370 void BlockDataRegion::LazyInitializeReferencedVars() { 01371 if (ReferencedVars) 01372 return; 01373 01374 AnalysisDeclContext *AC = getCodeRegion()->getAnalysisDeclContext(); 01375 AnalysisDeclContext::referenced_decls_iterator I, E; 01376 std::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl()); 01377 01378 if (I == E) { 01379 ReferencedVars = (void*) 0x1; 01380 return; 01381 } 01382 01383 MemRegionManager &MemMgr = *getMemRegionManager(); 01384 llvm::BumpPtrAllocator &A = MemMgr.getAllocator(); 01385 BumpVectorContext BC(A); 01386 01387 typedef BumpVector<const MemRegion*> VarVec; 01388 VarVec *BV = (VarVec*) A.Allocate<VarVec>(); 01389 new (BV) VarVec(BC, E - I); 01390 VarVec *BVOriginal = (VarVec*) A.Allocate<VarVec>(); 01391 new (BVOriginal) VarVec(BC, E - I); 01392 01393 for ( ; I != E; ++I) { 01394 const VarRegion *VR = nullptr; 01395 const VarRegion *OriginalVR = nullptr; 01396 std::tie(VR, OriginalVR) = getCaptureRegions(*I); 01397 assert(VR); 01398 assert(OriginalVR); 01399 BV->push_back(VR, BC); 01400 BVOriginal->push_back(OriginalVR, BC); 01401 } 01402 01403 ReferencedVars = BV; 01404 OriginalVars = BVOriginal; 01405 } 01406 01407 BlockDataRegion::referenced_vars_iterator 01408 BlockDataRegion::referenced_vars_begin() const { 01409 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars(); 01410 01411 BumpVector<const MemRegion*> *Vec = 01412 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars); 01413 01414 if (Vec == (void*) 0x1) 01415 return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr); 01416 01417 BumpVector<const MemRegion*> *VecOriginal = 01418 static_cast<BumpVector<const MemRegion*>*>(OriginalVars); 01419 01420 return BlockDataRegion::referenced_vars_iterator(Vec->begin(), 01421 VecOriginal->begin()); 01422 } 01423 01424 BlockDataRegion::referenced_vars_iterator 01425 BlockDataRegion::referenced_vars_end() const { 01426 const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars(); 01427 01428 BumpVector<const MemRegion*> *Vec = 01429 static_cast<BumpVector<const MemRegion*>*>(ReferencedVars); 01430 01431 if (Vec == (void*) 0x1) 01432 return BlockDataRegion::referenced_vars_iterator(nullptr, nullptr); 01433 01434 BumpVector<const MemRegion*> *VecOriginal = 01435 static_cast<BumpVector<const MemRegion*>*>(OriginalVars); 01436 01437 return BlockDataRegion::referenced_vars_iterator(Vec->end(), 01438 VecOriginal->end()); 01439 } 01440 01441 const VarRegion *BlockDataRegion::getOriginalRegion(const VarRegion *R) const { 01442 for (referenced_vars_iterator I = referenced_vars_begin(), 01443 E = referenced_vars_end(); 01444 I != E; ++I) { 01445 if (I.getCapturedRegion() == R) 01446 return I.getOriginalRegion(); 01447 } 01448 return nullptr; 01449 } 01450 01451 //===----------------------------------------------------------------------===// 01452 // RegionAndSymbolInvalidationTraits 01453 //===----------------------------------------------------------------------===// 01454 01455 void RegionAndSymbolInvalidationTraits::setTrait(SymbolRef Sym, 01456 InvalidationKinds IK) { 01457 SymTraitsMap[Sym] |= IK; 01458 } 01459 01460 void RegionAndSymbolInvalidationTraits::setTrait(const MemRegion *MR, 01461 InvalidationKinds IK) { 01462 assert(MR); 01463 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) 01464 setTrait(SR->getSymbol(), IK); 01465 else 01466 MRTraitsMap[MR] |= IK; 01467 } 01468 01469 bool RegionAndSymbolInvalidationTraits::hasTrait(SymbolRef Sym, 01470 InvalidationKinds IK) { 01471 const_symbol_iterator I = SymTraitsMap.find(Sym); 01472 if (I != SymTraitsMap.end()) 01473 return I->second & IK; 01474 01475 return false; 01476 } 01477 01478 bool RegionAndSymbolInvalidationTraits::hasTrait(const MemRegion *MR, 01479 InvalidationKinds IK) { 01480 if (!MR) 01481 return false; 01482 01483 if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) 01484 return hasTrait(SR->getSymbol(), IK); 01485 01486 const_region_iterator I = MRTraitsMap.find(MR); 01487 if (I != MRTraitsMap.end()) 01488 return I->second & IK; 01489 01490 return false; 01491 }