Fix analyzer regression reported in PR 4164:
- Update the old StoreManager::CastRegion to strip off 'ElementRegions' when
  casting to void* (Zhongxing: please validate)
- Pass-by-reference argument invalidation logic in CFRefCount.cpp:
  - Strip ElementRegions when the ElementRegion is just a 'raw data' view
    on top of the underlying typed region.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71094 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/Store.cpp b/lib/Analysis/Store.cpp
index 32b186b..49411b4 100644
--- a/lib/Analysis/Store.cpp
+++ b/lib/Analysis/Store.cpp
@@ -44,18 +44,37 @@
     QualType Pointee = PTy->getPointeeType();
     if (Pointee->isVoidType()) {
 
-      // Casts to void* only removes TypedViewRegion. If there is no
-      // TypedViewRegion, leave the region untouched. This happens when:
-      //
-      // void foo(void*);
-      // ...
-      // void bar() {
-      //   int x;
-      //   foo(&x);
-      // }
-
-      if (const TypedViewRegion *TR = dyn_cast<TypedViewRegion>(R))
-        R = TR->removeViews();
+      do {
+        if (const TypedViewRegion *TR = dyn_cast<TypedViewRegion>(R)) {
+          // Casts to void* removes TypedViewRegion. This happens when:
+          //
+          // void foo(void*);
+          // ...
+          // void bar() {
+          //   int x;
+          //   foo(&x);
+          // }
+          //
+          R = TR->removeViews();
+          continue;
+        }
+        else if (const ElementRegion *ER = dyn_cast<ElementRegion>(R)) {
+          // Casts to void* also removes ElementRegions. This happens when:
+          //
+          // void foo(void*);
+          // ...
+          // void bar() {
+          //   int x;
+          //   foo((char*)&x);
+          // }                
+          //
+          R = ER->getSuperRegion();
+          continue;
+        }
+        else
+          break;
+      }
+      while (0);
       
       return CastResult(state, R);
     }