[analyzer] Teach invalidateRegions that regions within LazyCompoundVal need to be invalidated

Refactor invalidateRegions to take SVals instead of Regions as input and teach RegionStore
about processing LazyCompoundVal as a top-level “escaping” value.

This addresses several false positives that get triggered by the NewDelete checker, but the
underlying issue is reproducible with other checkers as well (for example, MallocChecker).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178518 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/malloc.cpp b/test/Analysis/malloc.cpp
index a7c3652..54efa1c 100644
--- a/test/Analysis/malloc.cpp
+++ b/test/Analysis/malloc.cpp
@@ -5,7 +5,7 @@
 void free(void *);
 void *realloc(void *ptr, size_t size);
 void *calloc(size_t nmemb, size_t size);
-
+char *strdup(const char *s);
 
 void checkThatMallocCheckerIsRunning() {
   malloc(4);
@@ -67,3 +67,36 @@
   result.a = malloc(4);
   return result; // no-warning
 }
+
+// Ensure that regions accessible through a LazyCompoundVal trigger region escape.
+// Malloc checker used to report leaks for the following two test cases.
+struct Property {
+  char* getterName;
+  Property(char* n)
+  : getterName(n) {}
+
+};
+void append(Property x);
+
+void appendWrapper(char *getterName) {
+  append(Property(getterName));
+}
+void foo(const char* name) {
+  char* getterName = strdup(name);
+  appendWrapper(getterName); // no-warning
+}
+
+struct NestedProperty {
+  Property prop;
+  NestedProperty(Property p)
+  : prop(p) {}
+};
+void appendNested(NestedProperty x);
+
+void appendWrapperNested(char *getterName) {
+  appendNested(NestedProperty(Property(getterName)));
+}
+void fooNested(const char* name) {
+  char* getterName = strdup(name);
+  appendWrapperNested(getterName); // no-warning
+}
\ No newline at end of file