| @@ -1,220 +1,245 @@ | | | @@ -1,220 +1,245 @@ |
1 | /* $NetBSD: d_c99_init.c,v 1.17 2021/03/28 14:01:50 rillig Exp $ */ | | 1 | /* $NetBSD: d_c99_init.c,v 1.18 2021/03/28 18:48:32 rillig Exp $ */ |
2 | # 3 "d_c99_init.c" | | 2 | # 3 "d_c99_init.c" |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Test C99 initializers. | | 5 | * Test C99 initializers. |
6 | * | | 6 | * |
7 | * See C99 6.7.8 "Initialization". | | 7 | * See C99 6.7.8 "Initialization". |
8 | */ | | 8 | */ |
9 | | | 9 | |
10 | | | 10 | |
11 | void use(const void *); | | 11 | void use(const void *); |
12 | | | 12 | |
13 | typedef struct any { | | 13 | typedef struct any { |
14 | const void *value; | | 14 | const void *value; |
15 | } any; | | 15 | } any; |
16 | | | 16 | |
17 | | | 17 | |
18 | // C99 6.7.8p11 says "optionally enclosed in braces". There is no limitation | | 18 | // C99 6.7.8p11 says "optionally enclosed in braces". There is no limitation |
19 | // on the number of brace pairs. | | 19 | // on the number of brace pairs. |
20 | int scalar_without_braces = 3; | | 20 | int scalar_without_braces = 3; |
21 | int scalar_with_optional_braces = { 3 }; | | 21 | int scalar_with_optional_braces = { 3 }; |
22 | int scalar_with_too_many_braces = {{ 3 }}; | | 22 | int scalar_with_too_many_braces = {{ 3 }}; |
23 | int scalar_with_too_many_initializers = { 3, 5 }; /* expect: 174 */ | | 23 | int scalar_with_too_many_initializers = { 3, 5 }; /* expect: 174 */ |
24 | | | 24 | |
25 | | | 25 | |
26 | // See init_using_expr, 'handing over to ASSIGN'. | | 26 | // See init_using_expr, 'handing over to ASSIGN'. |
27 | void | | 27 | void |
28 | struct_initialization_via_assignment(any arg) | | 28 | struct_initialization_via_assignment(any arg) |
29 | { | | 29 | { |
30 | any local = arg; | | 30 | any local = arg; |
31 | use(&local); | | 31 | use(&local); |
32 | } | | 32 | } |
33 | | | 33 | |
34 | | | 34 | |
35 | // See init_using_expr, initstack_string. | | 35 | // See init_using_expr, initstack_string. |
36 | char static_duration[] = "static duration"; | | 36 | char static_duration[] = "static duration"; |
| | | 37 | signed char static_duration_signed[] = "static duration"; |
| | | 38 | unsigned char static_duration_unsigned[] = "static duration"; |
| | | 39 | int static_duration_wchar[] = L"static duration"; |
37 | | | 40 | |
38 | // See init_using_expr. | | 41 | // See init_using_expr. |
39 | void | | 42 | void |
40 | initialization_by_braced_string(void) | | 43 | initialization_by_braced_string(void) |
41 | { | | 44 | { |
42 | any local = { "hello" }; | | 45 | any local = { "hello" }; |
43 | use(&local); | | 46 | use(&local); |
44 | } | | 47 | } |
45 | | | 48 | |
46 | void | | 49 | void |
47 | initialization_with_redundant_braces(any arg) | | 50 | initialization_by_redundantly_braced_string(void) |
| | | 51 | { |
| | | 52 | any local = {{{{ "hello" }}}}; |
| | | 53 | use(&local); |
| | | 54 | } |
| | | 55 | |
| | | 56 | /* |
| | | 57 | * Only scalar expressions and string literals may be enclosed by additional |
| | | 58 | * braces. Since 'arg' is a struct, this is a compile-time error. |
| | | 59 | */ |
| | | 60 | void |
| | | 61 | initialization_with_too_many_braces(any arg) |
48 | { | | 62 | { |
49 | any local = { arg }; /* expect: 185 */ | | 63 | any local = { arg }; /* expect: 185 */ |
50 | use(&arg); | | 64 | use(&arg); |
51 | } | | 65 | } |
52 | | | 66 | |
53 | // Some of the following examples are mentioned in init.c. | | 67 | // Some of the following examples are mentioned in the introduction comment |
| | | 68 | // in init.c. |
54 | | | 69 | |
55 | int number = 12345; | | 70 | int number = 12345; |
56 | | | 71 | |
57 | int number_with_braces_and_comma = { | | 72 | int number_with_braces_and_comma = { |
58 | 12345, | | 73 | 12345, |
59 | }; | | 74 | }; |
60 | | | 75 | |
61 | int array_with_fixed_size[3] = { | | 76 | int array_with_fixed_size[3] = { |
62 | 111, | | 77 | 111, |
63 | 222, | | 78 | 222, |
64 | 333, | | 79 | 333, |
65 | 444, /* expect: too many array initializers */ | | 80 | 444, /* expect: too many array initializers */ |
66 | }; | | 81 | }; |
67 | | | 82 | |
68 | // See initstack_push, 'extending array of unknown size'. | | 83 | // See initstack_push, 'extending array of unknown size'. |
69 | int array_of_unknown_size[] = { | | 84 | int array_of_unknown_size[] = { |
70 | 111, | | 85 | 111, |
71 | 222, | | 86 | 222, |
72 | 333, | | 87 | 333, |
73 | }; | | 88 | }; |
74 | | | 89 | |
75 | int array_flat[2][2] = { | | 90 | int array_flat[2][2] = { |
76 | 11, | | 91 | 11, |
77 | 12, | | 92 | 12, |
78 | 21, | | 93 | 21, |
79 | 22 | | 94 | 22 |
80 | }; | | 95 | }; |
81 | | | 96 | |
82 | int array_nested[2][2] = { | | 97 | int array_nested[2][2] = { |
83 | { | | 98 | { |
84 | 11, | | 99 | 11, |
85 | 12 | | 100 | 12 |
86 | }, | | 101 | }, |
87 | { | | 102 | { |
88 | 21, | | 103 | 21, |
89 | 22 | | 104 | 22 |
90 | } | | 105 | } |
91 | }; | | 106 | }; |
92 | | | 107 | |
93 | int array_with_designators[] = { | | 108 | int array_with_designators[] = { |
94 | ['1'] = 111, | | 109 | ['1'] = 111, |
95 | ['5'] = 555, | | 110 | ['5'] = 555, |
96 | ['9'] = 999 | | 111 | ['9'] = 999 |
97 | }; | | 112 | }; |
98 | | | 113 | |
99 | int array_with_some_designators[] = { | | 114 | int array_with_some_designators[] = { |
100 | ['1'] = 111, | | 115 | ['1'] = 111, |
101 | 222, | | 116 | 222, |
102 | ['9'] = 999 | | 117 | ['9'] = 999 |
103 | }; | | 118 | }; |
104 | | | 119 | |
105 | struct point { | | 120 | struct point { |
106 | int x; | | 121 | int x; |
107 | int y; | | 122 | int y; |
108 | }; | | 123 | }; |
109 | | | 124 | |
110 | struct point point = { | | 125 | struct point point = { |
111 | 3, | | 126 | 3, |
112 | 4 | | 127 | 4 |
113 | }; | | 128 | }; |
114 | | | 129 | |
115 | struct point point_with_designators = { | | 130 | struct point point_with_designators = { |
116 | .y = 4, | | 131 | .y = 4, |
117 | .x = 3, | | 132 | .x = 3, |
118 | }; | | 133 | }; |
119 | | | 134 | |
120 | struct point point_with_mixed_designators = { | | 135 | struct point point_with_mixed_designators = { |
121 | .x = 3, | | 136 | .x = 3, |
122 | 4, | | 137 | 4, |
123 | // FIXME: assertion failure '== ARRAY' | | 138 | // FIXME: assertion failure '== ARRAY' |
124 | // 5, | | 139 | // 5, |
125 | .x = 3, | | 140 | .x = 3, |
126 | }; | | 141 | }; |
127 | | | 142 | |
128 | int array_with_designator[] = { | | 143 | int array_with_designator[] = { |
129 | 111, | | 144 | 111, |
130 | .member = 222, /* expect: 249 */ | | 145 | .member = 222, /* expect: 249 */ |
131 | 333, | | 146 | 333, |
132 | }; | | 147 | }; |
133 | | | 148 | |
134 | /* | | 149 | /* |
135 | * C99 6.7.8p11 says that the initializer of a scalar can be "optionally | | 150 | * C99 6.7.8p11 says that the initializer of a scalar can be "optionally |
136 | * enclosed in braces". It does not explicitly set an upper limit on the | | 151 | * enclosed in braces". It does not explicitly set an upper limit on the |
137 | * number of braces. It also doesn't restrict the term "initializer" to only | | 152 | * number of braces. It also doesn't restrict the term "initializer" to only |
138 | * mean the "outermost initializer". Both GCC 10 and Clang 8 already warn | | 153 | * mean the "outermost initializer". Both GCC 10 and Clang 8 already warn |
139 | * about this, so there is no extra work for lint to do. | | 154 | * about this, so there is no extra work for lint to do. |
140 | */ | | 155 | */ |
141 | struct point scalar_with_several_braces = { | | 156 | struct point scalar_with_several_braces = { |
142 | {{{3}}}, | | 157 | {{{3}}}, |
143 | {{{{4}}}}, | | 158 | {{{{4}}}}, |
144 | }; | | 159 | }; |
145 | | | 160 | |
146 | struct rectangle { | | 161 | struct rectangle { |
147 | struct point top_left; | | 162 | struct point top_left; |
148 | struct point bottom_right; | | 163 | struct point bottom_right; |
149 | }; | | 164 | }; |
150 | | | 165 | |
151 | /* C99 6.7.8p18 */ | | 166 | /* C99 6.7.8p18 */ |
152 | struct rectangle screen = { | | 167 | struct rectangle screen = { |
153 | .bottom_right = { | | 168 | .bottom_right = { |
154 | 1920, | | 169 | 1920, |
155 | 1080, | | 170 | 1080, |
156 | } | | 171 | } |
157 | }; | | 172 | }; |
158 | | | 173 | |
159 | /* | | 174 | /* |
160 | * C99 6.7.8p22 says: At the _end_ of its initializer list, the array no | | 175 | * C99 6.7.8p22 says: At the _end_ of its initializer list, the array no |
161 | * longer has incomplete type. | | 176 | * longer has incomplete type. |
162 | */ | | 177 | */ |
163 | struct point points[] = { | | 178 | struct point points[] = { |
164 | { | | 179 | { |
165 | /* | | 180 | /* |
166 | * At this point, the size of the object 'points' is not known | | 181 | * At this point, the size of the object 'points' is not known |
167 | * yet since its type is still incomplete. Lint could warn | | 182 | * yet since its type is still incomplete. Lint could warn |
168 | * about this, but GCC and Clang already do. | | 183 | * about this, but GCC and Clang already do. |
169 | * | | 184 | * |
170 | * This test case demonstrates that in | | 185 | * This test case demonstrates that in |
171 | * extend_if_array_of_unknown_size, setcomplete is called too | | 186 | * extend_if_array_of_unknown_size, setcomplete is called too |
172 | * early. | | 187 | * early. |
173 | */ | | 188 | */ |
174 | sizeof points, | | 189 | sizeof points, |
175 | 4 | | 190 | 4 |
176 | } | | 191 | } |
177 | }; | | 192 | }; |
178 | | | 193 | |
179 | | | 194 | |
180 | struct triangle { | | 195 | struct triangle { |
181 | struct point points[3]; | | 196 | struct point points[3]; |
182 | }; | | 197 | }; |
183 | | | 198 | |
184 | struct pentagon { | | 199 | struct pentagon { |
185 | struct point points[5]; | | 200 | struct point points[5]; |
186 | }; | | 201 | }; |
187 | | | 202 | |
188 | struct geometry { | | 203 | struct geometry { |
189 | struct pentagon pentagons[6]; | | 204 | struct pentagon pentagons[6]; |
190 | struct triangle triangles[10]; | | 205 | struct triangle triangles[10]; |
191 | struct point points[3][5][2]; | | 206 | struct point points[3][5][2]; |
192 | }; | | 207 | }; |
193 | | | 208 | |
194 | /* | | 209 | /* |
195 | * Initialization of a complex struct containing nested arrays and nested | | 210 | * Initialization of a complex struct containing nested arrays and nested |
196 | * structs. | | 211 | * structs. |
197 | */ | | 212 | */ |
198 | struct geometry geometry = { | | 213 | struct geometry geometry = { |
199 | // FIXME: assertion "istk->i_type != NULL" failed in initstack_push | | 214 | // FIXME: assertion "istk->i_type != NULL" failed in initstack_push |
200 | //.pentagons[0].points[4].x = 1, | | 215 | //.pentagons[0].points[4].x = 1, |
201 | .points[0][0][0] = { 0, 0 }, | | 216 | .points[0][0][0] = { 0, 0 }, |
202 | .points[2][4][1] = {301, 302 }, | | 217 | .points[2][4][1] = {301, 302 }, |
203 | /* TODO: expect+1: array index 3 must be between 0 and 2 */ | | 218 | /* TODO: expect+1: array index 3 must be between 0 and 2 */ |
204 | .points[3][0][0] = {3001, 3002 }, | | 219 | .points[3][0][0] = {3001, 3002 }, |
205 | /* TODO: expect+1: array index 5 must be between 0 and 4 */ | | 220 | /* TODO: expect+1: array index 5 must be between 0 and 4 */ |
206 | .points[0][5][0] = {501, 502 }, | | 221 | .points[0][5][0] = {501, 502 }, |
207 | /* TODO: expect+1: array index 2 must be between 0 and 1 */ | | 222 | /* TODO: expect+1: array index 2 must be between 0 and 1 */ |
208 | .points[0][0][2] = {21, 22 }, | | 223 | .points[0][0][2] = {21, 22 }, |
209 | }; | | 224 | }; |
210 | | | 225 | |
211 | struct ends_with_unnamed_bit_field { | | 226 | struct ends_with_unnamed_bit_field { |
212 | int member; | | 227 | int member; |
213 | int : 0; | | 228 | int : 0; |
214 | } ends_with_unnamed_bit_field = { | | 229 | } ends_with_unnamed_bit_field = { |
215 | 12345, | | 230 | 12345, |
216 | /* expect+1: too many struct/union initializers */ | | 231 | /* expect+1: too many struct/union initializers */ |
217 | 23456, | | 232 | 23456, |
218 | }; | | 233 | }; |
219 | | | 234 | |
220 | // See d_struct_init_nested.c for a more complicated example. | | 235 | char prefixed_message[] = { |
| | | 236 | 'E', ':', ' ', |
| | | 237 | /* expect+1: illegal combination of integer (char) and pointer */ |
| | | 238 | "message\n", |
| | | 239 | }; |
| | | 240 | |
| | | 241 | char message_with_suffix[] = { |
| | | 242 | "message", |
| | | 243 | /* expect+1: too many array initializers */ |
| | | 244 | '\n', |
| | | 245 | }; |