summaryrefslogtreecommitdiffstats
path: root/lib/Checker/RegionStore.cpp
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-04-02 08:55:10 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-04-02 08:55:10 +0000
commit07b2cfcdb817cc0790420f159a313d61e7241cb9 (patch)
treed374cdca417e76f1bf101f139dba2db1d10ee8f7 /lib/Checker/RegionStore.cpp
parent1e255aab650a7fa2047fd953cae65b12215280af (diff)
downloadFreeBSD-src-07b2cfcdb817cc0790420f159a313d61e7241cb9.zip
FreeBSD-src-07b2cfcdb817cc0790420f159a313d61e7241cb9.tar.gz
Update clang to r100181.
Diffstat (limited to 'lib/Checker/RegionStore.cpp')
-rw-r--r--lib/Checker/RegionStore.cpp108
1 files changed, 62 insertions, 46 deletions
diff --git a/lib/Checker/RegionStore.cpp b/lib/Checker/RegionStore.cpp
index c2b702a..c97da33 100644
--- a/lib/Checker/RegionStore.cpp
+++ b/lib/Checker/RegionStore.cpp
@@ -536,15 +536,15 @@ public:
// First visit the cluster.
static_cast<DERIVED*>(this)->VisitCluster(baseR, C->begin(), C->end());
- // Next, visit the region.
- static_cast<DERIVED*>(this)->VisitRegion(baseR);
+ // Next, visit the base region.
+ static_cast<DERIVED*>(this)->VisitBaseRegion(baseR);
}
}
public:
void VisitAddedToCluster(const MemRegion *baseR, RegionCluster &C) {}
void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E) {}
- void VisitRegion(const MemRegion *baseR) {}
+ void VisitBaseRegion(const MemRegion *baseR) {}
};
}
@@ -580,7 +580,7 @@ public:
Ex(ex), Count(count), IS(is) {}
void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E);
- void VisitRegion(const MemRegion *baseR);
+ void VisitBaseRegion(const MemRegion *baseR);
private:
void VisitBinding(SVal V);
@@ -627,7 +627,7 @@ void InvalidateRegionsWorker::VisitCluster(const MemRegion *baseR,
}
}
-void InvalidateRegionsWorker::VisitRegion(const MemRegion *baseR) {
+void InvalidateRegionsWorker::VisitBaseRegion(const MemRegion *baseR) {
if (IS) {
// Symbolic region? Mark that symbol touched by the invalidation.
if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(baseR))
@@ -787,9 +787,12 @@ DefinedOrUnknownSVal RegionStoreManager::getSizeInElements(const GRState *state,
return ValMgr.makeIntVal(CAT->getSize(), false);
}
- // Clients can use ordinary variables as if they were arrays. These
- // essentially are arrays of size 1.
- return ValMgr.makeIntVal(1, false);
+ // Clients can reinterpret ordinary variables as arrays, possibly of
+ // another type. The width is rounded down to ensure that an access is
+ // entirely within bounds.
+ CharUnits VarSize = getContext().getTypeSizeInChars(T);
+ CharUnits EleSize = getContext().getTypeSizeInChars(EleTy);
+ return ValMgr.makeIntVal(VarSize / EleSize, false);
}
}
@@ -963,7 +966,7 @@ Optional<SVal> RegionStoreManager::getDefaultBinding(RegionBindings B,
Optional<SVal> RegionStoreManager::getBinding(RegionBindings B,
const MemRegion *R) {
- if (Optional<SVal> V = getDirectBinding(B, R))
+ if (const Optional<SVal> &V = getDirectBinding(B, R))
return V;
return getDefaultBinding(B, R);
@@ -1044,7 +1047,7 @@ SVal RegionStoreManager::Retrieve(Store store, Loc L, QualType T) {
}
#endif
- if (RTy->isStructureType())
+ if (RTy->isStructureType() || RTy->isClassType())
return RetrieveStruct(store, R);
// FIXME: Handle unions.
@@ -1144,7 +1147,7 @@ SVal RegionStoreManager::RetrieveElement(Store store,
const ElementRegion* R) {
// Check if the region has a binding.
RegionBindings B = GetRegionBindings(store);
- if (Optional<SVal> V = getDirectBinding(B, R))
+ if (const Optional<SVal> &V = getDirectBinding(B, R))
return *V;
const MemRegion* superR = R->getSuperRegion();
@@ -1175,7 +1178,7 @@ SVal RegionStoreManager::RetrieveElement(Store store,
}
// Check if the immediate super region has a direct binding.
- if (Optional<SVal> V = getDirectBinding(B, superR)) {
+ if (const Optional<SVal> &V = getDirectBinding(B, superR)) {
if (SymbolRef parentSym = V->getAsSymbol())
return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
@@ -1203,7 +1206,7 @@ SVal RegionStoreManager::RetrieveField(Store store,
// Check if the region has a binding.
RegionBindings B = GetRegionBindings(store);
- if (Optional<SVal> V = getDirectBinding(B, R))
+ if (const Optional<SVal> &V = getDirectBinding(B, R))
return *V;
QualType Ty = R->getValueType(getContext());
@@ -1278,13 +1281,13 @@ SVal RegionStoreManager::RetrieveObjCIvar(Store store, const ObjCIvarRegion* R){
// Check if the region has a binding.
RegionBindings B = GetRegionBindings(store);
- if (Optional<SVal> V = getDirectBinding(B, R))
+ if (const Optional<SVal> &V = getDirectBinding(B, R))
return *V;
const MemRegion *superR = R->getSuperRegion();
// Check if the super region has a default binding.
- if (Optional<SVal> V = getDefaultBinding(B, superR)) {
+ if (const Optional<SVal> &V = getDefaultBinding(B, superR)) {
if (SymbolRef parentSym = V->getAsSymbol())
return ValMgr.getDerivedRegionValueSymbolVal(parentSym, R);
@@ -1300,7 +1303,7 @@ SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) {
// Check if the region has a binding.
RegionBindings B = GetRegionBindings(store);
- if (Optional<SVal> V = getDirectBinding(B, R))
+ if (const Optional<SVal> &V = getDirectBinding(B, R))
return *V;
// Lazily derive a value for the VarRegion.
@@ -1313,8 +1316,23 @@ SVal RegionStoreManager::RetrieveVar(Store store, const VarRegion *R) {
return ValMgr.getRegionValueSymbolVal(R);
if (isa<GlobalsSpaceRegion>(MS)) {
- if (VD->isFileVarDecl())
+ if (VD->isFileVarDecl()) {
+ // Is 'VD' declared constant? If so, retrieve the constant value.
+ QualType CT = Ctx.getCanonicalType(T);
+ if (CT.isConstQualified()) {
+ const Expr *Init = VD->getInit();
+ // Do the null check first, as we want to call 'IgnoreParenCasts'.
+ if (Init)
+ if (const IntegerLiteral *IL =
+ dyn_cast<IntegerLiteral>(Init->IgnoreParenCasts())) {
+ const nonloc::ConcreteInt &V = ValMgr.makeIntVal(IL);
+ return ValMgr.getSValuator().EvalCast(V, Init->getType(),
+ IL->getType());
+ }
+ }
+
return ValMgr.getRegionValueSymbolVal(R);
+ }
if (T->isIntegerType())
return ValMgr.makeIntVal(0, T);
@@ -1337,8 +1355,7 @@ SVal RegionStoreManager::RetrieveLazySymbol(const TypedRegion *R) {
SVal RegionStoreManager::RetrieveStruct(Store store, const TypedRegion* R) {
QualType T = R->getValueType(getContext());
- assert(T->isStructureType());
- assert(T->getAsStructureType()->getDecl()->isDefinition());
+ assert(T->isStructureType() || T->isClassType());
return ValMgr.makeLazyCompoundVal(store, R);
}
@@ -1692,8 +1709,8 @@ public:
// Called by ClusterAnalysis.
void VisitAddedToCluster(const MemRegion *baseR, RegionCluster &C);
void VisitCluster(const MemRegion *baseR, BindingKey *I, BindingKey *E);
- void VisitRegion(const MemRegion *baseR);
+ void VisitBindingKey(BindingKey K);
bool UpdatePostponed();
void VisitBinding(SVal V);
};
@@ -1730,11 +1747,8 @@ void RemoveDeadBindingsWorker::VisitAddedToCluster(const MemRegion *baseR,
void RemoveDeadBindingsWorker::VisitCluster(const MemRegion *baseR,
BindingKey *I, BindingKey *E) {
- for ( ; I != E; ++I) {
- const MemRegion *R = I->getRegion();
- if (R != baseR)
- VisitRegion(R);
- }
+ for ( ; I != E; ++I)
+ VisitBindingKey(*I);
}
void RemoveDeadBindingsWorker::VisitBinding(SVal V) {
@@ -1762,34 +1776,36 @@ void RemoveDeadBindingsWorker::VisitBinding(SVal V) {
SymReaper.markLive(*SI);
}
-void RemoveDeadBindingsWorker::VisitRegion(const MemRegion *R) {
+void RemoveDeadBindingsWorker::VisitBindingKey(BindingKey K) {
+ const MemRegion *R = K.getRegion();
+
// Mark this region "live" by adding it to the worklist. This will cause
// use to visit all regions in the cluster (if we haven't visited them
// already).
- AddToWorkList(R);
-
- // Mark the symbol for any live SymbolicRegion as "live". This means we
- // should continue to track that symbol.
- if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
- SymReaper.markLive(SymR->getSymbol());
+ if (AddToWorkList(R)) {
+ // Mark the symbol for any live SymbolicRegion as "live". This means we
+ // should continue to track that symbol.
+ if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
+ SymReaper.markLive(SymR->getSymbol());
+
+ // For BlockDataRegions, enqueue the VarRegions for variables marked
+ // with __block (passed-by-reference).
+ // via BlockDeclRefExprs.
+ if (const BlockDataRegion *BD = dyn_cast<BlockDataRegion>(R)) {
+ for (BlockDataRegion::referenced_vars_iterator
+ RI = BD->referenced_vars_begin(), RE = BD->referenced_vars_end();
+ RI != RE; ++RI) {
+ if ((*RI)->getDecl()->getAttr<BlocksAttr>())
+ AddToWorkList(*RI);
+ }
- // For BlockDataRegions, enqueue the VarRegions for variables marked
- // with __block (passed-by-reference).
- // via BlockDeclRefExprs.
- if (const BlockDataRegion *BD = dyn_cast<BlockDataRegion>(R)) {
- for (BlockDataRegion::referenced_vars_iterator
- RI = BD->referenced_vars_begin(), RE = BD->referenced_vars_end();
- RI != RE; ++RI) {
- if ((*RI)->getDecl()->getAttr<BlocksAttr>())
- AddToWorkList(*RI);
+ // No possible data bindings on a BlockDataRegion.
+ return;
}
-
- // No possible data bindings on a BlockDataRegion.
- return;
}
- // Get the data binding for R (if any).
- if (Optional<SVal> V = RM.getBinding(B, R))
+ // Visit the data binding for K.
+ if (const SVal *V = RM.Lookup(B, K))
VisitBinding(*V);
}
OpenPOWER on IntegriCloud