diff options
| author | Ed Schouten <ed@FreeBSD.org> | 2009-07-04 13:58:54 +0000 | 
|---|---|---|
| committer | Ed Schouten <ed@FreeBSD.org> | 2009-07-04 13:58:54 +0000 | 
| commit | 5362a71c02e7d448a8ce98cf00c47e353fba5d04 (patch) | |
| tree | 8ddfe382e1c6d590dc240e76f7cd45cea5c78e24 /lib/Analysis | |
| parent | 4ebdf5c4f587daef4e0be499802eac3a7a49bf2f (diff) | |
Diffstat (limited to 'lib/Analysis')
| -rw-r--r-- | lib/Analysis/BasicStore.cpp | 104 | ||||
| -rw-r--r-- | lib/Analysis/BugReporter.cpp | 7 | ||||
| -rw-r--r-- | lib/Analysis/CFRefCount.cpp | 57 | ||||
| -rw-r--r-- | lib/Analysis/CheckDeadStores.cpp | 4 | ||||
| -rw-r--r-- | lib/Analysis/CheckObjCDealloc.cpp | 14 | ||||
| -rw-r--r-- | lib/Analysis/CheckObjCInstMethSignature.cpp | 8 | ||||
| -rw-r--r-- | lib/Analysis/CheckObjCUnusedIVars.cpp | 15 | ||||
| -rw-r--r-- | lib/Analysis/Environment.cpp | 15 | ||||
| -rw-r--r-- | lib/Analysis/GRExprEngine.cpp | 15 | ||||
| -rw-r--r-- | lib/Analysis/GRExprEngineInternalChecks.cpp | 2 | ||||
| -rw-r--r-- | lib/Analysis/GRState.cpp | 6 | ||||
| -rw-r--r-- | lib/Analysis/LiveVariables.cpp | 3 | ||||
| -rw-r--r-- | lib/Analysis/MemRegion.cpp | 46 | ||||
| -rw-r--r-- | lib/Analysis/RegionStore.cpp | 135 | ||||
| -rw-r--r-- | lib/Analysis/SVals.cpp | 7 | ||||
| -rw-r--r-- | lib/Analysis/Store.cpp | 6 | 
16 files changed, 263 insertions, 181 deletions
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp index 8fbce528fa9a..19d641ee9753 100644 --- a/lib/Analysis/BasicStore.cpp +++ b/lib/Analysis/BasicStore.cpp @@ -198,7 +198,7 @@ SVal BasicStoreManager::getLValueElement(const GRState *state,      return Base;    Loc BaseL = cast<Loc>(Base);   -  const TypedRegion* BaseR = 0; +  const MemRegion* BaseR = 0;    switch(BaseL.getSubKind()) {      case loc::GotoLabelKind: @@ -216,17 +216,11 @@ SVal BasicStoreManager::getLValueElement(const GRState *state,          return Base;        } -       -      if (const TypedRegion *TR = dyn_cast<TypedRegion>(R)) { -        BaseR = TR; +      if (isa<TypedRegion>(R) || isa<SymbolicRegion>(R)) { +        BaseR = R;          break;        } -      if (const SymbolicRegion* SR = dyn_cast<SymbolicRegion>(R)) { -        SymbolRef Sym = SR->getSymbol(); -        BaseR = MRMgr.getTypedViewRegion(Sym->getType(getContext()), SR); -      } -              break;      } @@ -242,9 +236,10 @@ SVal BasicStoreManager::getLValueElement(const GRState *state,        return Base;    } -  if (BaseR)   +  if (BaseR) {       return ValMgr.makeLoc(MRMgr.getElementRegion(elementType, UnknownVal(),                                                   BaseR, getContext())); +  }    else      return UnknownVal();  } @@ -319,54 +314,50 @@ SVal BasicStoreManager::Retrieve(const GRState *state, Loc loc, QualType T) {  }  Store BasicStoreManager::BindInternal(Store store, Loc loc, SVal V) {     -  switch (loc.getSubKind()) {       -    case loc::MemRegionKind: { -      const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion(); -      ASTContext &C = StateMgr.getContext(); +  if (isa<loc::ConcreteInt>(loc)) +    return store; + +  const MemRegion* R = cast<loc::MemRegionVal>(loc).getRegion(); +  ASTContext &C = StateMgr.getContext(); -      // Special case: handle store of pointer values (Loc) to pointers via -      // a cast to intXX_t*, void*, etc.  This is needed to handle -      // OSCompareAndSwap32Barrier/OSCompareAndSwap64Barrier. -      if (isa<Loc>(V) || isa<nonloc::LocAsInteger>(V)) -        if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { -          // FIXME: Should check for index 0. -          QualType T = ER->getLocationType(C); +  // Special case: handle store of pointer values (Loc) to pointers via +  // a cast to intXX_t*, void*, etc.  This is needed to handle +  // OSCompareAndSwap32Barrier/OSCompareAndSwap64Barrier. +  if (isa<Loc>(V) || isa<nonloc::LocAsInteger>(V)) +    if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) { +      // FIXME: Should check for index 0. +      QualType T = ER->getLocationType(C); -          if (isHigherOrderRawPtr(T, C)) -            R = ER->getSuperRegion(); -        }       +      if (isHigherOrderRawPtr(T, C)) +        R = ER->getSuperRegion(); +    }       -      if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R))) -        return store; +  if (!(isa<VarRegion>(R) || isa<ObjCIvarRegion>(R))) +    return store; -      // We only track bindings to self.ivar. -      if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) -        if (IVR->getSuperRegion() != SelfRegion) -          return store; +  // We only track bindings to self.ivar. +  if (const ObjCIvarRegion *IVR = dyn_cast<ObjCIvarRegion>(R)) +    if (IVR->getSuperRegion() != SelfRegion) +      return store; -      if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&V)) { -        // Only convert 'V' to a location iff the underlying region type -        // is a location as well. -        // FIXME: We are allowing a store of an arbitrary location to -        // a pointer.  We may wish to flag a type error here if the types -        // are incompatible.  This may also cause lots of breakage -        // elsewhere. Food for thought. -        if (const TypedRegion *TyR = dyn_cast<TypedRegion>(R)) { -          if (TyR->isBoundable() && -              Loc::IsLocType(TyR->getValueType(C)))               -            V = X->getLoc(); -        } -      } - -      BindingsTy B = GetBindings(store); -      return V.isUnknown() -        ? VBFactory.Remove(B, R).getRoot() -        : VBFactory.Add(B, R, V).getRoot(); +  if (nonloc::LocAsInteger *X = dyn_cast<nonloc::LocAsInteger>(&V)) { +    // Only convert 'V' to a location iff the underlying region type +    // is a location as well. +    // FIXME: We are allowing a store of an arbitrary location to +    // a pointer.  We may wish to flag a type error here if the types +    // are incompatible.  This may also cause lots of breakage +    // elsewhere. Food for thought. +    if (const TypedRegion *TyR = dyn_cast<TypedRegion>(R)) { +      if (TyR->isBoundable() && +          Loc::IsLocType(TyR->getValueType(C)))               +        V = X->getLoc();      } -    default: -      assert ("SetSVal for given Loc type not yet implemented."); -      return store;    } + +  BindingsTy B = GetBindings(store); +  return V.isUnknown() +    ? VBFactory.Remove(B, R).getRoot() +    : VBFactory.Add(B, R, V).getRoot();  }  Store BasicStoreManager::Remove(Store store, Loc loc) { @@ -521,7 +512,7 @@ Store BasicStoreManager::getInitialStore() {            // Scan the method for ivar references.  While this requires an            // entire AST scan, the cost should not be high in practice. -          St = scanForIvars(MD->getBody(getContext()), PD, St); +          St = scanForIvars(MD->getBody(), PD, St);          }        }      } @@ -537,10 +528,9 @@ Store BasicStoreManager::getInitialStore() {        // Initialize globals and parameters to symbolic values.        // Initialize local variables to undefined.        const MemRegion *R = ValMgr.getRegionManager().getVarRegion(VD); -      SVal X = (VD->hasGlobalStorage() || isa<ParmVarDecl>(VD) || -                isa<ImplicitParamDecl>(VD)) -            ? ValMgr.getRegionValueSymbolVal(R) -            : UndefinedVal(); +      SVal X = R->hasGlobalsOrParametersStorage() +               ? ValMgr.getRegionValueSymbolVal(R) +               : UndefinedVal();        St = BindInternal(St, ValMgr.makeLoc(R), X);      } @@ -594,7 +584,7 @@ Store BasicStoreManager::BindDeclInternal(Store store, const VarDecl* VD,    } else {      // Process local scalar variables.      QualType T = VD->getType(); -    if (Loc::IsLocType(T) || T->isIntegerType()) { +    if (ValMgr.getSymbolManager().canSymbolicate(T)) {        SVal V = InitVal ? *InitVal : UndefinedVal();        store = BindInternal(store, getLoc(VD), V);      } diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index 38ea458a6599..3db96ca9eacb 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -146,7 +146,7 @@ public:    ParentMap& getParentMap() {      if (PM.get() == 0) -      PM.reset(new ParentMap(getCodeDecl().getBody(getASTContext()))); +      PM.reset(new ParentMap(getCodeDecl().getBody()));      return *PM.get();    } @@ -182,8 +182,7 @@ PathDiagnosticBuilder::ExecutionContinues(const ExplodedNode<GRState>* N) {    if (Stmt *S = GetNextStmt(N))      return PathDiagnosticLocation(S, getSourceManager()); -  return FullSourceLoc(getCodeDecl().getBodyRBrace(getASTContext()), -                       getSourceManager()); +  return FullSourceLoc(getCodeDecl().getBodyRBrace(), getSourceManager());  }  PathDiagnosticLocation @@ -893,7 +892,7 @@ public:      // statement (if it doesn't already exist).      // FIXME: Should handle CXXTryStmt if analyser starts supporting C++.      if (const CompoundStmt *CS = -          PDB.getCodeDecl().getCompoundBody(PDB.getASTContext())) +          PDB.getCodeDecl().getCompoundBody())        if (!CS->body_empty()) {          SourceLocation Loc = (*CS->body_begin())->getLocStart();          rawAddEdge(PathDiagnosticLocation(Loc, PDB.getSourceManager())); diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp index f4a28e0c19fd..3cca482633ca 100644 --- a/lib/Analysis/CFRefCount.cpp +++ b/lib/Analysis/CFRefCount.cpp @@ -156,13 +156,13 @@ static bool followsFundamentalRule(Selector S) {  }  static const ObjCMethodDecl* -ResolveToInterfaceMethodDecl(const ObjCMethodDecl *MD, ASTContext &Context) {   +ResolveToInterfaceMethodDecl(const ObjCMethodDecl *MD) {      ObjCInterfaceDecl *ID =      const_cast<ObjCInterfaceDecl*>(MD->getClassInterface());    return MD->isInstanceMethod() -         ? ID->lookupInstanceMethod(Context, MD->getSelector()) -         : ID->lookupClassMethod(Context, MD->getSelector()); +         ? ID->lookupInstanceMethod(MD->getSelector()) +         : ID->lookupClassMethod(MD->getSelector());  }  namespace { @@ -827,8 +827,7 @@ public:      QualType ResultTy = MD->getResultType();      // Resolve the method decl last.     -    if (const ObjCMethodDecl *InterfaceMD = -        ResolveToInterfaceMethodDecl(MD, Ctx)) +    if (const ObjCMethodDecl *InterfaceMD = ResolveToInterfaceMethodDecl(MD))        MD = InterfaceMD;      if (MD->isInstanceMethod()) @@ -1248,15 +1247,15 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,    // Determine if there is a special return effect for this method.    if (isTrackedObjCObjectType(RetTy)) { -    if (FD->getAttr<NSReturnsRetainedAttr>(Ctx)) { +    if (FD->getAttr<NSReturnsRetainedAttr>()) {        Summ.setRetEffect(ObjCAllocRetE);      } -    else if (FD->getAttr<CFReturnsRetainedAttr>(Ctx)) { +    else if (FD->getAttr<CFReturnsRetainedAttr>()) {        Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));      }    }    else if (RetTy->getAsPointerType()) { -    if (FD->getAttr<CFReturnsRetainedAttr>(Ctx)) { +    if (FD->getAttr<CFReturnsRetainedAttr>()) {        Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));      }    } @@ -1270,10 +1269,10 @@ RetainSummaryManager::updateSummaryFromAnnotations(RetainSummary &Summ,    // Determine if there is a special return effect for this method.    if (isTrackedObjCObjectType(MD->getResultType())) { -    if (MD->getAttr<NSReturnsRetainedAttr>(Ctx)) { +    if (MD->getAttr<NSReturnsRetainedAttr>()) {        Summ.setRetEffect(ObjCAllocRetE);      } -    else if (MD->getAttr<CFReturnsRetainedAttr>(Ctx)) { +    else if (MD->getAttr<CFReturnsRetainedAttr>()) {        Summ.setRetEffect(RetEffect::MakeOwned(RetEffect::CF, true));      }    } @@ -2632,7 +2631,7 @@ CFRefLeakReport::getEndPath(BugReporterContext& BRC,    if (!L.isValid()) {      const Decl &D = BRC.getCodeDecl(); -    L = PathDiagnosticLocation(D.getBodyRBrace(BRC.getASTContext()), SMgr); +    L = PathDiagnosticLocation(D.getBodyRBrace(), SMgr);    }    std::string sbuf; @@ -2796,7 +2795,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,          //  to identify conjured symbols by an expression pair: the enclosing          //  expression (the context) and the expression itself.  This should          //  disambiguate conjured symbols.  -         +        unsigned Count = Builder.getCurrentBlockCount();          const TypedRegion* R = dyn_cast<TypedRegion>(MR->getRegion());          if (R) { @@ -2833,7 +2832,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,            if (R->isBoundable()) {              // Set the value of the variable to be a conjured symbol. -            unsigned Count = Builder.getCurrentBlockCount(); +              QualType T = R->getValueType(Ctx);              if (Loc::IsLocType(T) || (T->isIntegerType() && T->isScalarType())){ @@ -2857,20 +2856,31 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,                  state->getStateManager().getRegionManager();                // Iterate through the fields and construct new symbols. -              for (RecordDecl::field_iterator FI=RD->field_begin(Ctx), -                   FE=RD->field_end(Ctx); FI!=FE; ++FI) { +              for (RecordDecl::field_iterator FI=RD->field_begin(), +                   FE=RD->field_end(); FI!=FE; ++FI) {                  // For now just handle scalar fields.                  FieldDecl *FD = *FI;                  QualType FT = FD->getType(); -                 +                const FieldRegion* FR = MRMgr.getFieldRegion(FD, R); +                  if (Loc::IsLocType(FT) ||                       (FT->isIntegerType() && FT->isScalarType())) { -                  const FieldRegion* FR = MRMgr.getFieldRegion(FD, R); -                    SVal V = ValMgr.getConjuredSymbolVal(*I, FT, Count);                    state = state->bindLoc(ValMgr.makeLoc(FR), V); -                }                 +                } +                else if (FT->isStructureType()) { +                  // set the default value of the struct field to conjured +                  // symbol. Note that the type of the symbol is irrelavant. +                  // We cannot use the type of the struct otherwise ValMgr won't +                  // give us the conjured symbol. +                  StoreManager& StoreMgr =  +                    Eng.getStateManager().getStoreManager(); +                  SVal V = ValMgr.getConjuredSymbolVal(*I,  +                                                       Eng.getContext().IntTy, +                                                       Count); +                  state = StoreMgr.setDefaultValue(state, FR, V); +                }                }              } else if (const ArrayType *AT = Ctx.getAsArrayType(T)) {                // Set the default value of the array to conjured symbol. @@ -2884,6 +2894,15 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,              }            }          } +        else if (isa<AllocaRegion>(MR->getRegion())) { +          // Invalidate the alloca region by setting its default value to  +          // conjured symbol. The type of the symbol is irrelavant. +          SVal V = ValMgr.getConjuredSymbolVal(*I, Eng.getContext().IntTy,  +                                               Count); +          StoreManager& StoreMgr =  +                    Eng.getStateManager().getStoreManager(); +          state = StoreMgr.setDefaultValue(state, MR->getRegion(), V); +        }          else            state = state->bindLoc(*MR, UnknownVal());        } diff --git a/lib/Analysis/CheckDeadStores.cpp b/lib/Analysis/CheckDeadStores.cpp index 0f61a5ee916a..69433d6396a5 100644 --- a/lib/Analysis/CheckDeadStores.cpp +++ b/lib/Analysis/CheckDeadStores.cpp @@ -85,7 +85,7 @@ public:                      const LiveVariables::AnalysisDataTy& AD,                      const LiveVariables::ValTy& Live) { -    if (VD->hasLocalStorage() && !Live(VD, AD) && !VD->getAttr<UnusedAttr>(Ctx)) +    if (VD->hasLocalStorage() && !Live(VD, AD) && !VD->getAttr<UnusedAttr>())        Report(VD, dsk, Ex->getSourceRange().getBegin(),               Val->getSourceRange());          } @@ -190,7 +190,7 @@ public:              // A dead initialization is a variable that is dead after it              // is initialized.  We don't flag warnings for those variables              // marked 'unused'. -            if (!Live(V, AD) && V->getAttr<UnusedAttr>(Ctx) == 0) { +            if (!Live(V, AD) && V->getAttr<UnusedAttr>() == 0) {                // Special case: check for initializations with constants.                //                //  e.g. : int x = 0; diff --git a/lib/Analysis/CheckObjCDealloc.cpp b/lib/Analysis/CheckObjCDealloc.cpp index 2ba7d868e90b..a14ae265128b 100644 --- a/lib/Analysis/CheckObjCDealloc.cpp +++ b/lib/Analysis/CheckObjCDealloc.cpp @@ -109,7 +109,7 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,      QualType T = ID->getType();      if (!Ctx.isObjCObjectPointerType(T) || -        ID->getAttr<IBOutletAttr>(Ctx)) // Skip IBOutlets. +        ID->getAttr<IBOutletAttr>()) // Skip IBOutlets.        continue;      containsPointerIvar = true; @@ -147,8 +147,8 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,    ObjCMethodDecl* MD = 0;    // Scan the instance methods for "dealloc". -  for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(Ctx), -       E = D->instmeth_end(Ctx); I!=E; ++I) { +  for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(), +       E = D->instmeth_end(); I!=E; ++I) {      if ((*I)->getSelector() == S) {        MD = *I; @@ -172,7 +172,7 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,    }    // dealloc found.  Scan for missing [super dealloc]. -  if (MD->getBody(Ctx) && !scan_dealloc(MD->getBody(Ctx), S)) { +  if (MD->getBody() && !scan_dealloc(MD->getBody(), S)) {      const char* name = LOpts.getGCMode() == LangOptions::NonGC                         ? "missing [super dealloc]" @@ -198,8 +198,8 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,    // Scan for missing and extra releases of ivars used by implementations    // of synthesized properties -  for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(Ctx), -       E = D->propimpl_end(Ctx); I!=E; ++I) { +  for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(), +       E = D->propimpl_end(); I!=E; ++I) {      // We can only check the synthesized properties      if((*I)->getPropertyImplementation() != ObjCPropertyImplDecl::Synthesize) @@ -223,7 +223,7 @@ void clang::CheckObjCDealloc(ObjCImplementationDecl* D,      // ivar must be released if and only if the kind of setter was not 'assign'      bool requiresRelease = PD->getSetterKind() != ObjCPropertyDecl::Assign; -    if(scan_ivar_release(MD->getBody(Ctx), ID, PD, RS, SelfII, Ctx)  +    if(scan_ivar_release(MD->getBody(), ID, PD, RS, SelfII, Ctx)          != requiresRelease) {        const char *name;        const char* category = "Memory (Core Foundation/Objective-C)"; diff --git a/lib/Analysis/CheckObjCInstMethSignature.cpp b/lib/Analysis/CheckObjCInstMethSignature.cpp index 9fec7c1dc111..28814867bd58 100644 --- a/lib/Analysis/CheckObjCInstMethSignature.cpp +++ b/lib/Analysis/CheckObjCInstMethSignature.cpp @@ -86,8 +86,8 @@ void clang::CheckObjCInstMethSignature(ObjCImplementationDecl* ID,    MapTy IMeths;    unsigned NumMethods = 0; -  for (ObjCImplementationDecl::instmeth_iterator I=ID->instmeth_begin(Ctx), -       E=ID->instmeth_end(Ctx); I!=E; ++I) {     +  for (ObjCImplementationDecl::instmeth_iterator I=ID->instmeth_begin(), +       E=ID->instmeth_end(); I!=E; ++I) {          ObjCMethodDecl* M = *I;      IMeths[M->getSelector()] = M; @@ -97,8 +97,8 @@ void clang::CheckObjCInstMethSignature(ObjCImplementationDecl* ID,    // Now recurse the class hierarchy chain looking for methods with the    // same signatures.    while (C && NumMethods) { -    for (ObjCInterfaceDecl::instmeth_iterator I=C->instmeth_begin(Ctx), -         E=C->instmeth_end(Ctx); I!=E; ++I) { +    for (ObjCInterfaceDecl::instmeth_iterator I=C->instmeth_begin(), +         E=C->instmeth_end(); I!=E; ++I) {        ObjCMethodDecl* M = *I;        Selector S = M->getSelector(); diff --git a/lib/Analysis/CheckObjCUnusedIVars.cpp b/lib/Analysis/CheckObjCUnusedIVars.cpp index 21dc658dfa1a..0063c40482a0 100644 --- a/lib/Analysis/CheckObjCUnusedIVars.cpp +++ b/lib/Analysis/CheckObjCUnusedIVars.cpp @@ -59,9 +59,6 @@ void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {    ObjCInterfaceDecl* ID = D->getClassInterface();    IvarUsageMap M; - -  ASTContext &Ctx = BR.getContext(); -    // Iterate over the ivars.    for (ObjCInterfaceDecl::ivar_iterator I=ID->ivar_begin(), E=ID->ivar_end();         I!=E; ++I) { @@ -73,7 +70,7 @@ void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {        continue;      // Skip IB Outlets. -    if (ID->getAttr<IBOutletAttr>(Ctx)) +    if (ID->getAttr<IBOutletAttr>())        continue;      M[ID] = Unused; @@ -83,14 +80,14 @@ void clang::CheckObjCUnusedIvar(ObjCImplementationDecl* D, BugReporter& BR) {      return;    // Now scan the methods for accesses. -  for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(Ctx), -       E = D->instmeth_end(Ctx); I!=E; ++I) -    Scan(M, (*I)->getBody(Ctx)); +  for (ObjCImplementationDecl::instmeth_iterator I = D->instmeth_begin(), +       E = D->instmeth_end(); I!=E; ++I) +    Scan(M, (*I)->getBody());    // Scan for @synthesized property methods that act as setters/getters    // to an ivar. -  for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(Ctx), -       E = D->propimpl_end(Ctx); I!=E; ++I) +  for (ObjCImplementationDecl::propimpl_iterator I = D->propimpl_begin(), +       E = D->propimpl_end(); I!=E; ++I)      Scan(M, *I);      // Find ivars that are unused. diff --git a/lib/Analysis/Environment.cpp b/lib/Analysis/Environment.cpp index 2b751df830c2..3f8f14dcb0b4 100644 --- a/lib/Analysis/Environment.cpp +++ b/lib/Analysis/Environment.cpp @@ -143,8 +143,19 @@ EnvironmentManager::RemoveDeadBindings(Environment Env, Stmt* Loc,        SVal X = I.getData();        // If the block expr's value is a memory region, then mark that region. -      if (isa<loc::MemRegionVal>(X)) -        DRoots.push_back(cast<loc::MemRegionVal>(X).getRegion()); +      if (isa<loc::MemRegionVal>(X)) { +        const MemRegion* R = cast<loc::MemRegionVal>(X).getRegion(); +        DRoots.push_back(R); +        // Mark the super region of the RX as live. +        // e.g.: int x; char *y = (char*) &x; if (*y) ...  +        // 'y' => element region. 'x' is its super region. +        // We only add one level super region for now. + +        // FIXME: maybe multiple level of super regions should be added. +        if (const SubRegion *SR = dyn_cast<SubRegion>(R)) { +          DRoots.push_back(SR->getSuperRegion()); +        } +      }        // Mark all symbols in the block expr's value live.        MarkLiveCallback cb(SymReaper); diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 8b4f5c8f11c1..d9117f5930e6 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -1437,8 +1437,8 @@ void GRExprEngine::VisitCallRec(CallExpr* CE, NodeTy* Pred,      SaveAndRestore<bool> OldSink(Builder->BuildSinks);      const FunctionDecl* FD = L.getAsFunctionDecl();      if (FD) {       -      if (FD->getAttr<NoReturnAttr>(getContext()) ||  -          FD->getAttr<AnalyzerNoReturnAttr>(getContext())) +      if (FD->getAttr<NoReturnAttr>() ||  +          FD->getAttr<AnalyzerNoReturnAttr>())          Builder->BuildSinks = true;        else {          // HACK: Some functions are not marked noreturn, and don't return. @@ -3154,7 +3154,8 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :            SourceLocation SLoc = S->getLocStart();            Out << S->getStmtClassName() << ' ' << (void*) S << ' ';         -          S->printPretty(Out); +          LangOptions LO; // FIXME. +          S->printPretty(Out, 0, PrintingPolicy(LO));            if (SLoc.isFileID()) {                      Out << "\\lline=" @@ -3208,7 +3209,8 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :            SourceLocation SLoc = T->getLocStart();            Out << "\\|Terminator: "; -          E.getSrc()->printTerminator(Out); +          LangOptions LO; // FIXME. +          E.getSrc()->printTerminator(Out, LO);            if (SLoc.isFileID()) {              Out << "\\lline=" @@ -3223,11 +3225,12 @@ struct VISIBILITY_HIDDEN DOTGraphTraits<GRExprEngine::NodeTy*> :              if (Label) {                                        if (CaseStmt* C = dyn_cast<CaseStmt>(Label)) {                  Out << "\\lcase "; -                C->getLHS()->printPretty(Out); +                LangOptions LO; // FIXME. +                C->getLHS()->printPretty(Out, 0, PrintingPolicy(LO));                  if (Stmt* RHS = C->getRHS()) {                    Out << " .. "; -                  RHS->printPretty(Out); +                  RHS->printPretty(Out, 0, PrintingPolicy(LO));                  }                  Out << ":"; diff --git a/lib/Analysis/GRExprEngineInternalChecks.cpp b/lib/Analysis/GRExprEngineInternalChecks.cpp index 76d26dd9f02a..a2ce79a2f390 100644 --- a/lib/Analysis/GRExprEngineInternalChecks.cpp +++ b/lib/Analysis/GRExprEngineInternalChecks.cpp @@ -566,7 +566,7 @@ public:      if (!FD)        return false; -    const NonNullAttr* Att = FD->getAttr<NonNullAttr>(BR.getContext()); +    const NonNullAttr* Att = FD->getAttr<NonNullAttr>();      if (!Att)        return false; diff --git a/lib/Analysis/GRState.cpp b/lib/Analysis/GRState.cpp index 493edc37bacb..54c0afbff33e 100644 --- a/lib/Analysis/GRState.cpp +++ b/lib/Analysis/GRState.cpp @@ -166,7 +166,8 @@ void GRState::print(llvm::raw_ostream& Out, const char* nl,      else { Out << nl; }      Out << " (" << (void*) I.getKey() << ") "; -    I.getKey()->printPretty(Out); +    LangOptions LO; // FIXME. +    I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));      Out << " : ";      I.getData().print(Out);    } @@ -183,7 +184,8 @@ void GRState::print(llvm::raw_ostream& Out, const char* nl,      else { Out << nl; }      Out << " (" << (void*) I.getKey() << ") "; -    I.getKey()->printPretty(Out); +    LangOptions LO; // FIXME. +    I.getKey()->printPretty(Out, 0, PrintingPolicy(LO));      Out << " : ";      I.getData().print(Out);    } diff --git a/lib/Analysis/LiveVariables.cpp b/lib/Analysis/LiveVariables.cpp index b0eb37b06524..aead7f43ad8f 100644 --- a/lib/Analysis/LiveVariables.cpp +++ b/lib/Analysis/LiveVariables.cpp @@ -135,9 +135,10 @@ void TransferFuncs::Visit(Stmt *S) {      StmtVisitor<TransferFuncs,void>::Visit(S);    } -  else +  else {      // For block-level expressions, mark that they are live.      LiveState(S,AD) = Alive; +  }  }  void TransferFuncs::VisitTerminator(CFGBlock* B) { diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp index c8e027579a30..45305403585a 100644 --- a/lib/Analysis/MemRegion.cpp +++ b/lib/Analysis/MemRegion.cpp @@ -143,6 +143,10 @@ void CodeTextRegion::Profile(llvm::FoldingSetNodeID& ID) const {  // Region pretty-printing.  //===----------------------------------------------------------------------===// +void MemRegion::printStdErr() const { +  print(llvm::errs()); +} +  std::string MemRegion::getString() const {    std::string s;    llvm::raw_string_ostream os(s); @@ -184,7 +188,8 @@ void FieldRegion::print(llvm::raw_ostream& os) const {  }  void StringRegion::print(llvm::raw_ostream& os) const { -  Str->printPretty(os); +  LangOptions LO; // FIXME. +  Str->printPretty(os, 0, PrintingPolicy(LO));  }  void SymbolicRegion::print(llvm::raw_ostream& os) const { @@ -218,6 +223,10 @@ MemSpaceRegion* MemRegionManager::getStackRegion() {    return LazyAllocate(stack);  } +MemSpaceRegion* MemRegionManager::getStackArgumentsRegion() { +  return LazyAllocate(stackArguments); +} +  MemSpaceRegion* MemRegionManager::getGlobalsRegion() {    return LazyAllocate(globals);  } @@ -327,8 +336,10 @@ const MemSpaceRegion *MemRegion::getMemorySpace() const {  }  bool MemRegion::hasStackStorage() const { -  if (const MemSpaceRegion *MS = getMemorySpace()) -    return MS == getMemRegionManager()->getStackRegion(); +  if (const MemSpaceRegion *MS = getMemorySpace()) { +    MemRegionManager *Mgr = getMemRegionManager(); +    return MS == Mgr->getStackRegion() || MS == Mgr->getStackArgumentsRegion(); +  }    return false;  } @@ -343,10 +354,35 @@ bool MemRegion::hasHeapStorage() const {  bool MemRegion::hasHeapOrStackStorage() const {    if (const MemSpaceRegion *MS = getMemorySpace()) {      MemRegionManager *Mgr = getMemRegionManager(); -    return MS == Mgr->getHeapRegion() || MS == Mgr->getStackRegion(); +    return MS == Mgr->getHeapRegion() +      || MS == Mgr->getStackRegion() +      || MS == Mgr->getStackArgumentsRegion();    }    return false; -}   +} + +bool MemRegion::hasGlobalsStorage() const { +  if (const MemSpaceRegion *MS = getMemorySpace()) +    return MS == getMemRegionManager()->getGlobalsRegion(); + +  return false; +} + +bool MemRegion::hasParametersStorage() const { +  if (const MemSpaceRegion *MS = getMemorySpace()) +    return MS == getMemRegionManager()->getStackArgumentsRegion(); +   +  return false; +} + +bool MemRegion::hasGlobalsOrParametersStorage() const { +  if (const MemSpaceRegion *MS = getMemorySpace()) { +    MemRegionManager *Mgr = getMemRegionManager(); +    return MS == Mgr->getGlobalsRegion() +    || MS == Mgr->getStackArgumentsRegion(); +  } +  return false; +}  //===----------------------------------------------------------------------===//  // View handling. diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index d45048de1a42..23e8b738b601 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/lib/Analysis/RegionStore.cpp @@ -347,9 +347,6 @@ public:    // FIXME: Remove.    ASTContext& getContext() { return StateMgr.getContext(); } - -  // FIXME: Use ValueManager? -  SymbolManager& getSymbolManager() { return StateMgr.getSymbolManager(); }    };  } // end anonymous namespace @@ -822,12 +819,6 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {    const TypedRegion *R = cast<TypedRegion>(MR);    assert(R && "bad region"); -  if (const FieldRegion* FR = dyn_cast<FieldRegion>(R)) -    return RetrieveField(state, FR); - -  if (const ElementRegion* ER = dyn_cast<ElementRegion>(R)) -    return RetrieveElement(state, ER); -    // FIXME: We should eventually handle funny addressing.  e.g.:    //    //   int x = ...; @@ -848,6 +839,12 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {    // FIXME: handle Vector types.    if (RTy->isVectorType())        return UnknownVal(); + +  if (const FieldRegion* FR = dyn_cast<FieldRegion>(R)) +    return RetrieveField(state, FR); + +  if (const ElementRegion* ER = dyn_cast<ElementRegion>(R)) +    return RetrieveElement(state, ER);    RegionBindingsTy B = GetRegionBindings(state->getStore());    RegionBindingsTy::data_type* V = B.lookup(R); @@ -882,14 +879,8 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {      if (VD == SelfDecl)        return loc::MemRegionVal(getSelfRegion(0)); -    if (isa<ParmVarDecl>(VD) || isa<ImplicitParamDecl>(VD) || -        VD->hasGlobalStorage()) { -      QualType VTy = VD->getType(); -      if (Loc::IsLocType(VTy) || VTy->isIntegerType()) -        return ValMgr.getRegionValueSymbolVal(VR); -      else -        return UnknownVal(); -    } +    if (VR->hasGlobalsOrParametersStorage()) +      return ValMgr.getRegionValueSymbolValOrUnknown(VR, VD->getType());    }      if (R->hasHeapOrStackStorage()) { @@ -907,23 +898,21 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {      RTy = T->getAsPointerType()->getPointeeType();    } -  // All other integer values are symbolic. -  if (Loc::IsLocType(RTy) || RTy->isIntegerType()) -    return ValMgr.getRegionValueSymbolVal(R, RTy); -  else -    return UnknownVal(); +  // All other values are symbolic. +  return ValMgr.getRegionValueSymbolValOrUnknown(R, RTy);  }  SVal RegionStoreManager::RetrieveElement(const GRState* state,                                           const ElementRegion* R) {    // Check if the region has a binding.    RegionBindingsTy B = GetRegionBindings(state->getStore()); -  const SVal* V = B.lookup(R); -  if (V) +  if (const SVal* V = B.lookup(R))      return *V; +  const MemRegion* superR = R->getSuperRegion(); +    // Check if the region is an element region of a string literal. -  if (const StringRegion *StrR=dyn_cast<StringRegion>(R->getSuperRegion())) { +  if (const StringRegion *StrR=dyn_cast<StringRegion>(superR)) {      const StringLiteral *Str = StrR->getStringLiteral();      SVal Idx = R->getIndex();      if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Idx)) { @@ -937,18 +926,38 @@ SVal RegionStoreManager::RetrieveElement(const GRState* state,      }    } -  const MemRegion* SuperR = R->getSuperRegion(); -  const SVal* D = state->get<RegionDefaultValue>(SuperR); - -  if (D) { +  // Check if the super region has a default value. +  if (const SVal *D = state->get<RegionDefaultValue>(superR)) {      if (D->hasConjuredSymbol())        return ValMgr.getRegionValueSymbolVal(R);      else        return *D;    } -  if (R->hasHeapOrStackStorage()) +  // Check if the super region has a binding. +  if (B.lookup(superR)) { +    // We do not extract the bit value from super region for now. +    return UnknownVal(); +  } +   +  if (R->hasHeapStorage()) { +    // FIXME: If the region has heap storage and we know nothing special +    // about its bindings, should we instead return UnknownVal?  Seems like +    // we should only return UndefinedVal in the cases where we know the value +    // will be undefined.      return UndefinedVal(); +  } + +  if (R->hasStackStorage() && !R->hasParametersStorage()) { +    // Currently we don't reason specially about Clang-style vectors.  Check +    // if superR is a vector and if so return Unknown. +    if (const TypedRegion *typedSuperR = dyn_cast<TypedRegion>(superR)) { +      if (typedSuperR->getValueType(getContext())->isVectorType()) +        return UnknownVal(); +    } + +    return UndefinedVal(); +  }    QualType Ty = R->getValueType(getContext()); @@ -957,10 +966,7 @@ SVal RegionStoreManager::RetrieveElement(const GRState* state,    if (const QualType *p = state->get<RegionCasts>(R))      Ty = (*p)->getAsPointerType()->getPointeeType(); -  if (Loc::IsLocType(Ty) || Ty->isIntegerType()) -    return ValMgr.getRegionValueSymbolVal(R, Ty); -  else -    return UnknownVal(); +  return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty);  }  SVal RegionStoreManager::RetrieveField(const GRState* state,  @@ -969,13 +975,11 @@ SVal RegionStoreManager::RetrieveField(const GRState* state,    // Check if the region has a binding.    RegionBindingsTy B = GetRegionBindings(state->getStore()); -  const SVal* V = B.lookup(R); -  if (V) +  if (const SVal* V = B.lookup(R))      return *V; -  const MemRegion* SuperR = R->getSuperRegion(); -  const SVal* D = state->get<RegionDefaultValue>(SuperR); -  if (D) { +  const MemRegion* superR = R->getSuperRegion(); +  if (const SVal* D = state->get<RegionDefaultValue>(superR)) {      if (D->hasConjuredSymbol())        return ValMgr.getRegionValueSymbolVal(R); @@ -988,7 +992,11 @@ SVal RegionStoreManager::RetrieveField(const GRState* state,      assert(0 && "Unknown default value");    } -  if (R->hasHeapOrStackStorage()) +  // FIXME: Is this correct?  Should it be UnknownVal? +  if (R->hasHeapStorage()) +    return UndefinedVal(); +   +  if (R->hasStackStorage() && !R->hasParametersStorage())      return UndefinedVal();    // If the region is already cast to another type, use that type to create the @@ -998,11 +1006,8 @@ SVal RegionStoreManager::RetrieveField(const GRState* state,      Ty = tmp->getAsPointerType()->getPointeeType();    } -  // All other integer values are symbolic. -  if (Loc::IsLocType(Ty) || Ty->isIntegerType()) -    return ValMgr.getRegionValueSymbolVal(R, Ty); -  else -    return UnknownVal(); +  // All other values are symbolic. +  return ValMgr.getRegionValueSymbolValOrUnknown(R, Ty);  }  SVal RegionStoreManager::RetrieveStruct(const GRState *state,  @@ -1018,8 +1023,7 @@ SVal RegionStoreManager::RetrieveStruct(const GRState *state,    // FIXME: We shouldn't use a std::vector.  If RecordDecl doesn't have a    // reverse iterator, we should implement one. -  std::vector<FieldDecl *> Fields(RD->field_begin(getContext()),  -                                  RD->field_end(getContext())); +  std::vector<FieldDecl *> Fields(RD->field_begin(), RD->field_end());    for (std::vector<FieldDecl *>::reverse_iterator Field = Fields.rbegin(),                                                 FieldEnd = Fields.rend(); @@ -1074,6 +1078,9 @@ Store RegionStoreManager::Remove(Store store, Loc L) {  }  const GRState *RegionStoreManager::Bind(const GRState *state, Loc L, SVal V) { +  if (isa<loc::ConcreteInt>(L)) +    return state; +    // If we get here, the location should be a region.    const MemRegion* R = cast<loc::MemRegionVal>(L).getRegion(); @@ -1204,8 +1211,7 @@ RegionStoreManager::BindStruct(const GRState *state, const TypedRegion* R,    RecordDecl::field_iterator FI, FE; -  for (FI = RD->field_begin(getContext()), FE = RD->field_end(getContext()); -       FI != FE; ++FI, ++VI) { +  for (FI = RD->field_begin(), FE = RD->field_end(); FI != FE; ++FI, ++VI) {      if (VI == VE)        break; @@ -1357,8 +1363,9 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,      IntermediateRoots.pop_back();      if (const VarRegion* VR = dyn_cast<VarRegion>(R)) { -      if (SymReaper.isLive(Loc, VR->getDecl())) +      if (SymReaper.isLive(Loc, VR->getDecl())) {          RegionRoots.push_back(VR); // This is a live "root". +      }      }       else if (const SymbolicRegion* SR = dyn_cast<SymbolicRegion>(R)) {        if (SymReaper.isLive(SR->getSymbol())) @@ -1366,19 +1373,19 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,      }      else {        // Get the super region for R. -      const MemRegion* SuperR = cast<SubRegion>(R)->getSuperRegion(); +      const MemRegion* superR = cast<SubRegion>(R)->getSuperRegion();        // Get the current set of subregions for SuperR. -      const SubRegionsTy* SRptr = SubRegMap.lookup(SuperR); +      const SubRegionsTy* SRptr = SubRegMap.lookup(superR);        SubRegionsTy SRs = SRptr ? *SRptr : SubRegF.GetEmptySet();        // Add R to the subregions of SuperR. -      SubRegMap = SubRegMapF.Add(SubRegMap, SuperR, SubRegF.Add(SRs, R)); +      SubRegMap = SubRegMapF.Add(SubRegMap, superR, SubRegF.Add(SRs, R));        // Super region may be VarRegion or subregion of another VarRegion. Add it        // to the work list. -      if (isa<SubRegion>(SuperR)) -        IntermediateRoots.push_back(SuperR); +      if (isa<SubRegion>(superR)) +        IntermediateRoots.push_back(superR);      }    } @@ -1409,9 +1416,19 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,        SVal X = *Xptr;        UpdateLiveSymbols(X, SymReaper); // Update the set of live symbols. -      // If X is a region, then add it the RegionRoots. -      if (loc::MemRegionVal* RegionX = dyn_cast<loc::MemRegionVal>(&X)) -        RegionRoots.push_back(RegionX->getRegion()); +      // If X is a region, then add it to the RegionRoots. +      if (const MemRegion *RX = X.getAsRegion()) { +        RegionRoots.push_back(RX); + +        // Mark the super region of the RX as live. +        // e.g.: int x; char *y = (char*) &x; if (*y) ...  +        // 'y' => element region. 'x' is its super region. +        // We only add one level super region for now. +        // FIXME: maybe multiple level of super regions should be added. +        if (const SubRegion *SR = dyn_cast<SubRegion>(RX)) { +          RegionRoots.push_back(SR->getSuperRegion()); +        } +      }      }      // Get the subregions of R.  These are RegionRoots as well since they @@ -1422,6 +1439,7 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,      for (SubRegionsTy::iterator I=SR.begin(), E=SR.end(); I!=E; ++I)        RegionRoots.push_back(*I); +    }    // We have now scanned the store, marking reachable regions and symbols @@ -1429,7 +1447,6 @@ Store RegionStoreManager::RemoveDeadBindings(const GRState *state, Stmt* Loc,    // as well as update DSymbols with the set symbols that are now dead.      for (RegionBindingsTy::iterator I = B.begin(), E = B.end(); I != E; ++I) {      const MemRegion* R = I.getKey(); -          // If this region live?  Is so, none of its symbols are dead.      if (Marked.count(R))        continue; diff --git a/lib/Analysis/SVals.cpp b/lib/Analysis/SVals.cpp index 7d1850d73095..d711ce0a225e 100644 --- a/lib/Analysis/SVals.cpp +++ b/lib/Analysis/SVals.cpp @@ -114,6 +114,13 @@ const SymExpr *SVal::getAsSymbolicExpression() const {    return getAsSymbol();  } +const MemRegion *SVal::getAsRegion() const { +  if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) +    return X->getRegion(); + +  return 0; +} +  bool SVal::symbol_iterator::operator==(const symbol_iterator &X) const {    return itr == X.itr;  } diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp index 5aa756e14be3..cb099862f055 100644 --- a/lib/Analysis/Store.cpp +++ b/lib/Analysis/Store.cpp @@ -88,10 +88,10 @@ StoreManager::CastRegion(const GRState* state, const MemRegion* R,          // If the super region is an element region, strip it away.          // FIXME: Is this the right thing to do in all cases? -        const TypedRegion *Base = isa<ElementRegion>(TR) ? -                                  cast<TypedRegion>(TR->getSuperRegion()) : TR; +        const MemRegion *Base = isa<ElementRegion>(TR) ? TR->getSuperRegion() +                                                       : TR;          ElementRegion* ER = MRMgr.getElementRegion(Pointee, Idx, Base,  -						   StateMgr.getContext()); +                                                   StateMgr.getContext());          return CastResult(state, ER);        }      }  | 
