Reimplement the handling of the "current object" in designator
initializers, so that we are within the appropriate subobject after
we've processed a multi-designator designation. We're matching GCC and
EDG's behavior on all examples I've found thus far.

*Huge* thanks to Eli Friedman for pointing out my fundamental
misunderstanding of "current object" in the C99 spec.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@62812 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Sema/designated-initializers.c b/test/Sema/designated-initializers.c
index 5efb444..cc2c346 100644
--- a/test/Sema/designated-initializers.c
+++ b/test/Sema/designated-initializers.c
@@ -1,5 +1,9 @@
 // RUN: clang -fsyntax-only -verify %s
 
+int complete_array_from_init[] = { 1, 2, [10] = 5, 1, 2, [5] = 2, 6 };
+
+int complete_array_from_init_check[((sizeof(complete_array_from_init) / sizeof(int)) == 13)? 1 : -1];
+
 int iarray[10] = {
   [0] = 1,
   [1 ... 5] = 2,
@@ -11,6 +15,9 @@
 
 int iarray2[10] = {
   [10] = 1, // expected-error{{array designator index (10) exceeds array bounds (10)}}
+};
+
+int iarray3[10] = {
   [5 ... 12] = 2 // expected-error{{array designator index (12) exceeds array bounds (10)}}
 };
 
@@ -23,7 +30,9 @@
   .y = 1.0, 
   x: 2.0,
   .a = 4.0, // expected-error{{field designator 'a' does not refer to any field in type 'struct point'}}
+};
 
+struct point p2 = {
   [1] = 1.0 // expected-error{{array designator cannot initialize non-array type}}
 };
 
@@ -31,9 +40,15 @@
   [0].x = 1.0,
   [1].y = 2.0,
   [2].z = 3.0, // expected-error{{field designator 'z' does not refer to any field in type 'struct point'}}
+};
+
+struct point array2[10] = {
   [10].x = 2.0, // expected-error{{array designator index (10) exceeds array bounds (10)}}
   [4 ... 5].y = 2.0,
-  [4 ... 6] = { .x = 3, .y = 4.0 },
+  [4 ... 6] = { .x = 3, .y = 4.0 }
+};
+
+struct point array3[10] = {
   .x = 5 // expected-error{{field designator cannot initialize a non-struct, non-union type}}
 };
 
@@ -76,3 +91,24 @@
   .wonky = { 0 }
 };
 
+int anint;
+struct {int x,*y;} z[] = {[0].x = 2, &z[0].x};
+
+struct outer { struct inner { int x, *y; } in, *inp; } zz[] = {
+  [0].in.x = 2, &zz[0].in.x, &zz[0].in,
+  0, &anint, &zz[1].in,
+  [3].in = { .y = &anint, .x = 17 },
+  [7].in.y = &anint, &zz[0].in,
+  [4].in.y = &anint, [5].in.x = 12
+};
+
+int zz_sizecheck[sizeof(zz) / sizeof(struct outer) == 8? 1 : -1 ];
+
+struct disklabel_ops {
+  struct {} type;
+  int labelsize;
+};
+
+struct disklabel_ops disklabel64_ops = {
+  .labelsize = sizeof(struct disklabel_ops)
+};