1 // RUN: %clang_cc1 %s -verify=stock,c -fsyntax-only 2 // RUN: %clang_cc1 %s -verify=stock,cpp -fsyntax-only -x c++ 3 // RUN: %clang_cc1 %s -verify=stock,cpp -fsyntax-only -fms-compatibility -x c++ 4 // RUN: %clang_cc1 %s -verify=stock,c,gnu -fsyntax-only -Wgnu-flexible-array-union-member -Wgnu-empty-struct 5 // RUN: %clang_cc1 %s -verify=stock,c,microsoft -fsyntax-only -fms-compatibility -Wmicrosoft 6 7 // The test checks that an attempt to initialize union with flexible array 8 // member with an initializer list doesn't crash clang. 9 10 11 union { char x[]; } r = {0}; /* gnu-warning {{flexible array member 'x' in a union is a GNU extension}} 12 microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} 13 */ 14 struct _name1 { 15 int a; 16 union { 17 int b; 18 char x[]; /* gnu-warning {{flexible array member 'x' in a union is a GNU extension}} 19 microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} 20 */ 21 }; 22 } name1 = { 23 10, 24 42, /* initializes "b" */ 25 }; 26 27 struct _name1i { 28 int a; 29 union { 30 int b; 31 char x[]; /* gnu-warning {{flexible array member 'x' in a union is a GNU extension}} 32 microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} 33 */ 34 }; 35 } name1i = { 36 .a = 10, 37 .b = 42, 38 }; 39 40 /* Initialization of flexible array in a union is never allowed. */ 41 struct _name2 { 42 int a; 43 union { 44 int b; 45 char x[]; /* gnu-warning {{flexible array member 'x' in a union is a GNU extension}} 46 microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} 47 */ 48 }; 49 } name2 = { 50 12, 51 13, 52 { 'c' }, /* c-warning {{excess elements in struct initializer}} 53 cpp-error {{excess elements in struct initializer}} 54 */ 55 }; 56 57 /* Initialization of flexible array in a union is never allowed. */ 58 struct _name2i { 59 int a; 60 union { 61 int b; 62 char x[]; /* gnu-warning {{flexible array member 'x' in a union is a GNU extension}} 63 microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} 64 stock-note {{initialized flexible array member 'x' is here}} 65 */ 66 }; 67 } name2i = { 68 .a = 12, 69 .b = 13, /* stock-note {{previous initialization is here}} */ 70 .x = { 'c' }, /* stock-error {{initialization of flexible array member is not allowed}} 71 c-warning {{initializer overrides prior initialization of this subobject}} 72 cpp-error {{initializer partially overrides prior initialization of this subobject}} 73 */ 74 }; 75 76 /* Flexible array initialization always allowed when not in a union, 77 and when struct has another member. 78 */ 79 struct _okay { 80 int a; 81 char x[]; 82 } okay = { 83 22, 84 { 'x', 'y', 'z' }, 85 }; 86 87 struct _okayi { 88 int a; 89 char x[]; 90 } okayi = { 91 .a = 22, 92 .x = { 'x', 'y', 'z' }, 93 }; 94 95 struct _okay0 { 96 int a; 97 char x[]; 98 } okay0 = { }; 99 100 struct _flex_extension { 101 char x[]; /* gnu-warning {{flexible array member 'x' in otherwise empty struct is a GNU extension}} 102 microsoft-warning {{flexible array member 'x' in otherwise empty struct is a Microsoft extension}} 103 */ 104 } flex_extension = { 105 { 'x', 'y', 'z' }, 106 }; 107 108 struct _flex_extensioni { 109 char x[]; /* gnu-warning {{flexible array member 'x' in otherwise empty struct is a GNU extension}} 110 microsoft-warning {{flexible array member 'x' in otherwise empty struct is a Microsoft extension}} 111 */ 112 } flex_extensioni = { 113 .x = { 'x', 'y', 'z' }, 114 }; 115 116 struct already_hidden { 117 int a; 118 union { 119 int b; 120 struct { 121 struct { } __empty; // gnu-warning {{empty struct is a GNU extension}} 122 char x[]; 123 }; 124 }; 125 }; 126 127 struct still_zero_sized { 128 struct { } __unused; // gnu-warning {{empty struct is a GNU extension}} 129 int x[]; 130 }; 131 132 struct warn1 { 133 int a; 134 union { 135 int b; 136 char x[]; /* gnu-warning {{flexible array member 'x' in a union is a GNU extension}} 137 microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} 138 */ 139 }; 140 }; 141 142 struct warn2 { 143 int x[]; /* gnu-warning {{flexible array member 'x' in otherwise empty struct is a GNU extension}} 144 microsoft-warning {{flexible array member 'x' in otherwise empty struct is a Microsoft extension}} 145 */ 146 }; 147 148 union warn3 { 149 short x[]; /* gnu-warning {{flexible array member 'x' in a union is a GNU extension}} 150 microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} 151 */ 152 }; 153 154 struct quiet1 { 155 int a; 156 short x[]; 157 }; 158 159 struct _not_at_end { 160 union { short x[]; }; /* stock-warning-re {{field '' with variable sized type '{{.*}}' not at the end of a struct or class is a GNU extension}} 161 gnu-warning {{flexible array member 'x' in a union is a GNU extension}} 162 microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} 163 */ 164 int y; 165 } not_at_end = {{}, 3}; 166 167 struct _not_at_end_s { 168 struct { int a; short x[]; }; /* stock-warning-re {{field '' with variable sized type '{{.*}}' not at the end of a struct or class is a GNU extension}} */ 169 int y; 170 } not_at_end_s = {{}, 3}; 171 172 struct { 173 int a; 174 union { /* stock-warning-re {{field '' with variable sized type '{{.*}}' not at the end of a struct or class is a GNU extension}} */ 175 short x[]; /* stock-note {{initialized flexible array member 'x' is here}} 176 gnu-warning {{flexible array member 'x' in a union is a GNU extension}} 177 microsoft-warning {{flexible array member 'x' in a union is a Microsoft extension}} 178 */ 179 int b; 180 }; 181 int c; 182 int d; 183 } i_f = { 4, 184 {5}, /* stock-error {{initialization of flexible array member is not allowed}} */ 185 {}, 186 6}; 187 188 // expected-no-diagnostics 189