xref: /llvm-project/clang/test/Sema/flexible-array-in-union.c (revision 14ba782a87e16e9e15460a51f50e67e2744c26d9)
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