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