[cfe-commits] r95200 - in /cfe/trunk: lib/Checker/RegionStore.cpp test/Analysis/misc-ps.m
Ted Kremenek
kremenek at apple.com
Tue Feb 2 20:16:03 PST 2010
Author: kremenek
Date: Tue Feb 2 22:16:00 2010
New Revision: 95200
URL: http://llvm.org/viewvc/llvm-project?rev=95200&view=rev
Log:
Fix regression in RegionStore due to recent changes in
RegionStoreManager::InvalidateRegions() by adjusting the worklist to
iterate over BindingKeys instead of MemRegions. We also only need to
do the actual invalidation work on base regions, and for non-base
regions just blow away their bindings.
Modified:
cfe/trunk/lib/Checker/RegionStore.cpp
cfe/trunk/test/Analysis/misc-ps.m
Modified: cfe/trunk/lib/Checker/RegionStore.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/RegionStore.cpp?rev=95200&r1=95199&r2=95200&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/RegionStore.cpp (original)
+++ cfe/trunk/lib/Checker/RegionStore.cpp Tue Feb 2 22:16:00 2010
@@ -506,9 +506,10 @@
namespace {
class InvalidateRegionsWorker {
- typedef BumpVector<const MemRegion *> RegionCluster;
+ typedef BumpVector<BindingKey> RegionCluster;
typedef llvm::DenseMap<const MemRegion *, RegionCluster *> ClusterMap;
- typedef llvm::SmallVector<RegionCluster*, 10> WorkList;
+ typedef llvm::SmallVector<std::pair<const MemRegion *,RegionCluster*>, 10>
+ WorkList;
BumpVectorContext BVC;
ClusterMap ClusterM;
@@ -523,25 +524,30 @@
StoreManager::InvalidatedSymbols *IS);
private:
+ void AddToWorkList(BindingKey K);
void AddToWorkList(const MemRegion *R);
- void AddToCluster(const MemRegion *R);
+ void AddToCluster(BindingKey K);
RegionCluster **getCluster(const MemRegion *R);
};
}
-void InvalidateRegionsWorker::AddToCluster(const MemRegion *R) {
+void InvalidateRegionsWorker::AddToCluster(BindingKey K) {
+ const MemRegion *R = K.getRegion();
const MemRegion *baseR = R->getBaseRegion();
RegionCluster **CPtr = getCluster(baseR);
- if (R != baseR) {
- assert(*CPtr);
- (*CPtr)->push_back(R, BVC);
- }
+ assert(*CPtr);
+ (*CPtr)->push_back(K, BVC);
+}
+
+void InvalidateRegionsWorker::AddToWorkList(BindingKey K) {
+ AddToWorkList(K.getRegion());
}
void InvalidateRegionsWorker::AddToWorkList(const MemRegion *R) {
- RegionCluster **CPtr = getCluster( R->getBaseRegion());
+ const MemRegion *baseR = R->getBaseRegion();
+ RegionCluster **CPtr = getCluster(baseR);
if (RegionCluster *C = *CPtr) {
- WL.push_back(C);
+ WL.push_back(std::make_pair(baseR, C));
*CPtr = NULL;
}
}
@@ -552,7 +558,6 @@
if (!CRef) {
void *Mem = BVC.getAllocator().Allocate<RegionCluster>();
CRef = new (Mem) RegionCluster(BVC, 10);
- CRef->push_back(R, BVC);
}
return &CRef;
}
@@ -571,9 +576,12 @@
// Scan the entire store and make the region clusters.
for (RegionBindings::iterator RI = B.begin(), RE = B.end(); RI != RE; ++RI) {
- AddToCluster(RI.getKey().getRegion());
- if (const MemRegion *R = RI.getData().getAsRegion())
- AddToCluster(R);
+ AddToCluster(RI.getKey());
+ if (const MemRegion *R = RI.getData().getAsRegion()) {
+ // Generate a cluster, but don't add the region to the cluster
+ // if there aren't any bindings.
+ getCluster(R->getBaseRegion());
+ }
}
// Add the cluster for I .. E to a worklist.
@@ -581,94 +589,92 @@
AddToWorkList(*I);
while (!WL.empty()) {
- RegionCluster *C = WL.back();
+ const MemRegion *baseR;
+ RegionCluster *C;
+ llvm::tie(baseR, C) = WL.back();
WL.pop_back();
for (RegionCluster::iterator I = C->begin(), E = C->end(); I != E; ++I) {
- const MemRegion *R = *I;
+ BindingKey K = *I;
// Get the old binding. Is it a region? If so, add it to the worklist.
- if (Optional<SVal> V = RM.getDirectBinding(B, R)) {
- if (const MemRegion *RV = V->getAsRegion())
- AddToWorkList(RV);
+ if (const SVal *V = RM.Lookup(B, K)) {
+ if (const MemRegion *R = V->getAsRegion())
+ AddToWorkList(R);
// A symbol? Mark it touched by the invalidation.
if (IS)
if (SymbolRef Sym = V->getAsSymbol())
IS->insert(Sym);
}
-
- // Symbolic region? Mark that symbol touched by the invalidation.
- if (IS)
- if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R))
- IS->insert(SR->getSymbol());
-
- // BlockDataRegion? If so, invalidate captured variables that are passed
- // by reference.
- if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(R)) {
- for (BlockDataRegion::referenced_vars_iterator
- I = BR->referenced_vars_begin(), E = BR->referenced_vars_end() ;
- I != E; ++I) {
- const VarRegion *VR = *I;
- if (VR->getDecl()->getAttr<BlocksAttr>())
- AddToWorkList(VR);
- }
- continue;
- }
-
- // Handle the region itself.
- if (isa<AllocaRegion>(R) || isa<SymbolicRegion>(R)) {
- // Invalidate the region by setting its default value to
- // conjured symbol. The type of the symbol is irrelavant.
- DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(R, Ex, Ctx.IntTy,
- Count);
- B = RM.Add(B, R, BindingKey::Default, V);
- continue;
- }
- if (!R->isBoundable())
- continue;
-
- const TypedRegion *TR = cast<TypedRegion>(R);
- QualType T = TR->getValueType(Ctx);
+ B = RM.Remove(B, K);
+ }
- // Invalidate the binding.
- if (const RecordType *RT = T->getAsStructureType()) {
- const RecordDecl *RD = RT->getDecl()->getDefinition(Ctx);
- // No record definition. There is nothing we can do.
- if (!RD) {
- B = RM.Remove(B, R);
- continue;
- }
-
- // Invalidate the region by setting its default value to
- // conjured symbol. The type of the symbol is irrelavant.
- DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(R, Ex, Ctx.IntTy,
- Count);
- B = RM.Add(B, R, BindingKey::Default, V);
- continue;
- }
- if (const ArrayType *AT = Ctx.getAsArrayType(T)) {
- // Set the default value of the array to conjured symbol.
- DefinedOrUnknownSVal V =
- ValMgr.getConjuredSymbolVal(R, Ex, AT->getElementType(), Count);
- B = RM.Add(B, R, BindingKey::Default, V);
- continue;
+ // Now inspect the base region.
+
+ if (IS) {
+ // Symbolic region? Mark that symbol touched by the invalidation.
+ if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR))
+ IS->insert(SR->getSymbol());
+ }
+
+ // BlockDataRegion? If so, invalidate captured variables that are passed
+ // by reference.
+ if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(baseR)) {
+ for (BlockDataRegion::referenced_vars_iterator
+ I = BR->referenced_vars_begin(), E = BR->referenced_vars_end() ;
+ I != E; ++I) {
+ const VarRegion *VR = *I;
+ if (VR->getDecl()->getAttr<BlocksAttr>())
+ AddToWorkList(VR);
}
+ continue;
+ }
+
+ if (isa<AllocaRegion>(baseR) || isa<SymbolicRegion>(baseR)) {
+ // Invalidate the region by setting its default value to
+ // conjured symbol. The type of the symbol is irrelavant.
+ DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, Ctx.IntTy,
+ Count);
+ B = RM.Add(B, baseR, BindingKey::Default, V);
+ continue;
+ }
+
+ if (!baseR->isBoundable())
+ continue;
- // For fields and elements that aren't themselves structs or arrays,
- // just remove the binding. Base regions will get default values from
- // which the fields and elements will get lazily symbolicated.
- if (isa<FieldRegion>(R) || isa<ElementRegion>(R)) {
- B = RM.Remove(B, R, BindingKey::Direct);
+ const TypedRegion *TR = cast<TypedRegion>(baseR);
+ QualType T = TR->getValueType(Ctx);
+
+ // Invalidate the binding.
+ if (const RecordType *RT = T->getAsStructureType()) {
+ const RecordDecl *RD = RT->getDecl()->getDefinition(Ctx);
+ // No record definition. There is nothing we can do.
+ if (!RD) {
+ B = RM.Remove(B, baseR);
continue;
}
-
-
- DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(R, Ex, T, Count);
- assert(SymbolManager::canSymbolicate(T) || V.isUnknown());
- B = RM.Add(B, R, BindingKey::Direct, V);
+
+ // Invalidate the region by setting its default value to
+ // conjured symbol. The type of the symbol is irrelavant.
+ DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, Ctx.IntTy,
+ Count);
+ B = RM.Add(B, baseR, BindingKey::Default, V);
+ continue;
+ }
+
+ if (const ArrayType *AT = Ctx.getAsArrayType(T)) {
+ // Set the default value of the array to conjured symbol.
+ DefinedOrUnknownSVal V =
+ ValMgr.getConjuredSymbolVal(baseR, Ex, AT->getElementType(), Count);
+ B = RM.Add(B, baseR, BindingKey::Default, V);
+ continue;
}
+
+ DefinedOrUnknownSVal V = ValMgr.getConjuredSymbolVal(baseR, Ex, T, Count);
+ assert(SymbolManager::canSymbolicate(T) || V.isUnknown());
+ B = RM.Add(B, baseR, BindingKey::Direct, V);
}
// Create a new state with the updated bindings.
Modified: cfe/trunk/test/Analysis/misc-ps.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/misc-ps.m?rev=95200&r1=95199&r2=95200&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/misc-ps.m (original)
+++ cfe/trunk/test/Analysis/misc-ps.m Tue Feb 2 22:16:00 2010
@@ -866,3 +866,16 @@
baz_rev95119((double)value);
}
+//===----------------------------------------------------------------------===//
+// Handle loading a symbolic pointer from a symbolic region that was
+// invalidated by a call to an unknown function.
+//===----------------------------------------------------------------------===//
+
+void bar_rev95192(int **x);
+void foo_rev95192(int **x) {
+ *x = 0;
+ bar_rev95192(x);
+ // Not a null dereference.
+ **x = 1; // no-warning
+}
+
More information about the cfe-commits
mailing list