summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Analysis/PathSensitive/MemRegion.h2
-rw-r--r--clang/include/clang/Analysis/PathSensitive/SVals.h2
-rw-r--r--clang/lib/Analysis/MemRegion.cpp20
-rw-r--r--clang/lib/Analysis/SVals.cpp8
4 files changed, 30 insertions, 2 deletions
diff --git a/clang/include/clang/Analysis/PathSensitive/MemRegion.h b/clang/include/clang/Analysis/PathSensitive/MemRegion.h
index bcd195e75e8..a65c71b5ec9 100644
--- a/clang/include/clang/Analysis/PathSensitive/MemRegion.h
+++ b/clang/include/clang/Analysis/PathSensitive/MemRegion.h
@@ -70,6 +70,8 @@ public:
std::string getString() const;
const MemSpaceRegion *getMemorySpace() const;
+
+ const MemRegion *getBaseRegion() const;
bool hasStackStorage() const;
diff --git a/clang/include/clang/Analysis/PathSensitive/SVals.h b/clang/include/clang/Analysis/PathSensitive/SVals.h
index 2ba370e5322..63110c6facb 100644
--- a/clang/include/clang/Analysis/PathSensitive/SVals.h
+++ b/clang/include/clang/Analysis/PathSensitive/SVals.h
@@ -371,6 +371,8 @@ public:
return static_cast<MemRegion*>(Data);
}
+ const MemRegion* getBaseRegion() const;
+
template <typename REGION>
const REGION* getRegionAs() const {
return llvm::dyn_cast<REGION>(getRegion());
diff --git a/clang/lib/Analysis/MemRegion.cpp b/clang/lib/Analysis/MemRegion.cpp
index 9b8f7c81e1c..a708bd3068f 100644
--- a/clang/lib/Analysis/MemRegion.cpp
+++ b/clang/lib/Analysis/MemRegion.cpp
@@ -398,3 +398,23 @@ const MemRegion *TypedViewRegion::removeViews() const {
}
return R;
}
+
+const MemRegion *MemRegion::getBaseRegion() const {
+ const MemRegion *R = this;
+ while (true) {
+ if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
+ // FIXME: generalize. Essentially we want to strip away ElementRegions
+ // that were layered on a symbolic region because of casts. We only
+ // want to strip away ElementRegions, however, where the index is 0.
+ SVal index = ER->getIndex();
+ if (nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&index)) {
+ if (CI->getValue().getZExtValue() == 0) {
+ R = ER->getSuperRegion();
+ continue;
+ }
+ }
+ }
+ break;
+ }
+ return R;
+}
diff --git a/clang/lib/Analysis/SVals.cpp b/clang/lib/Analysis/SVals.cpp
index a5ba1993983..6f480e8d46b 100644
--- a/clang/lib/Analysis/SVals.cpp
+++ b/clang/lib/Analysis/SVals.cpp
@@ -72,7 +72,7 @@ const FunctionDecl* SVal::getAsFunctionDecl() const {
// FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
SymbolRef SVal::getAsLocSymbol() const {
if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) {
- const MemRegion *R = X->getRegion();
+ const MemRegion *R = X->getBaseRegion();
while (R) {
// Blast through region views.
@@ -80,7 +80,6 @@ SymbolRef SVal::getAsLocSymbol() const {
R = View->getSuperRegion();
continue;
}
-
if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
return SymR->getSymbol();
@@ -121,6 +120,11 @@ const MemRegion *SVal::getAsRegion() const {
return 0;
}
+const MemRegion *loc::MemRegionVal::getBaseRegion() const {
+ const MemRegion *R = getRegion();
+ return R ? R->getBaseRegion() : NULL;
+}
+
bool SVal::symbol_iterator::operator==(const symbol_iterator &X) const {
return itr == X.itr;
}
OpenPOWER on IntegriCloud