Rewrite default initialization of anonymous structs/unions within a
constructor. Previously, we did some bogus recursion into the fields
of anonymous structs (recursively), which ended up building invalid
ASTs that would cause CodeGen to crash due to invalid GEPs.

Now, we instead build the default initializations based on the
indirect field declarations at the top level, which properly generates
the sequence of GEPs needed to initialize the proper member. Fixes
PR10512 and <rdar://problem/9924046>.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137212 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
index 324ff4a..a12ae53 100644
--- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp
+++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp
@@ -67,6 +67,55 @@
   // CHECK: }
 }
 
+namespace PR10512 {
+  struct A {
+    A();
+    A(int);
+    A(long);
+
+    struct {
+      struct {int x;};
+      struct {int y;};
+    };
+  };
+
+  // CHECK: define void @_ZN7PR105121AC2Ev
+  // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
+  // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]]
+  // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]]
+  // CHECK-NEXT: ret void
+  A::A() {}
+
+  // CHECK: define void @_ZN7PR105121AC2Ei
+  // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
+  // CHECK-NEXT: [[XADDR:%[a-zA-z0-9.]+]] = alloca i32
+  // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]]
+  // CHECK-NEXT: store i32 [[X:%[a-zA-z0-9.]+]], i32* [[XADDR]]
+  // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]]
+  // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
+  // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
+  // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
+  // CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i32* [[XADDR]]
+  // CHECK-NEXT: store i32 [[TMP]]
+  // CHECK-NEXT: ret void
+  A::A(int x) : x(x) { }
+
+  // CHECK: define void @_ZN7PR105121AC2El
+  // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]]
+  // CHECK-NEXT: [[XADDR:%[a-zA-z0-9.]+]] = alloca i64
+  // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]]
+  // CHECK-NEXT: store i64 [[X:%[a-zA-z0-9.]+]], i64* [[XADDR]]
+  // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]]
+  // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
+  // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 1}}
+  // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}}
+  // CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i64* [[XADDR]]
+  // CHECK-NEXT: [[CONV:%[a-zA-z0-9.]+]] = trunc i64 [[TMP]] to i32
+  // CHECK-NEXT: store i32 [[CONV]]
+  // CHECK-NEXT: ret void
+  A::A(long y) : y(y) { }
+}
+
 namespace test3 {
   struct A {
     union {