Rework use of loc::SymbolVal in the retain/release checker to use the new method
SVal::getAsLocSymbol(). This simplifies the code and allows the retain/release
checker to (I believe) also correctly reason about location symbols wrapped in
SymbolicRegions.
Along the way I cleaned up SymbolRef a little, disallowing implicit casts to
'unsigned'.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65972 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/SVals.cpp b/lib/Analysis/SVals.cpp
index 2017c4b..c12c2d2 100644
--- a/lib/Analysis/SVals.cpp
+++ b/lib/Analysis/SVals.cpp
@@ -54,6 +54,42 @@
return symbol_iterator();
}
+/// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
+/// wraps a symbol, return that SymbolRef. Otherwise return a SymbolRef
+/// where 'isValid()' returns false.
+SymbolRef SVal::getAsLocSymbol() const {
+ if (const loc::SymbolVal *X = dyn_cast<loc::SymbolVal>(this))
+ return X->getSymbol();
+
+ if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) {
+ const MemRegion *R = X->getRegion();
+
+ while (R) {
+ // Blast through region views.
+ if (const TypedViewRegion *View = dyn_cast<TypedViewRegion>(R)) {
+ R = View->getSuperRegion();
+ continue;
+ }
+
+ if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
+ return SymR->getSymbol();
+
+ break;
+ }
+ }
+
+ return SymbolRef();
+}
+
+/// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
+/// Otherwise return a SymbolRef where 'isValid()' returns false.
+SymbolRef SVal::getAsSymbol() const {
+ if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this))
+ return X->getSymbol();
+
+ return getAsLocSymbol();
+}
+
//===----------------------------------------------------------------------===//
// Other Iterators.
//===----------------------------------------------------------------------===//