Create ElementRegion when the base is SymbolicRegion. This is like what we do
for FieldRegion. This enables us to track more values.
Simplify SymbolicRegion::getRValueType(). We assume the symbol always has
pointer type.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63928 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/MemRegion.cpp b/lib/Analysis/MemRegion.cpp
index e41c5f9..779f651 100644
--- a/lib/Analysis/MemRegion.cpp
+++ b/lib/Analysis/MemRegion.cpp
@@ -114,18 +114,14 @@
QualType SymbolicRegion::getRValueType(ASTContext& C) const {
const SymbolData& data = SymMgr.getSymbolData(sym);
- // FIXME: We could use the SymbolManager::getType() directly. But that
- // would hide the assumptions we made here. What is the type of a symbolic
- // region is unclear for other cases.
+ // Get the type of the symbol.
+ QualType T = data.getType(C);
- // For now we assume the symbol is a typed region rvalue.
- const TypedRegion* R
- = cast<TypedRegion>(cast<SymbolRegionRValue>(data).getRegion());
+ // Only when the symbol has pointer type it can have a symbolic region
+ // associated with it.
+ PointerType* PTy = cast<PointerType>(T.getTypePtr()->getDesugaredType());
- // Assume the region rvalue has a pointer type, only then we could have a
- // symbolic region associated with it.
- PointerType* PTy = cast<PointerType>(R->getRValueType(C).getTypePtr());
-
+ // The type of the symbolic region is the pointee type of the symbol.
return PTy->getPointeeType();
}
diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp
index e640087..93b5525 100644
--- a/lib/Analysis/RegionStore.cpp
+++ b/lib/Analysis/RegionStore.cpp
@@ -339,15 +339,20 @@
SVal RegionStoreManager::getLValueElement(const GRState* St,
SVal Base, SVal Offset) {
- if (Base.isUnknownOrUndef() || isa<loc::SymbolVal>(Base))
+ if (Base.isUnknownOrUndef())
return Base;
// Only handle integer offsets... for now.
if (!isa<nonloc::ConcreteInt>(Offset))
return UnknownVal();
- const TypedRegion *BaseRegion =
- cast<TypedRegion>(cast<loc::MemRegionVal>(Base).getRegion());
+ const TypedRegion* BaseRegion = 0;
+
+ if (isa<loc::SymbolVal>(Base))
+ BaseRegion = MRMgr.getSymbolicRegion(cast<loc::SymbolVal>(Base).getSymbol(),
+ StateMgr.getSymbolManager());
+ else
+ BaseRegion = cast<TypedRegion>(cast<loc::MemRegionVal>(Base).getRegion());
// Pointer of any type can be cast and used as array base.
const ElementRegion *ElemR = dyn_cast<ElementRegion>(BaseRegion);
@@ -476,6 +481,12 @@
return UnknownVal();
}
+ if (const SymbolicRegion* SR = dyn_cast<SymbolicRegion>(R)) {
+ // FIXME: Unsupported yet.
+ SR = 0;
+ return UnknownVal();
+ }
+
assert(0 && "Other regions are not supported yet.");
return UnknownVal();
}
diff --git a/test/Analysis/null-deref-ps.c b/test/Analysis/null-deref-ps.c
index 6daedf0..0c23690 100644
--- a/test/Analysis/null-deref-ps.c
+++ b/test/Analysis/null-deref-ps.c
@@ -212,3 +212,12 @@
*p = 1; // no-warning
}
+// Exercise ElementRegion with SymbolicRegion as super region.
+void foo(int* p) {
+ int *x;
+ int a;
+ if (p[0] == 1)
+ x = &a;
+ if (p[0] == 1)
+ *x; // no-warning
+}