zcov: / lib/Checker/MemRegion.cpp


Files: 1 Branches Taken: 67.1% 139 / 207
Generated: 2010-02-10 01:31 Branches Executed: 92.3% 191 / 207
Line Coverage: 79.8% 309 / 387


Programs: 1 Runs 2897


       1                 : //== MemRegion.cpp - Abstract memory regions for static analysis --*- 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 defines MemRegion and its subclasses.  MemRegion defines a
      11                 : //  partially-typed abstraction of memory useful for path-sensitive dataflow
      12                 : //  analyses.
      13                 : //
      14                 : //===----------------------------------------------------------------------===//
      15                 : 
      16                 : #include "clang/Analysis/AnalysisContext.h"
      17                 : #include "clang/Checker/PathSensitive/MemRegion.h"
      18                 : #include "clang/AST/CharUnits.h"
      19                 : #include "clang/AST/StmtVisitor.h"
      20                 : #include "llvm/Support/raw_ostream.h"
      21                 : 
      22                 : using namespace clang;
      23                 : 
      24                 : //===----------------------------------------------------------------------===//
      25                 : // MemRegion Construction.
      26                 : //===----------------------------------------------------------------------===//
      27                 : 
      28                 : template<typename RegionTy> struct MemRegionManagerTrait;
      29                 : 
      30                 : template <typename RegionTy, typename A1>
      31                 : RegionTy* MemRegionManager::getRegion(const A1 a1) {
      32                 :   
      33                 :   const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
      34                 :   MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1);
      35                 :   
      36                 :   llvm::FoldingSetNodeID ID;
      37                 :   RegionTy::ProfileRegion(ID, a1, superRegion);
      38                 :   void* InsertPos;
      39                 :   RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
      40                 :                                                                    InsertPos));
      41                 :   
      42                 :   if (!R) {
      43                 :     R = (RegionTy*) A.Allocate<RegionTy>();
      44                 :     new (R) RegionTy(a1, superRegion);
      45                 :     Regions.InsertNode(R, InsertPos);
      46                 :   }
      47                 :   
      48                 :   return R;
      49                 : }
      50                 : 
      51                 : template <typename RegionTy, typename A1>
      52                 : RegionTy* MemRegionManager::getSubRegion(const A1 a1,
      53            19054:                                          const MemRegion *superRegion) {
      54            19054:   llvm::FoldingSetNodeID ID;
      55            19054:   RegionTy::ProfileRegion(ID, a1, superRegion);
      56                 :   void* InsertPos;
      57                 :   RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
      58            19054:                                                                    InsertPos));
      59                 :   
                        1: branch 0 taken
                        0: branch 1 not taken
                     1383: branch 2 taken
                      251: branch 3 taken
                     2487: branch 4 taken
                      648: branch 5 taken
                       86: branch 6 taken
                      126: branch 7 taken
                      333: branch 8 taken
                      112: branch 9 taken
                     4141: branch 10 taken
                     9233: branch 11 taken
                        6: branch 12 taken
                        4: branch 13 taken
                       21: branch 14 taken
                        5: branch 15 taken
                      207: branch 16 taken
                       10: branch 17 taken
      60            19054:   if (!R) {
      61             8665:     R = (RegionTy*) A.Allocate<RegionTy>();
                        1: branch 1 taken
                        0: branch 2 not taken
                     1383: branch 5 taken
                        0: branch 6 not taken
                     2487: branch 9 taken
                        0: branch 10 not taken
                       86: branch 13 taken
                        0: branch 14 not taken
                      333: branch 17 taken
                        0: branch 18 not taken
                     4141: branch 21 taken
                        0: branch 22 not taken
                        6: branch 25 taken
                        0: branch 26 not taken
                       21: branch 29 taken
                        0: branch 30 not taken
                      207: branch 33 taken
                        0: branch 34 not taken
      62             8665:     new (R) RegionTy(a1, superRegion);
                        1: branch 0 taken
                        0: branch 1 not taken
                     1383: branch 3 taken
                        0: branch 4 not taken
                     2487: branch 6 taken
                        0: branch 7 not taken
                       86: branch 9 taken
                        0: branch 10 not taken
                      333: branch 12 taken
                        0: branch 13 not taken
                     4141: branch 15 taken
                        0: branch 16 not taken
                        6: branch 18 taken
                        0: branch 19 not taken
                       21: branch 21 taken
                        0: branch 22 not taken
                      207: branch 24 taken
                        0: branch 25 not taken
      63             8665:     Regions.InsertNode(R, InsertPos);
      64                 :   }
      65                 :   
      66            19054:   return R;
      67                 : }
      68                 : 
      69                 : template <typename RegionTy, typename A1, typename A2>
      70                 : RegionTy* MemRegionManager::getRegion(const A1 a1, const A2 a2) {
      71                 :   
      72                 :   const typename MemRegionManagerTrait<RegionTy>::SuperRegionTy *superRegion =
      73                 :   MemRegionManagerTrait<RegionTy>::getSuperRegion(*this, a1, a2);
      74                 :   
      75                 :   llvm::FoldingSetNodeID ID;
      76                 :   RegionTy::ProfileRegion(ID, a1, a2, superRegion);
      77                 :   void* InsertPos;
      78                 :   RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
      79                 :                                                                    InsertPos));
      80                 :   
      81                 :   if (!R) {
      82                 :     R = (RegionTy*) A.Allocate<RegionTy>();
      83                 :     new (R) RegionTy(a1, a2, superRegion);
      84                 :     Regions.InsertNode(R, InsertPos);
      85                 :   }
      86                 :   
      87                 :   return R;
      88                 : }
      89                 : 
      90                 : template <typename RegionTy, typename A1, typename A2>
      91                 : RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2,
      92               80:                                          const MemRegion *superRegion) {
      93                 :   
      94               80:   llvm::FoldingSetNodeID ID;
      95               80:   RegionTy::ProfileRegion(ID, a1, a2, superRegion);
      96                 :   void* InsertPos;
      97                 :   RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
      98               80:                                                                    InsertPos));
      99                 :   
                       66: branch 0 taken
                        0: branch 1 not taken
                       14: branch 2 taken
                        0: branch 3 not taken
     100               80:   if (!R) {
     101               80:     R = (RegionTy*) A.Allocate<RegionTy>();
                       66: branch 1 taken
                        0: branch 2 not taken
                       14: branch 5 taken
                        0: branch 6 not taken
     102               80:     new (R) RegionTy(a1, a2, superRegion);
                       66: branch 0 taken
                        0: branch 1 not taken
                       14: branch 3 taken
                        0: branch 4 not taken
     103               80:     Regions.InsertNode(R, InsertPos);
     104                 :   }
     105                 :   
     106               80:   return R;
     107                 : }
     108                 : 
     109                 : template <typename RegionTy, typename A1, typename A2, typename A3>
     110                 : RegionTy* MemRegionManager::getSubRegion(const A1 a1, const A2 a2, const A3 a3,
     111               66:                                          const MemRegion *superRegion) {
     112                 :   
     113               66:   llvm::FoldingSetNodeID ID;
     114               66:   RegionTy::ProfileRegion(ID, a1, a2, a3, superRegion);
     115                 :   void* InsertPos;
     116                 :   RegionTy* R = cast_or_null<RegionTy>(Regions.FindNodeOrInsertPos(ID,
     117               66:                                                                    InsertPos));
     118                 :   
                       66: branch 0 taken
                        0: branch 1 not taken
     119               66:   if (!R) {
     120               66:     R = (RegionTy*) A.Allocate<RegionTy>();
                       66: branch 1 taken
                        0: branch 2 not taken
     121               66:     new (R) RegionTy(a1, a2, a3, superRegion);
                       66: branch 0 taken
                        0: branch 1 not taken
     122               66:     Regions.InsertNode(R, InsertPos);
     123                 :   }
     124                 :   
     125               66:   return R;
     126                 : }
     127                 : 
     128                 : //===----------------------------------------------------------------------===//
     129                 : // Object destruction.
     130                 : //===----------------------------------------------------------------------===//
     131                 : 
                        0: branch 0 not taken
                        0: branch 1 not taken
                        0: branch 3 not taken
                        0: branch 4 not taken
                        0: branch 6 not taken
                        0: branch 7 not taken
     132                0: MemRegion::~MemRegion() {}
     133                 : 
     134             2138: MemRegionManager::~MemRegionManager() {
     135                 :   // All regions and their data are BumpPtrAllocated.  No need to call
     136                 :   // their destructors.
     137             2138: }
     138                 : 
     139                 : //===----------------------------------------------------------------------===//
     140                 : // Basic methods.
     141                 : //===----------------------------------------------------------------------===//
     142                 : 
     143                0: bool SubRegion::isSubRegionOf(const MemRegion* R) const {
     144                0:   const MemRegion* r = getSuperRegion();
                        0: branch 0 not taken
                        0: branch 1 not taken
     145                0:   while (r != 0) {
                        0: branch 0 not taken
                        0: branch 1 not taken
     146                0:     if (r == R)
     147                0:       return true;
                        0: branch 1 not taken
                        0: branch 2 not taken
     148                0:     if (const SubRegion* sr = dyn_cast<SubRegion>(r))
     149                0:       r = sr->getSuperRegion();
     150                 :     else
     151                0:       break;
     152                 :   }
     153                0:   return false;
     154                 : }
     155                 : 
     156            11321: MemRegionManager* SubRegion::getMemRegionManager() const {
     157            11321:   const SubRegion* r = this;
     158             5455:   do {
     159            16776:     const MemRegion *superRegion = r->getSuperRegion();
                     5455: branch 1 taken
                    11321: branch 2 taken
     160            16776:     if (const SubRegion *sr = dyn_cast<SubRegion>(superRegion)) {
     161             5455:       r = sr;
     162                 :       continue;
     163                 :     }
     164            11321:     return superRegion->getMemRegionManager();
     165                 :   } while (1);
     166                 : }
     167                 : 
     168            19549: const StackFrameContext *VarRegion::getStackFrame() const {
     169            19549:   const StackSpaceRegion *SSR = dyn_cast<StackSpaceRegion>(getMemorySpace());
                    18783: branch 0 taken
                      766: branch 1 taken
     170            19549:   return SSR ? SSR->getStackFrame() : NULL;
     171                 : }
     172                 : 
     173                 : //===----------------------------------------------------------------------===//
     174                 : // FoldingSet profiling.
     175                 : //===----------------------------------------------------------------------===//
     176                 : 
     177                0: void MemSpaceRegion::Profile(llvm::FoldingSetNodeID& ID) const {
     178                0:   ID.AddInteger((unsigned)getKind());
     179                0: }
     180                 : 
     181                0: void StackSpaceRegion::Profile(llvm::FoldingSetNodeID &ID) const {
     182                0:   ID.AddInteger((unsigned)getKind());
     183                0:   ID.AddPointer(getStackFrame());
     184                0: }
     185                 : 
     186                 : void StringRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
     187                 :                                  const StringLiteral* Str,
     188              255:                                  const MemRegion* superRegion) {
     189              255:   ID.AddInteger((unsigned) StringRegionKind);
     190              255:   ID.AddPointer(Str);
     191              255:   ID.AddPointer(superRegion);
     192              255: }
     193                 : 
     194                 : void AllocaRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
     195                 :                                  const Expr* Ex, unsigned cnt,
     196               16:                                  const MemRegion *) {
     197               16:   ID.AddInteger((unsigned) AllocaRegionKind);
     198               16:   ID.AddPointer(Ex);
     199               16:   ID.AddInteger(cnt);
     200               16: }
     201                 : 
     202                2: void AllocaRegion::Profile(llvm::FoldingSetNodeID& ID) const {
     203                2:   ProfileRegion(ID, Ex, Cnt, superRegion);
     204                2: }
     205                 : 
     206                5: void CompoundLiteralRegion::Profile(llvm::FoldingSetNodeID& ID) const {
     207                5:   CompoundLiteralRegion::ProfileRegion(ID, CL, superRegion);
     208                5: }
     209                 : 
     210                 : void CompoundLiteralRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
     211                 :                                           const CompoundLiteralExpr* CL,
     212               31:                                           const MemRegion* superRegion) {
     213               31:   ID.AddInteger((unsigned) CompoundLiteralRegionKind);
     214               31:   ID.AddPointer(CL);
     215               31:   ID.AddPointer(superRegion);
     216               31: }
     217                 : 
     218                 : void CXXThisRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
     219                 :                                   const PointerType *PT,
     220               14:                                   const MemRegion *sRegion) {
     221               14:   ID.AddInteger((unsigned) CXXThisRegionKind);
     222               14:   ID.AddPointer(PT);
     223               14:   ID.AddPointer(sRegion);
     224               14: }
     225                 : 
     226                4: void CXXThisRegion::Profile(llvm::FoldingSetNodeID &ID) const {
     227                4:   CXXThisRegion::ProfileRegion(ID, ThisPointerTy, superRegion);
     228                4: }
     229                 :                                   
     230                 : void DeclRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, const Decl* D,
     231            24012:                                const MemRegion* superRegion, Kind k) {
     232            24012:   ID.AddInteger((unsigned) k);
     233            24012:   ID.AddPointer(D);
     234            24012:   ID.AddPointer(superRegion);
     235            24012: }
     236                 : 
     237              278: void DeclRegion::Profile(llvm::FoldingSetNodeID& ID) const {
     238              278:   DeclRegion::ProfileRegion(ID, D, superRegion, getKind());
     239              278: }
     240                 : 
     241             9703: void VarRegion::Profile(llvm::FoldingSetNodeID &ID) const {
     242             9703:   VarRegion::ProfileRegion(ID, getDecl(), superRegion);
     243             9703: }
     244                 : 
     245                 : void SymbolicRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, SymbolRef sym,
     246             4067:                                    const MemRegion *sreg) {
     247             4067:   ID.AddInteger((unsigned) MemRegion::SymbolicRegionKind);
     248             4067:   ID.Add(sym);
     249             4067:   ID.AddPointer(sreg);
     250             4067: }
     251                 : 
     252              932: void SymbolicRegion::Profile(llvm::FoldingSetNodeID& ID) const {
     253              932:   SymbolicRegion::ProfileRegion(ID, sym, getSuperRegion());
     254              932: }
     255                 : 
     256                 : void ElementRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
     257                 :                                   QualType ElementType, SVal Idx,
     258             2340:                                   const MemRegion* superRegion) {
     259             2340:   ID.AddInteger(MemRegion::ElementRegionKind);
     260             2340:   ID.Add(ElementType);
     261             2340:   ID.AddPointer(superRegion);
     262             2340:   Idx.Profile(ID);
     263             2340: }
     264                 : 
     265              589: void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const {
     266              589:   ElementRegion::ProfileRegion(ID, ElementType, Index, superRegion);
     267              589: }
     268                 : 
     269                 : void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
     270                 :                                        const FunctionDecl *FD,
     271             1977:                                        const MemRegion*) {
     272             1977:   ID.AddInteger(MemRegion::FunctionTextRegionKind);
     273             1977:   ID.AddPointer(FD);
     274             1977: }
     275                 : 
     276              343: void FunctionTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
     277              343:   FunctionTextRegion::ProfileRegion(ID, FD, superRegion);
     278              343: }
     279                 : 
     280                 : void BlockTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
     281                 :                                     const BlockDecl *BD, CanQualType,
     282                 :                                     const AnalysisContext *AC,
     283               68:                                     const MemRegion*) {
     284               68:   ID.AddInteger(MemRegion::BlockTextRegionKind);
     285               68:   ID.AddPointer(BD);
     286               68: }
     287                 : 
     288                2: void BlockTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {
     289                2:   BlockTextRegion::ProfileRegion(ID, BD, locTy, AC, superRegion);
     290                2: }
     291                 : 
     292                 : void BlockDataRegion::ProfileRegion(llvm::FoldingSetNodeID& ID,
     293                 :                                     const BlockTextRegion *BC,
     294                 :                                     const LocationContext *LC,
     295               66:                                     const MemRegion *sReg) {
     296               66:   ID.AddInteger(MemRegion::BlockDataRegionKind);
     297               66:   ID.AddPointer(BC);
     298               66:   ID.AddPointer(LC);
     299               66:   ID.AddPointer(sReg);
     300               66: }
     301                 : 
     302                0: void BlockDataRegion::Profile(llvm::FoldingSetNodeID& ID) const {
     303                0:   BlockDataRegion::ProfileRegion(ID, BC, LC, getSuperRegion());
     304                0: }
     305                 : 
     306                 : void CXXObjectRegion::ProfileRegion(llvm::FoldingSetNodeID &ID,
     307                 :                                     Expr const *Ex,
     308                1:                                     const MemRegion *sReg) {
     309                1:   ID.AddPointer(Ex);
     310                1:   ID.AddPointer(sReg);
     311                1: }
     312                 : 
     313                0: void CXXObjectRegion::Profile(llvm::FoldingSetNodeID &ID) const {
     314                0:   ProfileRegion(ID, Ex, getSuperRegion());
     315                0: }
     316                 : 
     317                 : //===----------------------------------------------------------------------===//
     318                 : // Region pretty-printing.
     319                 : //===----------------------------------------------------------------------===//
     320                 : 
     321                0: void MemRegion::dump() const {
     322                0:   dumpToStream(llvm::errs());
     323                0: }
     324                 : 
     325               92: std::string MemRegion::getString() const {
     326               92:   std::string s;
     327               92:   llvm::raw_string_ostream os(s);
     328               92:   dumpToStream(os);
     329               92:   return os.str();
     330                 : }
     331                 : 
     332                0: void MemRegion::dumpToStream(llvm::raw_ostream& os) const {
     333                0:   os << "<Unknown Region>";
     334                0: }
     335                 : 
     336                0: void AllocaRegion::dumpToStream(llvm::raw_ostream& os) const {
     337                0:   os << "alloca{" << (void*) Ex << ',' << Cnt << '}';
     338                0: }
     339                 : 
     340                0: void FunctionTextRegion::dumpToStream(llvm::raw_ostream& os) const {
     341                0:   os << "code{" << getDecl()->getDeclName().getAsString() << '}';
     342                0: }
     343                 : 
     344                0: void BlockTextRegion::dumpToStream(llvm::raw_ostream& os) const {
     345                0:   os << "block_code{" << (void*) this << '}';
     346                0: }
     347                 : 
     348                0: void BlockDataRegion::dumpToStream(llvm::raw_ostream& os) const {
     349                0:   os << "block_data{" << BC << '}';
     350                0: }
     351                 : 
     352                 : 
     353                0: void CompoundLiteralRegion::dumpToStream(llvm::raw_ostream& os) const {
     354                 :   // FIXME: More elaborate pretty-printing.
     355                0:   os << "{ " << (void*) CL <<  " }";
     356                0: }
     357                 : 
     358                0: void CXXThisRegion::dumpToStream(llvm::raw_ostream &os) const {
     359                0:   os << "this";
     360                0: }
     361                 : 
     362                0: void ElementRegion::dumpToStream(llvm::raw_ostream& os) const {
     363                 :   os << "element{" << superRegion << ','
     364                0:      << Index << ',' << getElementType().getAsString() << '}';
     365                0: }
     366                 : 
     367                0: void FieldRegion::dumpToStream(llvm::raw_ostream& os) const {
     368                0:   os << superRegion << "->" << getDecl()->getNameAsString();
     369                0: }
     370                 : 
     371                0: void ObjCIvarRegion::dumpToStream(llvm::raw_ostream& os) const {
     372                0:   os << "ivar{" << superRegion << ',' << getDecl()->getNameAsString() << '}';
     373                0: }
     374                 : 
     375                0: void StringRegion::dumpToStream(llvm::raw_ostream& os) const {
     376                0:   Str->printPretty(os, 0, PrintingPolicy(getContext().getLangOptions()));
     377                0: }
     378                 : 
     379                0: void SymbolicRegion::dumpToStream(llvm::raw_ostream& os) const {
     380                0:   os << "SymRegion{" << sym << '}';
     381                0: }
     382                 : 
     383               92: void VarRegion::dumpToStream(llvm::raw_ostream& os) const {
     384               92:   os << cast<VarDecl>(D)->getNameAsString();
     385               92: }
     386                 : 
     387                0: void RegionRawOffset::dump() const {
     388                0:   dumpToStream(llvm::errs());
     389                0: }
     390                 : 
     391                0: void RegionRawOffset::dumpToStream(llvm::raw_ostream& os) const {
     392                0:   os << "raw_offset{" << getRegion() << ',' << getByteOffset() << '}';
     393                0: }
     394                 : 
     395                 : //===----------------------------------------------------------------------===//
     396                 : // MemRegionManager methods.
     397                 : //===----------------------------------------------------------------------===//
     398                 : 
     399                 : template <typename REG>
     400             5527: const REG *MemRegionManager::LazyAllocate(REG*& region) {
                      873: branch 0 taken
                      827: branch 1 taken
                     1168: branch 2 taken
                     1993: branch 3 taken
                     1993: branch 4 taken
                     1993: branch 5 taken
                      308: branch 6 taken
                      358: branch 7 taken
     401             5527:   if (!region) {
     402             2349:     region = (REG*) A.Allocate<REG>();
                      873: branch 1 taken
                        0: branch 2 not taken
                     1168: branch 5 taken
                        0: branch 6 not taken
                        0: branch 9 not taken
                        0: branch 10 not taken
                      308: branch 13 taken
                        0: branch 14 not taken
     403             2349:     new (region) REG(this);
     404                 :   }
     405                 : 
     406             5527:   return region;
     407                 : }
     408                 : 
     409                 : template <typename REG, typename ARG>
     410             2545: const REG *MemRegionManager::LazyAllocate(REG*& region, ARG a) {
                     1107: branch 0 taken
                        0: branch 1 not taken
                     1438: branch 2 taken
                        0: branch 3 not taken
     411             2545:   if (!region) {
     412             2545:     region = (REG*) A.Allocate<REG>();
                     1107: branch 1 taken
                        0: branch 2 not taken
                     1438: branch 5 taken
                        0: branch 6 not taken
     413             2545:     new (region) REG(this, a);
     414                 :   }
     415                 :   
     416             2545:   return region;
     417                 : }
     418                 : 
     419                 : const StackLocalsSpaceRegion*
     420             9089: MemRegionManager::getStackLocalsRegion(const StackFrameContext *STC) {
                        0: branch 0 not taken
                     9089: branch 1 taken
     421             9089:   assert(STC);
                     7651: branch 0 taken
                     1438: branch 1 taken
     422             9089:   if (STC == cachedStackLocalsFrame)
     423             7651:     return cachedStackLocalsRegion;
     424             1438:   cachedStackLocalsFrame = STC;
     425             1438:   return LazyAllocate(cachedStackLocalsRegion, STC);
     426                 : }
     427                 : 
     428                 : const StackArgumentsSpaceRegion *
     429             3896: MemRegionManager::getStackArgumentsRegion(const StackFrameContext *STC) {
                        0: branch 0 not taken
                     3896: branch 1 taken
     430             3896:   assert(STC);
                     2789: branch 0 taken
                     1107: branch 1 taken
     431             3896:   if (STC == cachedStackArgumentsFrame)
     432             2789:     return cachedStackArgumentsRegion;
     433                 :   
     434             1107:   cachedStackArgumentsFrame = STC;
     435             1107:   return LazyAllocate(cachedStackArgumentsRegion, STC);
     436                 : }
     437                 : 
     438              666: const GlobalsSpaceRegion *MemRegionManager::getGlobalsRegion() {
     439              666:   return LazyAllocate(globals);
     440                 : }
     441                 : 
     442                0: const HeapSpaceRegion *MemRegionManager::getHeapRegion() {
     443                0:   return LazyAllocate(heap);
     444                 : }
     445                 : 
     446             3161: const MemSpaceRegion *MemRegionManager::getUnknownRegion() {
     447             3161:   return LazyAllocate(unknown);
     448                 : }
     449                 : 
     450             1700: const MemSpaceRegion *MemRegionManager::getCodeRegion() {
     451             1700:   return LazyAllocate(code);
     452                 : }
     453                 : 
     454                 : //===----------------------------------------------------------------------===//
     455                 : // Constructing regions.
     456                 : //===----------------------------------------------------------------------===//
     457                 : 
     458              217: const StringRegion* MemRegionManager::getStringRegion(const StringLiteral* Str) {
     459              217:   return getSubRegion<StringRegion>(Str, getGlobalsRegion());
     460                 : }
     461                 : 
     462                 : const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D,
     463            13343:                                                 const LocationContext *LC) {
     464            13343:   const MemRegion *sReg = 0;
     465                 : 
                    12894: branch 1 taken
                      449: branch 2 taken
     466            13343:   if (D->hasLocalStorage()) {    
     467                 :     // FIXME: Once we implement scope handling, we will need to properly lookup
     468                 :     // 'D' to the proper LocationContext.
     469            12894:     const DeclContext *DC = D->getDeclContext();
     470            12894:     const StackFrameContext *STC = LC->getStackFrameForDeclContext(DC);
     471                 : 
                       26: branch 0 taken
                    12868: branch 1 taken
     472            12894:     if (!STC)
     473               26:       sReg = getUnknownRegion();
     474                 :     else {
     475                 :       sReg = isa<ParmVarDecl>(D) || isa<ImplicitParamDecl>(D)
     476                 :             ? static_cast<const MemRegion*>(getStackArgumentsRegion(STC))
                     9827: branch 1 taken
                     3041: branch 2 taken
                      845: branch 4 taken
                     8982: branch 5 taken
     477            12868:             : static_cast<const MemRegion*>(getStackLocalsRegion(STC));
     478                 :     }
     479                 :   }
     480                 :   else {
     481              449:     sReg = getGlobalsRegion();
     482                 :   }
     483                 :   
     484            13343:   return getSubRegion<VarRegion>(D, sReg);
     485                 : }
     486                 : 
     487                 : const VarRegion *MemRegionManager::getVarRegion(const VarDecl *D,
     488               31:                                                 const MemRegion *superR) {
     489               31:   return getSubRegion<VarRegion>(D, superR);
     490                 : }
     491                 : 
     492                 : const BlockDataRegion *
     493                 : MemRegionManager::getBlockDataRegion(const BlockTextRegion *BC,
     494               66:                                      const LocationContext *LC) {
     495               66:   const MemRegion *sReg = 0;
     496                 :   
                       66: branch 0 taken
                        0: branch 1 not taken
     497               66:   if (LC) {    
     498                 :     // FIXME: Once we implement scope handling, we want the parent region
     499                 :     // to be the scope.  
     500               66:     const StackFrameContext *STC = LC->getCurrentStackFrame();
                        0: branch 0 not taken
                       66: branch 1 taken
     501               66:     assert(STC);
     502               66:     sReg = getStackLocalsRegion(STC);
     503                 :   }
     504                 :   else {
     505                 :     // We allow 'LC' to be NULL for cases where want BlockDataRegions
     506                 :     // without context-sensitivity.
     507                0:     sReg = getUnknownRegion();
     508                 :   }
     509                 : 
     510               66:   return getSubRegion<BlockDataRegion>(BC, LC, sReg);
     511                 : }
     512                 : 
     513                 : const CompoundLiteralRegion*
     514                 : MemRegionManager::getCompoundLiteralRegion(const CompoundLiteralExpr* CL,
     515               26:                                            const LocationContext *LC) {
     516                 :   
     517               26:   const MemRegion *sReg = 0;
     518                 :   
                        0: branch 1 not taken
                       26: branch 2 taken
     519               26:   if (CL->isFileScope())
     520                0:     sReg = getGlobalsRegion();
     521                 :   else {
     522               26:     const StackFrameContext *STC = LC->getCurrentStackFrame();
                        0: branch 0 not taken
                       26: branch 1 taken
     523               26:     assert(STC);
     524               26:     sReg = getStackLocalsRegion(STC);
     525                 :   }
     526                 :   
     527               26:   return getSubRegion<CompoundLiteralRegion>(CL, sReg);
     528                 : }
     529                 : 
     530                 : const ElementRegion*
     531                 : MemRegionManager::getElementRegion(QualType elementType, SVal Idx,
     532                 :                                    const MemRegion* superRegion,
     533             1751:                                    ASTContext& Ctx){
     534                 : 
     535             1751:   QualType T = Ctx.getCanonicalType(elementType);
     536                 : 
     537             1751:   llvm::FoldingSetNodeID ID;
     538             1751:   ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
     539                 : 
     540                 :   void* InsertPos;
     541             1751:   MemRegion* data = Regions.FindNodeOrInsertPos(ID, InsertPos);
     542             1751:   ElementRegion* R = cast_or_null<ElementRegion>(data);
     543                 : 
                     1332: branch 0 taken
                      419: branch 1 taken
     544             1751:   if (!R) {
     545             1332:     R = (ElementRegion*) A.Allocate<ElementRegion>();
                     1332: branch 1 taken
                        0: branch 2 not taken
     546             1332:     new (R) ElementRegion(T, Idx, superRegion);
                     1332: branch 0 taken
                        0: branch 1 not taken
     547             1332:     Regions.InsertNode(R, InsertPos);
     548                 :   }
     549                 : 
     550             1751:   return R;
     551                 : }
     552                 : 
     553                 : const FunctionTextRegion *
     554             1634: MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) {
     555             1634:   return getSubRegion<FunctionTextRegion>(FD, getCodeRegion());
     556                 : }
     557                 : 
     558                 : const BlockTextRegion *
     559                 : MemRegionManager::getBlockTextRegion(const BlockDecl *BD, CanQualType locTy,
     560               66:                                      AnalysisContext *AC) {
     561               66:   return getSubRegion<BlockTextRegion>(BD, locTy, AC, getCodeRegion());
     562                 : }
     563                 : 
     564                 : 
     565                 : /// getSymbolicRegion - Retrieve or create a "symbolic" memory region.
     566             3135: const SymbolicRegion *MemRegionManager::getSymbolicRegion(SymbolRef sym) {
     567             3135:   return getSubRegion<SymbolicRegion>(sym, getUnknownRegion());
     568                 : }
     569                 : 
     570                 : const FieldRegion*
     571                 : MemRegionManager::getFieldRegion(const FieldDecl* d,
     572              445:                                  const MemRegion* superRegion){
     573              445:   return getSubRegion<FieldRegion>(d, superRegion);
     574                 : }
     575                 : 
     576                 : const ObjCIvarRegion*
     577                 : MemRegionManager::getObjCIvarRegion(const ObjCIvarDecl* d,
     578              212:                                     const MemRegion* superRegion) {
     579              212:   return getSubRegion<ObjCIvarRegion>(d, superRegion);
     580                 : }
     581                 : 
     582                 : const CXXObjectRegion*
     583                 : MemRegionManager::getCXXObjectRegion(Expr const *E,
     584                1:                                      LocationContext const *LC) {
     585                1:   const StackFrameContext *SFC = LC->getCurrentStackFrame();
                        0: branch 0 not taken
                        1: branch 1 taken
     586                1:   assert(SFC);
     587                1:   return getSubRegion<CXXObjectRegion>(E, getStackLocalsRegion(SFC));
     588                 : }
     589                 : 
     590                 : const CXXThisRegion*
     591                 : MemRegionManager::getCXXThisRegion(QualType thisPointerTy,
     592               10:                                    const LocationContext *LC) {
     593               10:   const StackFrameContext *STC = LC->getCurrentStackFrame();
                        0: branch 0 not taken
                       10: branch 1 taken
     594               10:   assert(STC);
     595               10:   const PointerType *PT = thisPointerTy->getAs<PointerType>();
                        0: branch 0 not taken
                       10: branch 1 taken
     596               10:   assert(PT);
     597               10:   return getSubRegion<CXXThisRegion>(PT, getStackArgumentsRegion(STC));
     598                 : }
     599                 : 
     600                 : const AllocaRegion*
     601                 : MemRegionManager::getAllocaRegion(const Expr* E, unsigned cnt,
     602               14:                                   const LocationContext *LC) {
     603               14:   const StackFrameContext *STC = LC->getCurrentStackFrame();
                        0: branch 0 not taken
                       14: branch 1 taken
     604               14:   assert(STC);
     605               14:   return getSubRegion<AllocaRegion>(E, cnt, getStackLocalsRegion(STC));
     606                 : }
     607                 : 
     608            27522: const MemSpaceRegion *MemRegion::getMemorySpace() const {
     609            27522:   const MemRegion *R = this;
     610            27522:   const SubRegion* SR = dyn_cast<SubRegion>(this);
     611                 : 
                    28338: branch 0 taken
                    27522: branch 1 taken
     612            83382:   while (SR) {
     613            28338:     R = SR->getSuperRegion();
     614            28338:     SR = dyn_cast<SubRegion>(R);
     615                 :   }
     616                 : 
     617            27522:   return dyn_cast<MemSpaceRegion>(R);
     618                 : }
     619                 : 
     620             4235: bool MemRegion::hasStackStorage() const {
     621             4235:   return isa<StackSpaceRegion>(getMemorySpace());
     622                 : }
     623                 : 
     624              395: bool MemRegion::hasStackNonParametersStorage() const {
     625              395:   return isa<StackLocalsSpaceRegion>(getMemorySpace());
     626                 : }
     627                 : 
     628                0: bool MemRegion::hasStackParametersStorage() const {
     629                0:   return isa<StackArgumentsSpaceRegion>(getMemorySpace());
     630                 : }
     631                 : 
     632             1488: bool MemRegion::hasGlobalsOrParametersStorage() const {
     633             1488:   const MemSpaceRegion *MS = getMemorySpace();
     634                 :   return isa<StackArgumentsSpaceRegion>(MS) ||
                      987: branch 1 taken
                      501: branch 2 taken
                       60: branch 4 taken
                      927: branch 5 taken
     635             1488:          isa<GlobalsSpaceRegion>(MS);
     636                 : }
     637                 : 
     638                 : // getBaseRegion strips away all elements and fields, and get the base region
     639                 : // of them.
     640             1194: const MemRegion *MemRegion::getBaseRegion() const {
     641             1194:   const MemRegion *R = this;
     642              212:   while (true) {
                      177: branch 1 taken
                     1229: branch 2 taken
     643             1406:     if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
     644              177:       R = ER->getSuperRegion();
     645              177:       continue;
     646                 :     }
                       35: branch 1 taken
                     1194: branch 2 taken
     647             1229:     if (const FieldRegion *FR = dyn_cast<FieldRegion>(R)) {
     648               35:       R = FR->getSuperRegion();
     649               35:       continue;
     650                 :     }
     651                 :     break;
     652                 :   }
     653             1194:   return R;
     654                 : }
     655                 : 
     656                 : //===----------------------------------------------------------------------===//
     657                 : // View handling.
     658                 : //===----------------------------------------------------------------------===//
     659                 : 
     660            28162: const MemRegion *MemRegion::StripCasts() const {
     661            28162:   const MemRegion *R = this;
     662             1613:   while (true) {
                     2511: branch 1 taken
                    27264: branch 2 taken
     663            29775:     if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
     664                 :       // FIXME: generalize.  Essentially we want to strip away ElementRegions
     665                 :       // that were layered on a symbolic region because of casts.  We only
     666                 :       // want to strip away ElementRegions, however, where the index is 0.
     667             2511:       SVal index = ER->getIndex();
                     2277: branch 1 taken
                      234: branch 2 taken
     668             2511:       if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
                     1613: branch 2 taken
                      664: branch 3 taken
     669             2277:         if (CI->getValue().getSExtValue() == 0) {
     670             1613:           R = ER->getSuperRegion();
     671                 :           continue;
     672                 :         }
                      898: branch 1 taken
                     1613: branch 2 taken
     673             2511:       }
     674                 :     }
     675                 :     break;
     676                 :   }
     677            28162:   return R;
     678                 : }
     679                 : 
     680                 : // FIXME: Merge with the implementation of the same method in Store.cpp
     681             1028: static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
                       58: branch 2 taken
                      970: branch 3 taken
     682             1028:   if (const RecordType *RT = Ty->getAs<RecordType>()) {
     683               58:     const RecordDecl *D = RT->getDecl();
                        0: branch 1 not taken
                       58: branch 2 taken
     684               58:     if (!D->getDefinition(Ctx))
     685                0:       return false;
     686                 :   }
     687                 : 
     688             1028:   return true;
     689                 : }
     690                 : 
     691             3154: RegionRawOffset ElementRegion::getAsRawOffset() const {
     692             3154:   CharUnits offset = CharUnits::Zero();
     693             3154:   const ElementRegion *ER = this;
     694             3154:   const MemRegion *superR = NULL;
     695             3154:   ASTContext &C = getContext();
     696                 : 
     697                 :   // FIXME: Handle multi-dimensional arrays.
     698                 : 
                        0: branch 1 not taken
                     2714: branch 2 taken
                      448: branch 3 taken
                     3162: branch 4 taken
                     2706: branch 5 taken
     699            12184:   while (ER) {
     700             3162:     superR = ER->getSuperRegion();
     701                 : 
     702                 :     // FIXME: generalize to symbolic offsets.
     703             3162:     SVal index = ER->getIndex();
                     2714: branch 1 taken
                      448: branch 2 taken
     704             3162:     if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
     705                 :       // Update the offset.
     706             2714:       int64_t i = CI->getValue().getSExtValue();
     707                 : 
                     1028: branch 0 taken
                     1686: branch 1 taken
     708             2714:       if (i != 0) {
     709             1028:         QualType elemType = ER->getElementType();
     710                 : 
     711                 :         // If we are pointing to an incomplete type, go no further.
                        0: branch 1 not taken
                     1028: branch 2 taken
     712             1028:         if (!IsCompleteType(C, elemType)) {
     713                0:           superR = ER;
     714                0:           break;
     715                 :         }
     716                 : 
     717             1028:         CharUnits size = C.getTypeSizeInChars(elemType);
     718             1028:         offset += (i * size);
     719                 :       }
     720                 : 
     721                 :       // Go to the next ElementRegion (if any).
     722             2714:       ER = dyn_cast<ElementRegion>(superR);
     723             2714:       continue;
     724                 :     }
     725                 : 
     726              896:     return NULL;
     727                 :   }
     728                 : 
                        0: branch 0 not taken
                     2706: branch 1 taken
     729             2706:   assert(superR && "super region cannot be NULL");
     730             2706:   return RegionRawOffset(superR, offset.getQuantity());
     731                 : }
     732                 : 
     733                 : //===----------------------------------------------------------------------===//
     734                 : // BlockDataRegion
     735                 : //===----------------------------------------------------------------------===//
     736                 : 
     737              252: void BlockDataRegion::LazyInitializeReferencedVars() {
                      192: branch 0 taken
                       60: branch 1 taken
     738              252:   if (ReferencedVars)
     739              192:     return;
     740                 : 
     741               60:   AnalysisContext *AC = getCodeRegion()->getAnalysisContext();
     742                 :   AnalysisContext::referenced_decls_iterator I, E;
     743               60:   llvm::tie(I, E) = AC->getReferencedBlockVars(BC->getDecl());
     744                 :   
                        6: branch 0 taken
                       54: branch 1 taken
     745               60:   if (I == E) {
     746                6:     ReferencedVars = (void*) 0x1;
     747                6:     return;
     748                 :   }
     749                 :     
     750               54:   MemRegionManager &MemMgr = *getMemRegionManager();
     751               54:   llvm::BumpPtrAllocator &A = MemMgr.getAllocator();
     752               54:   BumpVectorContext BC(A);
     753                 :   
     754                 :   typedef BumpVector<const MemRegion*> VarVec;
     755               54:   VarVec *BV = (VarVec*) A.Allocate<VarVec>();
                       54: branch 1 taken
                        0: branch 2 not taken
     756               54:   new (BV) VarVec(BC, E - I);
     757                 :   
                       76: branch 0 taken
                       54: branch 1 taken
     758              130:   for ( ; I != E; ++I) {
     759               76:     const VarDecl *VD = *I;
     760               76:     const VarRegion *VR = 0;
     761                 :     
                       36: branch 1 taken
                       40: branch 2 taken
                       31: branch 4 taken
                        5: branch 5 taken
                       31: branch 6 taken
                       45: branch 7 taken
     762               76:     if (!VD->getAttr<BlocksAttr>() && VD->hasLocalStorage())
     763               31:       VR = MemMgr.getVarRegion(VD, this);
     764                 :     else {
                       45: branch 0 taken
                        0: branch 1 not taken
     765               45:       if (LC)
     766               45:         VR = MemMgr.getVarRegion(VD, LC);
     767                 :       else {
     768                0:         VR = MemMgr.getVarRegion(VD, MemMgr.getUnknownRegion());
     769                 :       }
     770                 :     }
     771                 :     
                        0: branch 0 not taken
                       76: branch 1 taken
     772               76:     assert(VR);
     773               76:     BV->push_back(VR, BC);
     774                 :   }
     775                 :   
     776               54:   ReferencedVars = BV;
     777                 : }
     778                 : 
     779                 : BlockDataRegion::referenced_vars_iterator
     780              126: BlockDataRegion::referenced_vars_begin() const {
     781              126:   const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
     782                 : 
     783                 :   BumpVector<const MemRegion*> *Vec =
     784              126:     static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
     785                 :   
     786                 :   return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
                      119: branch 0 taken
                        7: branch 1 taken
     787              126:                                                    NULL : Vec->begin());
     788                 : }
     789                 : 
     790                 : BlockDataRegion::referenced_vars_iterator
     791              126: BlockDataRegion::referenced_vars_end() const {
     792              126:   const_cast<BlockDataRegion*>(this)->LazyInitializeReferencedVars();
     793                 : 
     794                 :   BumpVector<const MemRegion*> *Vec =
     795              126:     static_cast<BumpVector<const MemRegion*>*>(ReferencedVars);
     796                 :   
     797                 :   return BlockDataRegion::referenced_vars_iterator(Vec == (void*) 0x1 ?
                      119: branch 0 taken
                        7: branch 1 taken
     798              126:                                                    NULL : Vec->end());
     799                 : }

Generated: 2010-02-10 01:31 by zcov