Index: src/tests/.expect/designations.txt
===================================================================
--- src/tests/.expect/designations.txt	(revision bb1cd95b1669c150547e9c6ca1c0ac29ffadf57a)
+++ src/tests/.expect/designations.txt	(revision bb1cd95b1669c150547e9c6ca1c0ac29ffadf57a)
@@ -0,0 +1,53 @@
+=====A=====
+(A){ 2 3 (nil) }
+(A){ 2 3 (nil) }
+(A){ 0 3 (nil) }
+=====A=====
+
+=====B=====
+(B){
+  (A){ 5 0 (nil) }
+  (A){ 0 0 (nil) }
+}
+(B){
+  (A){ 5 2 (nil) }
+  (A){ 6 0 (nil) }
+}
+(B){
+  (A){ 1 0 (nil) }
+  (A){ 2 3 (nil) }
+}
+(B){
+  (A){ 1 2 (nil) }
+  (A){ 4 5 (nil) }
+}
+(B){
+  (A){ 1 0 (nil) }
+  (A){ 2 3 (nil) }
+}
+(B){
+  (A){ 1 0 (nil) }
+  (A){ 2 3 (nil) }
+}
+=====B=====
+
+=====C=====
+(C){
+  (int[]{ 2 3 4 }
+  (B){
+    (A){ 5 6 (nil) }
+    (A){ 7 8 (nil) }
+  }
+}
+=====C=====
+
+=====E=====
+(A){ 2 3 (nil) }
+(A){ 2 3 (nil) }
+(A){ 2 3 (nil) }
+(B){
+  (A){ 2 3 (nil) }
+  (A){ 5 6 (nil) }
+}
+=====E=====
+
Index: src/tests/designations.c
===================================================================
--- src/tests/designations.c	(revision bb1cd95b1669c150547e9c6ca1c0ac29ffadf57a)
+++ src/tests/designations.c	(revision bb1cd95b1669c150547e9c6ca1c0ac29ffadf57a)
@@ -0,0 +1,242 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// designations.c --
+//
+// Author           : Rob Schluntz
+// Created On       : Thu Jun 29 15:26:36 2017
+// Last Modified By : Rob Schluntz
+// Last Modified On : Thu Jun 29 15:27:05 2017
+// Update Count     : 2
+//
+
+// Note: this test case has been crafted so that it compiles with both cfa and with gcc without any modifications.
+// In particular, since the syntax for designations in Cforall differs from that of C, preprocessor substitution
+// is used for the designation syntax
+#ifdef __CFORALL__
+#define DES :
+#else
+int printf(const char *, ...);
+#define DES =
+#endif
+
+const int indentAmt = 2;
+void indent(int level) {
+  for (int i = 0; i < level; ++i) {
+    printf(" ");
+  }
+}
+
+// A contains fields with different types (int vs. int *)
+struct A {
+  int x, y;
+  int * ptr;
+};
+void printA(struct A a, int level) {
+  indent(level);
+  printf("(A){ %d %d %p }\n", a.x, a.y, a.ptr);
+}
+
+// B contains struct members
+struct B {
+  struct A a0, a1;
+};
+void printB(struct B b, int level) {
+  indent(level);
+  printf("(B){\n");
+  printA(b.a0, level+indentAmt);
+  printA(b.a1, level+indentAmt);
+  indent(level);
+  printf("}\n");
+}
+
+// C contains an array - tests that after 3 ints, the members of B are initialized.
+struct C {
+  int arr[3];
+  struct B b;
+};
+void printC(struct C c, int level) {
+  indent(level);
+  printf("(C){\n");
+  indent(level+indentAmt);
+  printf("(int[]{ %d %d %d }\n", c.arr[0], c.arr[1], c.arr[2]);
+  printB(c.b, level+indentAmt);
+  indent(level);
+  printf("}\n");
+}
+
+// D contains an unnamed aggregate - tests that this doesn't interfere with initialization.
+struct D {
+  struct {
+    int x;
+  };
+};
+void printD(struct D d, int level) {
+  indent(level);
+  printf("(D){ %d }\n", d.x);
+}
+
+// E tests unions
+union E {
+  struct A a;
+  struct B b;
+  struct C c;
+  struct D d;
+  int i;
+};
+
+int main() {
+  // simple designation case - starting from beginning of structure, leaves ptr default-initialized (zero)
+  struct A y0 = {
+  	.x DES 2,
+  	.y DES 3
+  };
+
+  // simple initializaiton case - initialize all elements explicitly with no designations
+  struct A y1 = {
+    2, 3, 0
+  };
+
+
+  // use designation to move to member y, leaving x default-initialized (zero)
+  struct A y2 = {
+    .y DES 3,
+    0
+  };
+
+#if ERROR
+  struct A yErr0 = {
+    {} // error - empty scalar initializer is illegal
+  };
+#endif
+
+  printf("=====A=====\n");
+  printA(y0, 0);
+  printA(y1, 0);
+  printA(y2, 0);
+  printf("=====A=====\n\n");
+
+  // initialize only first element (z0.a.x), leaving everything else default-initialized (zero), no nested curly-braces
+  struct B z0 = { 5 };
+
+  // some nested curly braces, use designation to 'jump around' within structure, leaving some members default-initialized
+  struct B z1 = {
+    { 3 }, // z1.a0
+    { 4 }, // z1.a1
+    .a0 DES { 5 }, // z1.a0
+    { 6 }, // z1.a1
+    .a0.y DES 2, // z1.a0.y
+    0, // z1.a0.ptr
+  };
+
+  // z2.a0.y and z2.a0.ptr default-initialized, everything else explicit
+  struct B z2 = {
+    { 1 },
+    { 2, 3, 0 }
+  };
+
+  // initialize every member, omitting nested curly braces
+  struct B z3 = {
+    1, 2, 0, 4, 5, 0
+  };
+
+  // no initializer - legal C, but garbage values - don't print this one
+  struct B z4;
+
+  // no curly braces - initialize with object of same type
+  struct B z5 = z2;
+
+  // z6.a0.y and z6.a0.ptr default-initialized, everything else explicit.
+  // no curly braces on z6.a1 initializers
+  struct B z6 = {
+    { 1 },
+    2, 3, 0
+  };
+
+  printf("=====B=====\n");
+  printB(z0, 0);
+  printB(z1, 0);
+  printB(z2, 0);
+  printB(z3, 0);
+  printB(z5, 0);
+  printB(z6, 0);
+  printf("=====B=====\n\n");
+
+  // TODO: what about extra things in a nested init? are empty structs skipped??
+
+  // test that initializing 'past array bound' correctly moves to next member.
+  struct C c1 = {
+    2, 3, 4,  // arr
+    5, 6, 0,  // b.a0
+    7, 8, 0,  // b.a1
+  };
+
+  printf("=====C=====\n");
+  printC(c1, 0);
+  printf("=====C=====\n\n");
+
+#if ERROR
+  // nested initializer can't refer to same type in C
+  struct C cErr0 = { c1 };
+
+  // must use curly braces to initialize members
+  struct C cErr1 = 2;
+
+  // can't initialize with array compound literal
+  struct C cErr2 = {
+    (int[3]) { 1, 2, 3 }  // error: array initialized from non-constant array expression
+  };
+#endif
+
+#if WARNING
+  // can't initialize array with array - converts to int*
+  int cWarn0_arr[3] = { 1, 2, 3 };
+  struct C cWarn0 = {
+    cWarn0_arr  // warning: initialization makes integer from ptr without cast
+  };
+#endif
+
+  // allowed to have 'too many' initialized lists - essentially they are ignored.
+  int i1 = { 3 };
+
+  // doesn't work yet.
+  // designate unnamed object's members
+  // struct D d = { .x DES 3 };
+#if ERROR
+  struct D d1 = { .y DES 3 };
+#endif
+
+  // simple union initialization - initialized first member (e0.a)
+  union E e0 = {
+    y0
+  };
+
+  // simple union initialization - initializes first member (e1.a) - with nested initializer list
+  union E e1 = {
+    { 2, 3, 0 }
+  };
+
+  // simple union initialization - initializes first member (e2.a) - without nested initializer list
+  union E e2 = {
+    2, 3, 0
+  };
+
+  // move cursor to e4.b.a0.x and initialize until e3.b.a1.ptr inclusive
+  union E e3 = {
+    .b.a0.x DES 2, 3, 0, 5, 6, 0
+  };
+
+  printf("=====E=====\n");
+  printA(e0.a, 0);
+  printA(e1.a, 0);
+  printA(e2.a, 0);
+  printB(e3.b, 0);
+  printf("=====E=====\n\n");
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// End: //
