]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - contrib/llvm/tools/clang/lib/StaticAnalyzer/Core/BasicStore.cpp
Copy head to stable/9 as part of 9.0-RELEASE release cycle.
[FreeBSD/stable/9.git] / contrib / llvm / tools / clang / lib / StaticAnalyzer / Core / BasicStore.cpp
1 //== BasicStore.cpp - Basic map from Locations to Values --------*- C++ -*--==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  This file defined the BasicStore and BasicStoreManager classes.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "clang/AST/DeclCXX.h"
15 #include "clang/AST/ExprObjC.h"
16 #include "clang/Analysis/Analyses/LiveVariables.h"
17 #include "clang/Analysis/AnalysisContext.h"
18 #include "clang/StaticAnalyzer/Core/PathSensitive/GRState.h"
19 #include "llvm/ADT/ImmutableMap.h"
20
21 using namespace clang;
22 using namespace ento;
23
24 typedef llvm::ImmutableMap<const MemRegion*,SVal> BindingsTy;
25
26 namespace {
27
28 class BasicStoreSubRegionMap : public SubRegionMap {
29 public:
30   BasicStoreSubRegionMap() {}
31
32   bool iterSubRegions(const MemRegion* R, Visitor& V) const {
33     return true; // Do nothing.  No subregions.
34   }
35 };
36
37 class BasicStoreManager : public StoreManager {
38   BindingsTy::Factory VBFactory;
39 public:
40   BasicStoreManager(GRStateManager& mgr)
41     : StoreManager(mgr), VBFactory(mgr.getAllocator()) {}
42
43   ~BasicStoreManager() {}
44
45   SubRegionMap *getSubRegionMap(Store store) {
46     return new BasicStoreSubRegionMap();
47   }
48
49   SVal Retrieve(Store store, Loc loc, QualType T = QualType());
50
51   StoreRef invalidateRegion(Store store, const MemRegion *R, const Expr *E,
52                             unsigned Count, InvalidatedSymbols &IS);
53
54   StoreRef invalidateRegions(Store store, const MemRegion * const *Begin,
55                              const MemRegion * const *End, const Expr *E,
56                              unsigned Count, InvalidatedSymbols &IS,
57                              bool invalidateGlobals,
58                              InvalidatedRegions *Regions);
59
60   StoreRef scanForIvars(Stmt *B, const Decl* SelfDecl,
61                         const MemRegion *SelfRegion, Store St);
62
63   StoreRef Bind(Store St, Loc loc, SVal V);
64   StoreRef Remove(Store St, Loc loc);
65   StoreRef getInitialStore(const LocationContext *InitLoc);
66
67   StoreRef BindCompoundLiteral(Store store, const CompoundLiteralExpr*,
68                             const LocationContext*, SVal val) {
69     return StoreRef(store, *this);
70   }
71
72   /// ArrayToPointer - Used by ExprEngine::VistCast to handle implicit
73   ///  conversions between arrays and pointers.
74   SVal ArrayToPointer(Loc Array) { return Array; }
75
76   /// removeDeadBindings - Scans a BasicStore of 'state' for dead values.
77   ///  It updatees the GRState object in place with the values removed.
78   StoreRef removeDeadBindings(Store store, const StackFrameContext *LCtx,
79                               SymbolReaper& SymReaper,
80                           llvm::SmallVectorImpl<const MemRegion*>& RegionRoots);
81
82   void iterBindings(Store store, BindingsHandler& f);
83
84   StoreRef BindDecl(Store store, const VarRegion *VR, SVal InitVal) {
85     return BindDeclInternal(store, VR, &InitVal);
86   }
87
88   StoreRef BindDeclWithNoInit(Store store, const VarRegion *VR) {
89     return BindDeclInternal(store, VR, 0);
90   }
91
92   StoreRef BindDeclInternal(Store store, const VarRegion *VR, SVal *InitVal);
93
94   static inline BindingsTy GetBindings(Store store) {
95     return BindingsTy(static_cast<const BindingsTy::TreeTy*>(store));
96   }
97
98   void print(Store store, llvm::raw_ostream& Out, const char* nl,
99              const char *sep);
100
101 private:
102   SVal LazyRetrieve(Store store, const TypedRegion *R);
103 };
104
105 } // end anonymous namespace
106
107
108 StoreManager* ento::CreateBasicStoreManager(GRStateManager& StMgr) {
109   return new BasicStoreManager(StMgr);
110 }
111
112 static bool isHigherOrderRawPtr(QualType T, ASTContext &C) {
113   bool foundPointer = false;
114   while (1) {
115     const PointerType *PT = T->getAs<PointerType>();
116     if (!PT) {
117       if (!foundPointer)
118         return false;
119
120       // intptr_t* or intptr_t**, etc?
121       if (T->isIntegerType() && C.getTypeSize(T) == C.getTypeSize(C.VoidPtrTy))
122         return true;
123
124       QualType X = C.getCanonicalType(T).getUnqualifiedType();
125       return X == C.VoidTy;
126     }
127
128     foundPointer = true;
129     T = PT->getPointeeType();
130   }
131 }
132
133 SVal BasicStoreManager::LazyRetrieve(Store store, const TypedRegion *R) {
134   const VarRegion *VR = dyn_cast<VarRegion>(R);
135   if (!VR)
136     return UnknownVal();
137
138   const VarDecl *VD = VR->getDecl();
139   QualType T = VD->getType();
140
141   // Only handle simple types that we can symbolicate.
142   if (!SymbolManager::canSymbolicate(T) || !T->isScalarType())
143     return UnknownVal();
144
145   // Globals and parameters start with symbolic values.
146   // Local variables initially are undefined.
147
148   // Non-static globals may have had their values reset by invalidateRegions.
149   const MemSpaceRegion *MS = VR->getMemorySpace();
150   if (isa<NonStaticGlobalSpaceRegion>(MS)) {
151     BindingsTy B = GetBindings(store);
152     // FIXME: Copy-and-pasted from RegionStore.cpp.
153     if (BindingsTy::data_type *Val = B.lookup(MS)) {
154       if (SymbolRef parentSym = Val->getAsSymbol())
155         return svalBuilder.getDerivedRegionValueSymbolVal(parentSym, R);
156
157       if (Val->isZeroConstant())
158         return svalBuilder.makeZeroVal(T);
159
160       if (Val->isUnknownOrUndef())
161         return *Val;
162
163       assert(0 && "Unknown default value.");
164     }
165   }
166
167   if (VR->hasGlobalsOrParametersStorage() ||
168       isa<UnknownSpaceRegion>(VR->getMemorySpace()))
169     return svalBuilder.getRegionValueSymbolVal(R);
170
171   return UndefinedVal();
172 }
173
174 SVal BasicStoreManager::Retrieve(Store store, Loc loc, QualType T) {
175   if (isa<UnknownVal>(loc))
176     return UnknownVal();
177
178   assert(!isa<UndefinedVal>(loc));
179
180   switch (loc.getSubKind()) {
181
182     case loc::MemRegionKind: {
183       const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
184
185       if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R) ||
186           isa<CXXThisRegion>(R)))
187         return UnknownVal();
188
189       BindingsTy B = GetBindings(store);
190       BindingsTy::data_type *Val = B.lookup(R);
191       const TypedRegion *TR = cast<TypedRegion>(R);
192
193       if (Val)
194         return CastRetrievedVal(*Val, TR, T);
195
196       SVal V = LazyRetrieve(store, TR);
197       return V.isUnknownOrUndef() ? V : CastRetrievedVal(V, TR, T);
198     }
199
200     case loc::ObjCPropRefKind:
201     case loc::ConcreteIntKind:
202       // Support direct accesses to memory.  It's up to individual checkers
203       // to flag an error.
204       return UnknownVal();
205
206     default:
207       assert (false && "Invalid Loc.");
208       break;
209   }
210
211   return UnknownVal();
212 }
213
214 StoreRef BasicStoreManager::Bind(Store store, Loc loc, SVal V) {
215   if (isa<loc::ConcreteInt>(loc))
216     return StoreRef(store, *this);
217
218   const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
219
220   // Special case: a default symbol assigned to the NonStaticGlobalsSpaceRegion
221   //  that is used to derive other symbols.
222   if (isa<NonStaticGlobalSpaceRegion>(R)) {
223     BindingsTy B = GetBindings(store);
224     return StoreRef(VBFactory.add(B, R, V).getRoot(), *this);
225   }
226
227   // Special case: handle store of pointer values (Loc) to pointers via
228   // a cast to intXX_t*, void*, etc.  This is needed to handle
229   // OSCompareAndSwap32Barrier/OSCompareAndSwap64Barrier.
230   if (isa<Loc>(V) || isa<nonloc::LocAsInteger>(V))
231     if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
232       // FIXME: Should check for index 0.
233       QualType T = ER->getLocationType();
234
235       if (isHigherOrderRawPtr(T, Ctx))
236         R = ER->getSuperRegion();
237     }
238
239   if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R) || isa<CXXThisRegion>(R)))
240     return StoreRef(store, *this);
241
242   const TypedRegion *TyR = cast<TypedRegion>(R);
243
244   // Do not bind to arrays.  We need to explicitly check for this so that
245   // we do not encounter any weirdness of trying to load/store from arrays.
246   if (TyR->isBoundable() && TyR->getValueType()->isArrayType())
247     return StoreRef(store, *this);
248
249   if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&V)) {
250     // Only convert 'V' to a location iff the underlying region type
251     // is a location as well.
252     // FIXME: We are allowing a store of an arbitrary location to
253     // a pointer.  We may wish to flag a type error here if the types
254     // are incompatible.  This may also cause lots of breakage
255     // elsewhere. Food for thought.
256     if (TyR->isBoundable() && Loc::isLocType(TyR->getValueType()))
257       V = X->getLoc();
258   }
259
260   BindingsTy B = GetBindings(store);
261   return StoreRef(V.isUnknown()
262                     ? VBFactory.remove(B, R).getRoot()
263                     : VBFactory.add(B, R, V).getRoot(), *this);
264 }
265
266 StoreRef BasicStoreManager::Remove(Store store, Loc loc) {
267   switch (loc.getSubKind()) {
268     case loc::MemRegionKind: {
269       const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion();
270
271       if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R) ||
272           isa<CXXThisRegion>(R)))
273         return StoreRef(store, *this);
274
275       return StoreRef(VBFactory.remove(GetBindings(store), R).getRoot(), *this);
276     }
277     default:
278       assert ("Remove for given Loc type not yet implemented.");
279       return StoreRef(store, *this);
280   }
281 }
282
283 StoreRef BasicStoreManager::removeDeadBindings(Store store,
284                                                const StackFrameContext *LCtx,
285                                                SymbolReaper& SymReaper,
286                            llvm::SmallVectorImpl<const MemRegion*>& RegionRoots)
287 {
288   BindingsTy B = GetBindings(store);
289   typedef SVal::symbol_iterator symbol_iterator;
290
291   // Iterate over the variable bindings.
292   for (BindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I) {
293     if (const VarRegion *VR = dyn_cast<VarRegion>(I.getKey())) {
294       if (SymReaper.isLive(VR))
295         RegionRoots.push_back(VR);
296       else
297         continue;
298     }
299     else if (isa<ObjCIvarRegion>(I.getKey()) ||
300              isa<NonStaticGlobalSpaceRegion>(I.getKey()) ||
301              isa<CXXThisRegion>(I.getKey()))
302       RegionRoots.push_back(I.getKey());
303     else
304       continue;
305
306     // Mark the bindings in the data as live.
307     SVal X = I.getData();
308     for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
309       SymReaper.markLive(*SI);
310   }
311
312   // Scan for live variables and live symbols.
313   llvm::SmallPtrSet<const MemRegion*, 10> Marked;
314
315   while (!RegionRoots.empty()) {
316     const MemRegion* MR = RegionRoots.back();
317     RegionRoots.pop_back();
318
319     while (MR) {
320       if (const SymbolicRegion* SymR = dyn_cast<SymbolicRegion>(MR)) {
321         SymReaper.markLive(SymR->getSymbol());
322         break;
323       }
324       else if (isa<VarRegion>(MR) || isa<ObjCIvarRegion>(MR) ||
325                isa<NonStaticGlobalSpaceRegion>(MR) || isa<CXXThisRegion>(MR)) {
326         if (Marked.count(MR))
327           break;
328
329         Marked.insert(MR);
330         SVal X = Retrieve(store, loc::MemRegionVal(MR));
331
332         // FIXME: We need to handle symbols nested in region definitions.
333         for (symbol_iterator SI=X.symbol_begin(),SE=X.symbol_end();SI!=SE;++SI)
334           SymReaper.markLive(*SI);
335
336         if (!isa<loc::MemRegionVal>(X))
337           break;
338
339         const loc::MemRegionVal& LVD = cast<loc::MemRegionVal>(X);
340         RegionRoots.push_back(LVD.getRegion());
341         break;
342       }
343       else if (const SubRegion* R = dyn_cast<SubRegion>(MR))
344         MR = R->getSuperRegion();
345       else
346         break;
347     }
348   }
349
350   // Remove dead variable bindings.
351   StoreRef newStore(store, *this);
352   for (BindingsTy::iterator I=B.begin(), E=B.end(); I!=E ; ++I) {
353     const MemRegion* R = I.getKey();
354
355     if (!Marked.count(R)) {
356       newStore = Remove(newStore.getStore(), svalBuilder.makeLoc(R));
357       SVal X = I.getData();
358
359       for (symbol_iterator SI=X.symbol_begin(), SE=X.symbol_end(); SI!=SE; ++SI)
360         SymReaper.maybeDead(*SI);
361     }
362   }
363
364   return newStore;
365 }
366
367 StoreRef BasicStoreManager::scanForIvars(Stmt *B, const Decl* SelfDecl,
368                                          const MemRegion *SelfRegion,
369                                          Store St) {
370   
371   StoreRef newStore(St, *this);
372
373   for (Stmt::child_iterator CI=B->child_begin(), CE=B->child_end();
374        CI != CE; ++CI) {
375
376     if (!*CI)
377       continue;
378
379     // Check if the statement is an ivar reference.  We only
380     // care about self.ivar.
381     if (ObjCIvarRefExpr *IV = dyn_cast<ObjCIvarRefExpr>(*CI)) {
382       const Expr *Base = IV->getBase()->IgnoreParenCasts();
383       if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Base)) {
384         if (DR->getDecl() == SelfDecl) {
385           const ObjCIvarRegion *IVR = MRMgr.getObjCIvarRegion(IV->getDecl(),
386                                                          SelfRegion);
387           SVal X = svalBuilder.getRegionValueSymbolVal(IVR);
388           newStore = Bind(newStore.getStore(), svalBuilder.makeLoc(IVR), X);
389         }
390       }
391     }
392     else
393       newStore = scanForIvars(*CI, SelfDecl, SelfRegion, newStore.getStore());
394   }
395
396   return newStore;
397 }
398
399 StoreRef BasicStoreManager::getInitialStore(const LocationContext *InitLoc) {
400   // The LiveVariables information already has a compilation of all VarDecls
401   // used in the function.  Iterate through this set, and "symbolicate"
402   // any VarDecl whose value originally comes from outside the function.
403   typedef LiveVariables::AnalysisDataTy LVDataTy;
404   LVDataTy& D = InitLoc->getLiveVariables()->getAnalysisData();
405   StoreRef St(VBFactory.getEmptyMap().getRoot(), *this);
406
407   for (LVDataTy::decl_iterator I=D.begin_decl(), E=D.end_decl(); I != E; ++I) {
408     const NamedDecl* ND = I->first;
409
410     // Handle implicit parameters.
411     if (const ImplicitParamDecl* PD = dyn_cast<ImplicitParamDecl>(ND)) {
412       const Decl& CD = *InitLoc->getDecl();
413       if (const ObjCMethodDecl* MD = dyn_cast<ObjCMethodDecl>(&CD)) {
414         if (MD->getSelfDecl() == PD) {
415           // FIXME: Add type constraints (when they become available) to
416           // SelfRegion?  (i.e., it implements MD->getClassInterface()).
417           const VarRegion *VR = MRMgr.getVarRegion(PD, InitLoc);
418           const MemRegion *SelfRegion =
419             svalBuilder.getRegionValueSymbolVal(VR).getAsRegion();
420           assert(SelfRegion);
421           St = Bind(St.getStore(), svalBuilder.makeLoc(VR),
422                     loc::MemRegionVal(SelfRegion));
423           // Scan the method for ivar references.  While this requires an
424           // entire AST scan, the cost should not be high in practice.
425           St = scanForIvars(MD->getBody(), PD, SelfRegion, St.getStore());
426         }
427       }
428     }
429   }
430
431   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(InitLoc->getDecl())) {
432     // For C++ non-static member variables, add a symbolic region for 'this' in
433     // the initial stack frame.
434     if (MD->isInstance()) {
435       QualType ThisT = MD->getThisType(StateMgr.getContext());
436       MemRegionManager &RegMgr = svalBuilder.getRegionManager();
437       const CXXThisRegion *ThisR = RegMgr.getCXXThisRegion(ThisT, InitLoc);
438       SVal ThisV = svalBuilder.getRegionValueSymbolVal(ThisR);
439       St = Bind(St.getStore(), svalBuilder.makeLoc(ThisR), ThisV);
440     }
441   }
442
443   return St;
444 }
445
446 StoreRef BasicStoreManager::BindDeclInternal(Store store, const VarRegion* VR,
447                                              SVal* InitVal) {
448
449   BasicValueFactory& BasicVals = StateMgr.getBasicVals();
450   const VarDecl *VD = VR->getDecl();
451   StoreRef newStore(store, *this);
452
453   // BasicStore does not model arrays and structs.
454   if (VD->getType()->isArrayType() || VD->getType()->isStructureOrClassType())
455     return newStore;
456   
457   if (VD->hasGlobalStorage()) {
458     // Handle variables with global storage: extern, static, PrivateExtern.
459
460     // FIXME:: static variables may have an initializer, but the second time a
461     // function is called those values may not be current. Currently, a function
462     // will not be called more than once.
463
464     // Static global variables should not be visited here.
465     assert(!(VD->getStorageClass() == SC_Static &&
466              VD->isFileVarDecl()));
467
468     // Process static variables.
469     if (VD->getStorageClass() == SC_Static) {
470       // C99: 6.7.8 Initialization
471       //  If an object that has static storage duration is not initialized
472       //  explicitly, then:
473       //   -if it has pointer type, it is initialized to a null pointer;
474       //   -if it has arithmetic type, it is initialized to (positive or
475       //     unsigned) zero;
476       if (!InitVal) {
477         QualType T = VD->getType();
478         if (Loc::isLocType(T))
479           newStore = Bind(store, loc::MemRegionVal(VR),
480                           loc::ConcreteInt(BasicVals.getValue(0, T)));
481         else if (T->isIntegerType() && T->isScalarType())
482           newStore = Bind(store, loc::MemRegionVal(VR),
483                           nonloc::ConcreteInt(BasicVals.getValue(0, T)));
484       } else {
485           newStore = Bind(store, loc::MemRegionVal(VR), *InitVal);
486       }
487     }
488   } else {
489     // Process local scalar variables.
490     QualType T = VD->getType();
491     // BasicStore only supports scalars.
492     if ((T->isScalarType() || T->isReferenceType()) &&
493         svalBuilder.getSymbolManager().canSymbolicate(T)) {
494       SVal V = InitVal ? *InitVal : UndefinedVal();
495       newStore = Bind(store, loc::MemRegionVal(VR), V);
496     }
497   }
498
499   return newStore;
500 }
501
502 void BasicStoreManager::print(Store store, llvm::raw_ostream& Out,
503                               const char* nl, const char *sep) {
504
505   BindingsTy B = GetBindings(store);
506   Out << "Variables:" << nl;
507
508   bool isFirst = true;
509
510   for (BindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I) {
511     if (isFirst)
512       isFirst = false;
513     else
514       Out << nl;
515
516     Out << ' ' << I.getKey() << " : " << I.getData();
517   }
518 }
519
520
521 void BasicStoreManager::iterBindings(Store store, BindingsHandler& f) {
522   BindingsTy B = GetBindings(store);
523
524   for (BindingsTy::iterator I=B.begin(), E=B.end(); I != E; ++I)
525     if (!f.HandleBinding(*this, store, I.getKey(), I.getData()))
526       return;
527
528 }
529
530 StoreManager::BindingsHandler::~BindingsHandler() {}
531
532 //===----------------------------------------------------------------------===//
533 // Binding invalidation.
534 //===----------------------------------------------------------------------===//
535
536
537 StoreRef BasicStoreManager::invalidateRegions(Store store,
538                                               const MemRegion * const *I,
539                                               const MemRegion * const *End,
540                                               const Expr *E, unsigned Count,
541                                               InvalidatedSymbols &IS,
542                                               bool invalidateGlobals,
543                                               InvalidatedRegions *Regions) {
544   StoreRef newStore(store, *this);
545   
546   if (invalidateGlobals) {
547     BindingsTy B = GetBindings(store);
548     for (BindingsTy::iterator I=B.begin(), End=B.end(); I != End; ++I) {
549       const MemRegion *R = I.getKey();
550       if (isa<NonStaticGlobalSpaceRegion>(R->getMemorySpace()))
551         newStore = invalidateRegion(newStore.getStore(), R, E, Count, IS);
552     }
553   }
554
555   for ( ; I != End ; ++I) {
556     const MemRegion *R = *I;
557     // Don't invalidate globals twice.
558     if (invalidateGlobals) {
559       if (isa<NonStaticGlobalSpaceRegion>(R->getMemorySpace()))
560         continue;
561     }
562     newStore = invalidateRegion(newStore.getStore(), *I, E, Count, IS);
563     if (Regions)
564       Regions->push_back(R);
565   }
566
567   // FIXME: This is copy-and-paste from RegionStore.cpp.
568   if (invalidateGlobals) {
569     // Bind the non-static globals memory space to a new symbol that we will
570     // use to derive the bindings for all non-static globals.
571     const GlobalsSpaceRegion *GS = MRMgr.getGlobalsRegion();
572     SVal V =
573       svalBuilder.getConjuredSymbolVal(/* SymbolTag = */ (void*) GS, E,
574                                   /* symbol type, doesn't matter */ Ctx.IntTy,
575                                   Count);
576
577     newStore = Bind(newStore.getStore(), loc::MemRegionVal(GS), V);
578     if (Regions)
579       Regions->push_back(GS);
580   }
581
582   return newStore;
583 }
584
585
586 StoreRef BasicStoreManager::invalidateRegion(Store store,
587                                              const MemRegion *R,
588                                              const Expr *E,
589                                              unsigned Count,
590                                              InvalidatedSymbols &IS) {
591   R = R->StripCasts();
592
593   if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R)))
594       return StoreRef(store, *this);
595
596   BindingsTy B = GetBindings(store);
597   if (BindingsTy::data_type *Val = B.lookup(R)) {
598     if (SymbolRef Sym = Val->getAsSymbol())
599       IS.insert(Sym);
600   }
601
602   QualType T = cast<TypedRegion>(R)->getValueType();
603   SVal V = svalBuilder.getConjuredSymbolVal(R, E, T, Count);
604   return Bind(store, loc::MemRegionVal(R), V);
605 }