[analyzer] Handle C++ member initializers and destructors.

This uses CFG to tell if a constructor call is for a member, and uses
the member's region appropriately.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160808 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/initializer.cpp b/test/Analysis/initializer.cpp
index 6640e1f..0580503 100644
--- a/test/Analysis/initializer.cpp
+++ b/test/Analysis/initializer.cpp
@@ -1,4 +1,7 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -cfg-add-initializers -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-store region -cfg-add-initializers -cfg-add-implicit-dtors -verify %s
+
+// We don't inline constructors unless we have both initializers and
+// implicit destructors turned on.
 
 void clang_analyzer_eval(bool);
 
@@ -11,3 +14,33 @@
 A::A() : x(0) {
   clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}
 }
+
+
+class DirectMember {
+  int x;
+public:
+  DirectMember(int value) : x(value) {}
+
+  int getX() { return x; }
+};
+
+void testDirectMember() {
+  DirectMember obj(3);
+  clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}
+}
+
+
+class IndirectMember {
+  struct {
+    int x;
+  };
+public:
+  IndirectMember(int value) : x(value) {}
+
+  int getX() { return x; }
+};
+
+void testIndirectMember() {
+  IndirectMember obj(3);
+  clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}
+}