summaryrefslogtreecommitdiff
path: root/lib/Analysis
diff options
context:
space:
mode:
authorEd Schouten <ed@FreeBSD.org>2009-07-04 13:58:54 +0000
committerEd Schouten <ed@FreeBSD.org>2009-07-04 13:58:54 +0000
commit5362a71c02e7d448a8ce98cf00c47e353fba5d04 (patch)
tree8ddfe382e1c6d590dc240e76f7cd45cea5c78e24 /lib/Analysis
parent4ebdf5c4f587daef4e0be499802eac3a7a49bf2f (diff)
Notes
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/BasicStore.cpp104
-rw-r--r--lib/Analysis/BugReporter.cpp7
-rw-r--r--lib/Analysis/CFRefCount.cpp57
-rw-r--r--lib/Analysis/CheckDeadStores.cpp4
-rw-r--r--lib/Analysis/CheckObjCDealloc.cpp14
-rw-r--r--lib/Analysis/CheckObjCInstMethSignature.cpp8
-rw-r--r--lib/Analysis/CheckObjCUnusedIVars.cpp15
-rw-r--r--lib/Analysis/Environment.cpp15
-rw-r--r--lib/Analysis/GRExprEngine.cpp15
-rw-r--r--lib/Analysis/GRExprEngineInternalChecks.cpp2
-rw-r--r--lib/Analysis/GRState.cpp6
-rw-r--r--lib/Analysis/LiveVariables.cpp3
-rw-r--r--lib/Analysis/MemRegion.cpp46
-rw-r--r--lib/Analysis/RegionStore.cpp135
-rw-r--r--lib/Analysis/SVals.cpp7
-rw-r--r--lib/Analysis/Store.cpp6
16 files changed, 263 insertions, 181 deletions
diff --git a/lib/Analysis/BasicStore.cpp b/lib/Analysis/BasicStore.cpp
index 8fbce528fa9a6..19d641ee9753a 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 38ea458a65994..3db96ca9eacba 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 f4a28e0c19fd2..3cca482633caf 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 0f61a5ee916a1..69433d6396a5b 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 2ba7d868e90b2..a14ae265128b9 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 9fec7c1dc1115..28814867bd589 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 21dc658dfa1a5..0063c40482a0e 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 2b751df830c2f..3f8f14dcb0b4e 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 8b4f5c8f11c10..d9117f5930e61 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 76d26dd9f02af..a2ce79a2f390d 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 493edc37bacbb..54c0afbff33ee 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 b0eb37b065244..aead7f43ad8f6 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 c8e027579a309..45305403585a8 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 d45048de1a42f..23e8b738b601f 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 7d1850d730957..d711ce0a225e3 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 5aa756e14be37..cb099862f0551 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);
}
}