Tue Mar 30 14:25:28 2021 UTC ()
lint: rewrite handling of initializations, fixing several bugs

The previous implementation had a wrong model of how initialization
happens in C99, its assertions failed in all kind of edge cases and it
was not possible to fix the remaining bugs one at a time without running
into even more obscure assertion failures.

The debug logging was detailed but did not help to clarify the
situation.  After about 20 failed attempts at fixing the small details I
decided to start all over and rewrite the initialization code from
scratch.  I left the low-level parts of handling designators, the code
that is independent of brace_level and the high-level parts of how the
parser calls into this module.  Everything else is completely new.

The concept of a brace level stays since that is how C99 describes
initialization.  The previous code could not handle multi-level
designations (see d_init_pop_member.c).  There are no more assertion
failures in the initialization code.

Some TODO comments have been left in the tests to keep the line numbers
the same in this commit.  These will be cleaned up in a follow-up
commit.

The new implementation does not handle initialization with "missing"
braces.  This is an edge case that both GCC and Clang warn about, so it
is not widely used.  If necessary, it may be added later.

The new implementation does not use any global variables in the vast
majority of the functions, to make all dependencies and possible
modifications obvious.


(rillig)
diff -r1.6 -r1.7 src/tests/usr.bin/xlint/lint1/d_c99_bool.c
diff -r1.6 -r1.7 src/tests/usr.bin/xlint/lint1/d_init_pop_member.c
diff -r1.23 -r1.24 src/tests/usr.bin/xlint/lint1/d_c99_init.c
diff -r1.16 -r1.17 src/tests/usr.bin/xlint/lint1/d_c99_init.exp
diff -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/d_init_array_using_string.c
diff -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/d_init_array_using_string.exp
diff -r1.5 -r1.6 src/tests/usr.bin/xlint/lint1/d_init_pop_member.exp
diff -r1.206 -r1.207 src/usr.bin/xlint/lint1/cgram.y
diff -r1.166 -r1.167 src/usr.bin/xlint/lint1/decl.c
diff -r1.94 -r1.95 src/usr.bin/xlint/lint1/externs1.h
diff -r1.178 -r1.179 src/usr.bin/xlint/lint1/init.c

cvs diff -r1.6 -r1.7 src/tests/usr.bin/xlint/lint1/d_c99_bool.c (expand / switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/d_c99_bool.c 2021/02/21 09:07:58 1.6
+++ src/tests/usr.bin/xlint/lint1/d_c99_bool.c 2021/03/30 14:25:28 1.7
@@ -1,25 +1,25 @@ @@ -1,25 +1,25 @@
1/* $NetBSD: d_c99_bool.c,v 1.6 2021/02/21 09:07:58 rillig Exp $ */ 1/* $NetBSD: d_c99_bool.c,v 1.7 2021/03/30 14:25:28 rillig Exp $ */
2# 3 "d_c99_bool.c" 2# 3 "d_c99_bool.c"
3 3
4/* 4/*
5 * C99 6.3.1.2 says: "When any scalar value is converted to _Bool, the result 5 * C99 6.3.1.2 says: "When any scalar value is converted to _Bool, the result
6 * is 0 if the value compares equal to 0; otherwise the result is 1." 6 * is 0 if the value compares equal to 0; otherwise the result is 1."
7 * 7 *
8 * This is different from the other integer types, which get truncated or 8 * This is different from the other integer types, which get truncated or
9 * invoke undefined behavior. 9 * invoke undefined behavior.
10 */ 10 */
11 11
12/* Below, each wrong assertion produces "negative array dimension" [20]. */ 12/* Below, each false statement produces "negative array dimension" [20]. */
13 13
14int int_0_converts_to_false[(_Bool)0 ? -1 : 1]; 14int int_0_converts_to_false[(_Bool)0 ? -1 : 1];
15int int_0_converts_to_true_[(_Bool)0 ? 1 : -1]; /* expect: 20 */ 15int int_0_converts_to_true_[(_Bool)0 ? 1 : -1]; /* expect: 20 */
16 16
17int int_1_converts_to_false[(_Bool)1 ? -1 : 1]; /* expect: 20 */ 17int int_1_converts_to_false[(_Bool)1 ? -1 : 1]; /* expect: 20 */
18int int_1_converts_to_true_[(_Bool)1 ? 1 : -1]; 18int int_1_converts_to_true_[(_Bool)1 ? 1 : -1];
19 19
20int int_2_converts_to_false[(_Bool)2 ? -1 : 1]; /* expect: 20 */ 20int int_2_converts_to_false[(_Bool)2 ? -1 : 1]; /* expect: 20 */
21int int_2_converts_to_true_[(_Bool)2 ? 1 : -1]; 21int int_2_converts_to_true_[(_Bool)2 ? 1 : -1];
22 22
23int int_256_converts_to_false[(_Bool)256 ? -1 : 1]; /* expect: 20 */ 23int int_256_converts_to_false[(_Bool)256 ? -1 : 1]; /* expect: 20 */
24int int_256_converts_to_true_[(_Bool)256 ? 1 : -1]; 24int int_256_converts_to_true_[(_Bool)256 ? 1 : -1];
25 25

cvs diff -r1.6 -r1.7 src/tests/usr.bin/xlint/lint1/d_init_pop_member.c (expand / switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/d_init_pop_member.c 2021/03/19 17:40:37 1.6
+++ src/tests/usr.bin/xlint/lint1/d_init_pop_member.c 2021/03/30 14:25:28 1.7
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: d_init_pop_member.c,v 1.6 2021/03/19 17:40:37 rillig Exp $ */ 1/* $NetBSD: d_init_pop_member.c,v 1.7 2021/03/30 14:25:28 rillig Exp $ */
2# 3 "d_init_pop_member.c" 2# 3 "d_init_pop_member.c"
3 3
4/* 4/*
5 * Since init.c 1.27 from 2015-07-28, 5 * Since init.c 1.27 from 2015-07-28,
6 * a bug in memberpop or pop_member led to a wrong error message 6 * a bug in memberpop or pop_member led to a wrong error message
7 * "undefined struct/union member: capital [101]" in the second and third 7 * "undefined struct/union member: capital [101]" in the second and third
8 * named initializer. 8 * named initializer.
9 */ 9 */
10 10
11struct rgb { 11struct rgb {
12 unsigned red; 12 unsigned red;
13 unsigned green; 13 unsigned green;
14 unsigned blue; 14 unsigned blue;
@@ -25,35 +25,35 @@ struct person { @@ -25,35 +25,35 @@ struct person {
25 struct rgb favorite_color; 25 struct rgb favorite_color;
26}; 26};
27 27
28struct city { 28struct city {
29 struct person mayor; 29 struct person mayor;
30}; 30};
31 31
32struct state { 32struct state {
33 struct city capital; 33 struct city capital;
34}; 34};
35 35
36void func(void) 36void func(void)
37{ 37{
38 struct state st = { 38 struct state st = { /* expect: set but not used */
39 .capital.mayor.hobbies.dancing = 1, 39 .capital.mayor.hobbies.dancing = 1,
40 /* 40 /*
41 * Since 2015-07-28: 41 * Since 2015-07-28:
42 * wrong "undefined struct/union member: capital [101]" 42 * wrong "undefined struct/union member: capital [101]"
43 */ 43 */
44 /* 44 /*
45 * Before init.c 1.52 from 2020-01-01: 45 * Before init.c 1.52 from 2020-01-01:
46 * wrong "warning: bit-field initializer does not fit [180]" 46 * wrong "warning: bit-field initializer does not fit [180]"
47 */ 47 */
48 .capital.mayor.favorite_color.green = 0xFF, /*FIXME*//* expect: 101 */ 48 .capital.mayor.favorite_color.green = 0xFF,
49 /* 49 /*
50 * Since 2015-07-28: 50 * Since 2015-07-28:
51 * wrong "undefined struct/union member: capital [101]" 51 * wrong "undefined struct/union member: capital [101]"
52 */ 52 */
53 /* 53 /*
54 * Before init.c 1.52 from 2020-01-01: 54 * Before init.c 1.52 from 2020-01-01:
55 * wrong "warning: bit-field initializer does not fit [180]" 55 * wrong "warning: bit-field initializer does not fit [180]"
56 */ 56 */
57 .capital.mayor.favorite_color.red = 0xFF, /*FIXME*//* expect: 101 */ 57 .capital.mayor.favorite_color.red = 0xFF,
58 }; 58 };
59} 59}

cvs diff -r1.23 -r1.24 src/tests/usr.bin/xlint/lint1/d_c99_init.c (expand / switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/d_c99_init.c 2021/03/29 22:42:10 1.23
+++ src/tests/usr.bin/xlint/lint1/d_c99_init.c 2021/03/30 14:25:28 1.24
@@ -1,54 +1,54 @@ @@ -1,54 +1,54 @@
1/* $NetBSD: d_c99_init.c,v 1.23 2021/03/29 22:42:10 rillig Exp $ */ 1/* $NetBSD: d_c99_init.c,v 1.24 2021/03/30 14:25:28 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
11void use(const void *); 11void use(const void *);
12 12
13typedef struct any { 13typedef 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.
20int scalar_without_braces = 3; 20int scalar_without_braces = 3;
21int scalar_with_optional_braces = { 3 }; 21int scalar_with_optional_braces = { 3 };
22int scalar_with_too_many_braces = {{ 3 }}; 22int scalar_with_too_many_braces = {{ 3 }};
23int scalar_with_too_many_initializers = { 3, 5 }; /* expect: 174 */ 23int 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_expr, 'handing over to ASSIGN'.
27void 27void
28struct_initialization_via_assignment(any arg) 28struct_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_expr, initialization_init_array_using_string.
36char static_duration[] = "static duration"; 36char static_duration[] = "static duration";
37signed char static_duration_signed[] = "static duration"; 37signed char static_duration_signed[] = "static duration";
38unsigned char static_duration_unsigned[] = "static duration"; 38unsigned char static_duration_unsigned[] = "static duration";
39int static_duration_wchar[] = L"static duration"; 39int static_duration_wchar[] = L"static duration";
40 40
41// See init_using_expr. 41// See init_expr.
42void 42void
43initialization_by_braced_string(void) 43initialization_by_braced_string(void)
44{ 44{
45 any local = { "hello" }; 45 any local = { "hello" };
46 use(&local); 46 use(&local);
47} 47}
48 48
49void 49void
50initialization_by_redundantly_braced_string(void) 50initialization_by_redundantly_braced_string(void)
51{ 51{
52 any local = {{{{ "hello" }}}}; 52 any local = {{{{ "hello" }}}};
53 use(&local); 53 use(&local);
54} 54}
@@ -70,27 +70,27 @@ initialization_with_too_many_braces(any  @@ -70,27 +70,27 @@ initialization_with_too_many_braces(any
70int number = 12345; 70int number = 12345;
71 71
72int number_with_braces_and_comma = { 72int number_with_braces_and_comma = {
73 12345, 73 12345,
74}; 74};
75 75
76int array_with_fixed_size[3] = { 76int array_with_fixed_size[3] = {
77 111, 77 111,
78 222, 78 222,
79 333, 79 333,
80 444, /* expect: too many array initializers */ 80 444, /* expect: too many array initializers */
81}; 81};
82 82
83// See initstack_push, 'extending array of unknown size'. 83// See initialization_set_set_of_unknown_array.
84int array_of_unknown_size[] = { 84int array_of_unknown_size[] = {
85 111, 85 111,
86 222, 86 222,
87 333, 87 333,
88}; 88};
89 89
90int array_flat[2][2] = { 90int array_flat[2][2] = {
91 11, 91 11,
92 12, 92 12,
93 21, 93 21,
94 22 94 22
95}; 95};
96 96
@@ -125,28 +125,28 @@ struct point { @@ -125,28 +125,28 @@ struct point {
125struct point point = { 125struct point point = {
126 3, 126 3,
127 4 127 4
128}; 128};
129 129
130struct point point_with_designators = { 130struct point point_with_designators = {
131 .y = 4, 131 .y = 4,
132 .x = 3, 132 .x = 3,
133}; 133};
134 134
135struct point point_with_mixed_designators = { 135struct point point_with_mixed_designators = {
136 .x = 3, 136 .x = 3,
137 4, 137 4,
138 // FIXME: assertion failure '== ARRAY' 138 /* TODO: remove me */
139 // 5, 139 5, /* expect: too many struct/union initializers */
140 .x = 3, 140 .x = 3,
141}; 141};
142 142
143int array_with_designator[] = { 143int array_with_designator[] = {
144 111, 144 111,
145 .member = 222, /* expect: 249 */ 145 .member = 222, /* expect: 249 */
146 333, 146 333,
147}; 147};
148 148
149/* 149/*
150 * 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
151 * 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
152 * 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
@@ -201,56 +201,56 @@ struct pentagon { @@ -201,56 +201,56 @@ struct pentagon {
201}; 201};
202 202
203struct geometry { 203struct geometry {
204 struct pentagon pentagons[6]; 204 struct pentagon pentagons[6];
205 struct triangle triangles[10]; 205 struct triangle triangles[10];
206 struct point points[3][5][2]; 206 struct point points[3][5][2];
207}; 207};
208 208
209/* 209/*
210 * Initialization of a complex struct containing nested arrays and nested 210 * Initialization of a complex struct containing nested arrays and nested
211 * structs. 211 * structs.
212 */ 212 */
213struct geometry geometry = { 213struct geometry geometry = {
214 // FIXME: assertion "istk->i_type != NULL" failed in initstack_push 214 /* TODO: remove me */
215 //.pentagons[0].points[4].x = 1, 215 .pentagons[0].points[4].x = 1,
216 .points[0][0][0] = { 0, 0 }, 216 .points[0][0][0] = { 0, 0 },
217 .points[2][4][1] = {301, 302 }, 217 .points[2][4][1] = {301, 302 },
218 /* 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 */
219 .points[3][0][0] = {3001, 3002 }, 219 .points[3][0][0] = {3001, 3002 },
220 /* 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 */
221 .points[0][5][0] = {501, 502 }, 221 .points[0][5][0] = {501, 502 },
222 /* 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 */
223 .points[0][0][2] = {21, 22 }, 223 .points[0][0][2] = {21, 22 },
224}; 224};
225 225
226struct ends_with_unnamed_bit_field { 226struct ends_with_unnamed_bit_field {
227 int member; 227 int member;
228 int : 0; 228 int : 0;
229} ends_with_unnamed_bit_field = { 229} ends_with_unnamed_bit_field = {
230 12345, 230 12345,
231 /* expect+1: too many struct/union initializers */ 231 /* expect+1: too many struct/union initializers */
232 23456, 232 23456,
233}; 233};
234 234
235char prefixed_message[] = { 235char prefixed_message[] = {
236 'E', ':', ' ', 236 'E', ':', ' ',
237 /* expect+1: illegal combination of integer (char) and pointer */ 237 /* expect+1: illegal combination of integer (char) and pointer */
238 "message\n", 238 "message\n",
239}; 239};
240 240
241char message_with_suffix[] = { 241char message_with_suffix[] = {
242 "message", 242 "message", /* expect: illegal combination */
243 /* expect+1: too many array initializers */ 243 /* */
244 '\n', 244 '\n',
245}; 245};
246 246
247struct ten { 247struct ten {
248 int i0; 248 int i0;
249 int i1; 249 int i1;
250 int i2; 250 int i2;
251 int i3; 251 int i3;
252 int i4; 252 int i4;
253 int i5; 253 int i5;
254 int i6; 254 int i6;
255 int i7; 255 int i7;
256 int i8; 256 int i8;
@@ -269,27 +269,27 @@ int c99_6_7_8_p26_example3[4][3] = { @@ -269,27 +269,27 @@ int c99_6_7_8_p26_example3[4][3] = {
269 { 1, 3, 5 }, 269 { 1, 3, 5 },
270 { 2, 4, 6 }, 270 { 2, 4, 6 },
271 { 3, 5, 7 }, 271 { 3, 5, 7 },
272}; 272};
273 273
274int c99_6_7_8_p27_example4[4][3] = { 274int c99_6_7_8_p27_example4[4][3] = {
275 { 1 }, { 2 }, { 3 }, { 4 } 275 { 1 }, { 2 }, { 3 }, { 4 }
276}; 276};
277 277
278struct { 278struct {
279 int a[3], b; 279 int a[3], b;
280} c99_6_7_8_p28_example5[] = { 280} c99_6_7_8_p28_example5[] = {
281 { 1 }, 281 { 1 },
282 2, 282 2, /* XXX *//* expect: cannot initialize */
283}; 283};
284 284
285short c99_6_7_8_p29_example6a[4][3][2] = { 285short c99_6_7_8_p29_example6a[4][3][2] = {
286 { 1 }, 286 { 1 },
287 { 2, 3 }, 287 { 2, 3 },
288 { 4, 5, 6 }, 288 { 4, 5, 6 },
289}; 289};
290 290
291short c99_6_7_8_p29_example6b[4][3][2] = { 291short c99_6_7_8_p29_example6b[4][3][2] = {
292 1, 0, 0, 0, 0, 0, 292 1, 0, 0, 0, 0, 0,
293 2, 3, 0, 0, 0, 0, 293 2, 3, 0, 0, 0, 0,
294 4, 5, 6, 0, 0, 0, 294 4, 5, 6, 0, 0, 0,
295}; 295};
@@ -320,47 +320,65 @@ ensure_array_type_is_not_modified_during @@ -320,47 +320,65 @@ ensure_array_type_is_not_modified_during
320 array_of_unknown_size a1 = { 1, 2, 3}; 320 array_of_unknown_size a1 = { 1, 2, 3};
321 321
322 switch (4) { 322 switch (4) {
323 case sizeof(array_of_unknown_size): 323 case sizeof(array_of_unknown_size):
324 case 0: /* expect: duplicate case in switch: 0 */ 324 case 0: /* expect: duplicate case in switch: 0 */
325 case 3: 325 case 3:
326 case 4: 326 case 4:
327 case 12: 327 case 12:
328 break; 328 break;
329 } 329 }
330} 330}
331 331
332struct point unknown_member_name_beginning = { 332struct point unknown_member_name_beginning = {
333 // FIXME: assertion "bl->bl_type != NULL" failed in initialization_push 333 /* TODO: remove me */
334 // .r = 5, 334 .r = 5, /* expect: undefined struct/union member: r */
335 .x = 4, 335 .x = 4,
336 .y = 3, 336 .y = 3,
337}; 337};
338 338
339struct point unknown_member_name_middle = { 339struct point unknown_member_name_middle = {
340 .x = 4, 340 .x = 4,
341 .r = 5, /* expect: undefined struct/union member: r */ 341 .r = 5, /* expect: undefined struct/union member: r */
342 .y = 3, 342 .y = 3,
343}; 343};
344 344
345struct point unknown_member_name_end = { 345struct point unknown_member_name_end = {
346 .x = 4, 346 .x = 4,
347 .y = 3, 347 .y = 3,
348 .r = 5, /* expect: undefined struct/union member: r */ 348 .r = 5, /* expect: undefined struct/union member: r */
349}; 349};
350 350
351union value { 351union value {
352 int int_value; 352 int int_value;
353 void *pointer_value; 353 void *pointer_value;
354}; 354};
355 355
356union value unknown_union_member_name_first = { 356union value unknown_union_member_name_first = {
357 // FIXME: assertion "bl->bl_type != NULL" failed in initialization_push 357 /* TODO: remove me */
358 // .unknown_value = 4, 358 .unknown_value = 4, /* expect: undefined struct/union member */
359 .int_value = 3, 359 .int_value = 3,
360}; 360};
361 361
362union value unknown_union_member_name_second = { 362union value unknown_union_member_name_second = {
363 .int_value = 3, 363 .int_value = 3,
364 // FIXME: assertion "bl->bl_type->t_tspec == ARRAY" failed in brace_level_extend_if_array_of_unknown_size 364 /* TODO: remove me */
365 // .unknown_value = 4, 365 .unknown_value = 4, /* expect: undefined struct/union member */
 366};
 367
 368struct point designators_with_subscript = {
 369 [0] = 3, /* expect: only for arrays */
 370 .member[0][0].member = 4, /* expect: undefined struct/union member */
 371 .x.y.z = 5, /* intentionally not caught, see designator_look_up */
 372};
 373
 374struct {
 375 int : 16;
 376} struct_with_only_unnamed_members = { /* expect: has no named members */
 377 123, /* expect: too many struct/union initializers */
 378};
 379
 380union {
 381 int : 16;
 382} union_with_only_unnamed_members = { /* expect: has no named members */
 383 123, /* expect: too many struct/union initializers */
366}; 384};

cvs diff -r1.16 -r1.17 src/tests/usr.bin/xlint/lint1/Attic/d_c99_init.exp (expand / switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/Attic/d_c99_init.exp 2021/03/29 22:36:31 1.16
+++ src/tests/usr.bin/xlint/lint1/Attic/d_c99_init.exp 2021/03/30 14:25:28 1.17
@@ -1,10 +1,21 @@ @@ -1,10 +1,21 @@
1d_c99_init.c(23): error: too many initializers [174] 1d_c99_init.c(23): error: too many initializers [174]
2d_c99_init.c(63): error: cannot initialize 'pointer to const void' from 'struct any' [185] 2d_c99_init.c(63): error: cannot initialize 'pointer to const void' from 'struct any' [185]
3d_c99_init.c(80): error: too many array initializers, expected 3 [173] 3d_c99_init.c(80): error: too many array initializers, expected 3 [173]
 4d_c99_init.c(139): error: too many struct/union initializers [172]
4d_c99_init.c(145): error: syntax error 'named member must only be used with struct/union' [249] 5d_c99_init.c(145): error: syntax error 'named member must only be used with struct/union' [249]
5d_c99_init.c(232): error: too many struct/union initializers [172] 6d_c99_init.c(232): error: too many struct/union initializers [172]
6d_c99_init.c(238): warning: illegal combination of integer (char) and pointer (pointer to char) [183] 7d_c99_init.c(238): warning: illegal combination of integer (char) and pointer (pointer to char) [183]
7d_c99_init.c(244): error: too many array initializers, expected 8 [173] 8d_c99_init.c(242): warning: illegal combination of integer (char) and pointer (pointer to char) [183]
 9d_c99_init.c(282): error: cannot initialize 'struct <unnamed>' from 'int' [185]
8d_c99_init.c(324): error: duplicate case in switch: 0 [199] 10d_c99_init.c(324): error: duplicate case in switch: 0 [199]
 11d_c99_init.c(334): error: undefined struct/union member: r [101]
9d_c99_init.c(341): error: undefined struct/union member: r [101] 12d_c99_init.c(341): error: undefined struct/union member: r [101]
10d_c99_init.c(348): error: undefined struct/union member: r [101] 13d_c99_init.c(348): error: undefined struct/union member: r [101]
 14d_c99_init.c(358): error: undefined struct/union member: unknown_value [101]
 15d_c99_init.c(365): error: undefined struct/union member: unknown_value [101]
 16d_c99_init.c(369): error: syntax error 'designator '[...]' is only for arrays' [249]
 17d_c99_init.c(370): error: undefined struct/union member: member [101]
 18d_c99_init.c(376): warning: structure has no named members [65]
 19d_c99_init.c(377): error: too many struct/union initializers [172]
 20d_c99_init.c(382): warning: union has no named members [65]
 21d_c99_init.c(383): error: too many struct/union initializers [172]

cvs diff -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/d_init_array_using_string.c (expand / switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/d_init_array_using_string.c 2021/03/23 22:58:08 1.2
+++ src/tests/usr.bin/xlint/lint1/d_init_array_using_string.c 2021/03/30 14:25:28 1.3
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: d_init_array_using_string.c,v 1.2 2021/03/23 22:58:08 rillig Exp $ */ 1/* $NetBSD: d_init_array_using_string.c,v 1.3 2021/03/30 14:25:28 rillig Exp $ */
2# 3 "d_init_array_using_string.c" 2# 3 "d_init_array_using_string.c"
3 3
4/* 4/*
5 * Test initialization of arrays and pointers by string literals. 5 * Test initialization of arrays and pointers by string literals.
6 */ 6 */
7 7
8void sink(const void *); 8void sink(const void *);
9 9
10void 10void
11test_assignment_initialization(void) 11test_assignment_initialization(void)
12{ 12{
13 const char *cs_match = ""; 13 const char *cs_match = "";
14 const int *ws_match = L""; 14 const int *ws_match = L"";
@@ -46,32 +46,34 @@ void @@ -46,32 +46,34 @@ void
46test_array_initialization_in_struct(void) 46test_array_initialization_in_struct(void)
47{ 47{
48 struct cs_ws { 48 struct cs_ws {
49 const char cs[10]; 49 const char cs[10];
50 const int ws[10]; 50 const int ws[10];
51 }; 51 };
52 52
53 struct cs_ws type_match = { 53 struct cs_ws type_match = {
54 "", 54 "",
55 L"", 55 L"",
56 }; 56 };
57 57
58 struct cs_ws type_mismatch = { 58 struct cs_ws type_mismatch = {
59 L"", /* expect: illegal combination */ 59 L"", /* expect: cannot initialize */
60 "", /* expect: illegal combination */ 60 "", /* expect: cannot initialize */
61 }; 61 };
62 62
63 struct cs_ws no_terminating_null = { 63 struct cs_ws no_terminating_null = {
64 "0123456789", 64 "0123456789",
65 L"0123456789", 65 L"0123456789",
66 }; 66 };
67 67
68 struct cs_ws too_many_characters = { 68 struct cs_ws too_many_characters = {
69 "0123456789X", /* expect: non-null byte ignored */ 69 "0123456789X", /* expect: non-null byte ignored */
70 L"0123456789X", /* expect: non-null byte ignored */ 70 L"0123456789X", /* expect: non-null byte ignored */
71 }; 71 };
72 72
73 struct cs_ws extra_braces = { 73 struct cs_ws extra_braces = {
74 { "" }, 74 { "" },
75 { L"" }, 75 { L"" },
76 }; 76 };
 77 /* expect-3: illegal combination of integer (char) and pointer (pointer to char) */
 78 /* expect-3: illegal combination of integer (int) and pointer (pointer to int) */
77} 79}

cvs diff -r1.2 -r1.3 src/tests/usr.bin/xlint/lint1/Attic/d_init_array_using_string.exp (expand / switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/Attic/d_init_array_using_string.exp 2021/03/23 22:58:08 1.2
+++ src/tests/usr.bin/xlint/lint1/Attic/d_init_array_using_string.exp 2021/03/30 14:25:28 1.3
@@ -1,8 +1,10 @@ @@ -1,8 +1,10 @@
1d_init_array_using_string.c(16): warning: illegal pointer combination (pointer to const char) and (pointer to int), op = [124] 1d_init_array_using_string.c(16): warning: illegal pointer combination (pointer to const char) and (pointer to int), op = [124]
2d_init_array_using_string.c(17): warning: illegal pointer combination (pointer to const int) and (pointer to char), op = [124] 2d_init_array_using_string.c(17): warning: illegal pointer combination (pointer to const int) and (pointer to char), op = [124]
3d_init_array_using_string.c(34): warning: illegal pointer combination [184] 3d_init_array_using_string.c(34): warning: illegal pointer combination [184]
4d_init_array_using_string.c(35): warning: illegal pointer combination [184] 4d_init_array_using_string.c(35): warning: illegal pointer combination [184]
5d_init_array_using_string.c(59): warning: illegal combination of integer (char) and pointer (pointer to int) [183] 5d_init_array_using_string.c(59): error: cannot initialize 'array[10] of const char' from 'pointer to int' [185]
6d_init_array_using_string.c(60): warning: illegal combination of integer (char) and pointer (pointer to char) [183] 6d_init_array_using_string.c(60): error: cannot initialize 'array[10] of const int' from 'pointer to char' [185]
7d_init_array_using_string.c(69): warning: non-null byte ignored in string initializer [187] 7d_init_array_using_string.c(69): warning: non-null byte ignored in string initializer [187]
8d_init_array_using_string.c(70): warning: non-null byte ignored in string initializer [187] 8d_init_array_using_string.c(70): warning: non-null byte ignored in string initializer [187]
 9d_init_array_using_string.c(74): warning: illegal combination of integer (char) and pointer (pointer to char) [183]
 10d_init_array_using_string.c(75): warning: illegal combination of integer (int) and pointer (pointer to int) [183]

cvs diff -r1.5 -r1.6 src/tests/usr.bin/xlint/lint1/Attic/d_init_pop_member.exp (expand / switch to unified diff)

--- src/tests/usr.bin/xlint/lint1/Attic/d_init_pop_member.exp 2021/03/21 20:44:59 1.5
+++ src/tests/usr.bin/xlint/lint1/Attic/d_init_pop_member.exp 2021/03/30 14:25:28 1.6

cvs diff -r1.206 -r1.207 src/usr.bin/xlint/lint1/cgram.y (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/cgram.y 2021/03/29 20:39:18 1.206
+++ src/usr.bin/xlint/lint1/cgram.y 2021/03/30 14:25:28 1.207
@@ -1,15 +1,15 @@ @@ -1,15 +1,15 @@
1%{ 1%{
2/* $NetBSD: cgram.y,v 1.206 2021/03/29 20:39:18 rillig Exp $ */ 2/* $NetBSD: cgram.y,v 1.207 2021/03/30 14:25:28 rillig Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 5 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
6 * Copyright (c) 1994, 1995 Jochen Pohl 6 * Copyright (c) 1994, 1995 Jochen Pohl
7 * All Rights Reserved. 7 * All Rights Reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35 35
36#include <sys/cdefs.h> 36#include <sys/cdefs.h>
37#if defined(__RCSID) && !defined(lint) 37#if defined(__RCSID) && !defined(lint)
38__RCSID("$NetBSD: cgram.y,v 1.206 2021/03/29 20:39:18 rillig Exp $"); 38__RCSID("$NetBSD: cgram.y,v 1.207 2021/03/30 14:25:28 rillig Exp $");
39#endif 39#endif
40 40
41#include <limits.h> 41#include <limits.h>
42#include <stdlib.h> 42#include <stdlib.h>
43#include <string.h> 43#include <string.h>
44 44
45#include "lint1.h" 45#include "lint1.h"
46 46
47extern char *yytext; 47extern char *yytext;
48 48
49/* 49/*
50 * Contains the level of current declaration, used for symbol table entries. 50 * Contains the level of current declaration, used for symbol table entries.
51 * 0 is the top-level, > 0 is inside a function body. 51 * 0 is the top-level, > 0 is inside a function body.
@@ -1335,27 +1335,27 @@ opt_asm_or_symbolrename: /* expect only @@ -1335,27 +1335,27 @@ opt_asm_or_symbolrename: /* expect only
1335 $$ = NULL; 1335 $$ = NULL;
1336 } 1336 }
1337 | T_ASM T_LPAREN T_STRING T_RPAREN { 1337 | T_ASM T_LPAREN T_STRING T_RPAREN {
1338 freeyyv(&$3, T_STRING); 1338 freeyyv(&$3, T_STRING);
1339 $$ = NULL; 1339 $$ = NULL;
1340 } 1340 }
1341 | T_SYMBOLRENAME T_LPAREN T_NAME T_RPAREN { 1341 | T_SYMBOLRENAME T_LPAREN T_NAME T_RPAREN {
1342 $$ = $3; 1342 $$ = $3;
1343 } 1343 }
1344 ; 1344 ;
1345 1345
1346initializer: /* C99 6.7.8 "Initialization" */ 1346initializer: /* C99 6.7.8 "Initialization" */
1347 expr %prec T_COMMA { 1347 expr %prec T_COMMA {
1348 init_using_expr($1); 1348 init_expr($1);
1349 } 1349 }
1350 | init_lbrace init_rbrace { 1350 | init_lbrace init_rbrace {
1351 /* XXX: Empty braces are not covered by C99 6.7.8. */ 1351 /* XXX: Empty braces are not covered by C99 6.7.8. */
1352 } 1352 }
1353 | init_lbrace initializer_list comma_opt init_rbrace 1353 | init_lbrace initializer_list comma_opt init_rbrace
1354 | error 1354 | error
1355 ; 1355 ;
1356 1356
1357initializer_list: /* C99 6.7.8 "Initialization" */ 1357initializer_list: /* C99 6.7.8 "Initialization" */
1358 initializer_list_item 1358 initializer_list_item
1359 | initializer_list T_COMMA initializer_list_item 1359 | initializer_list T_COMMA initializer_list_item
1360 ; 1360 ;
1361 1361

cvs diff -r1.166 -r1.167 src/usr.bin/xlint/lint1/decl.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/decl.c 2021/03/27 22:13:55 1.166
+++ src/usr.bin/xlint/lint1/decl.c 2021/03/30 14:25:28 1.167
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: decl.c,v 1.166 2021/03/27 22:13:55 rillig Exp $ */ 1/* $NetBSD: decl.c,v 1.167 2021/03/30 14:25:28 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved. 4 * Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
5 * Copyright (c) 1994, 1995 Jochen Pohl 5 * Copyright (c) 1994, 1995 Jochen Pohl
6 * All Rights Reserved. 6 * All Rights Reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -28,27 +28,27 @@ @@ -28,27 +28,27 @@
28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35#if HAVE_NBTOOL_CONFIG_H 35#if HAVE_NBTOOL_CONFIG_H
36#include "nbtool_config.h" 36#include "nbtool_config.h"
37#endif 37#endif
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40#if defined(__RCSID) && !defined(lint) 40#if defined(__RCSID) && !defined(lint)
41__RCSID("$NetBSD: decl.c,v 1.166 2021/03/27 22:13:55 rillig Exp $"); 41__RCSID("$NetBSD: decl.c,v 1.167 2021/03/30 14:25:28 rillig Exp $");
42#endif 42#endif
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <limits.h> 45#include <limits.h>
46#include <stdlib.h> 46#include <stdlib.h>
47#include <string.h> 47#include <string.h>
48 48
49#include "lint1.h" 49#include "lint1.h"
50 50
51const char *unnamed = "<unnamed>"; 51const char *unnamed = "<unnamed>";
52 52
53/* shared type structures for arithmetic types and void */ 53/* shared type structures for arithmetic types and void */
54static type_t *typetab; 54static type_t *typetab;
@@ -1903,27 +1903,27 @@ declare_extern(sym_t *dsym, bool initflg @@ -1903,27 +1903,27 @@ declare_extern(sym_t *dsym, bool initflg
1903 1903
1904 if (renaming != NULL) { 1904 if (renaming != NULL) {
1905 lint_assert(dsym->s_rename == NULL); 1905 lint_assert(dsym->s_rename == NULL);
1906 1906
1907 s = getlblk(1, renaming->sb_len + 1); 1907 s = getlblk(1, renaming->sb_len + 1);
1908 (void)memcpy(s, renaming->sb_name, renaming->sb_len + 1); 1908 (void)memcpy(s, renaming->sb_name, renaming->sb_len + 1);
1909 dsym->s_rename = s; 1909 dsym->s_rename = s;
1910 } 1910 }
1911 1911
1912 check_function_definition(dsym, true); 1912 check_function_definition(dsym, true);
1913 1913
1914 check_type(dsym); 1914 check_type(dsym);
1915 1915
1916 if (initflg && !(*current_initerr() = check_init(dsym))) 1916 if (initflg && !check_init(dsym))
1917 dsym->s_def = DEF; 1917 dsym->s_def = DEF;
1918 1918
1919 /* 1919 /*
1920 * Declarations of functions are marked as "tentative" in 1920 * Declarations of functions are marked as "tentative" in
1921 * declarator_name(). This is wrong because there are no 1921 * declarator_name(). This is wrong because there are no
1922 * tentative function definitions. 1922 * tentative function definitions.
1923 */ 1923 */
1924 if (dsym->s_type->t_tspec == FUNC && dsym->s_def == TDEF) 1924 if (dsym->s_type->t_tspec == FUNC && dsym->s_def == TDEF)
1925 dsym->s_def = DECL; 1925 dsym->s_def = DECL;
1926 1926
1927 if (dcs->d_inline) { 1927 if (dcs->d_inline) {
1928 if (dsym->s_type->t_tspec == FUNC) { 1928 if (dsym->s_type->t_tspec == FUNC) {
1929 dsym->s_inline = true; 1929 dsym->s_inline = true;
@@ -2033,29 +2033,26 @@ declare(sym_t *decl, bool initflg, sbuf_ @@ -2033,29 +2033,26 @@ declare(sym_t *decl, bool initflg, sbuf_
2033 if (renaming != NULL) { 2033 if (renaming != NULL) {
2034 /* symbol renaming can't be used on function arguments */ 2034 /* symbol renaming can't be used on function arguments */
2035 error(310); 2035 error(310);
2036 } else 2036 } else
2037 (void)declare_argument(decl, initflg); 2037 (void)declare_argument(decl, initflg);
2038 } else { 2038 } else {
2039 lint_assert(dcs->d_ctx == AUTO); 2039 lint_assert(dcs->d_ctx == AUTO);
2040 if (renaming != NULL) { 2040 if (renaming != NULL) {
2041 /* symbol renaming can't be used on automatic variables */ 2041 /* symbol renaming can't be used on automatic variables */
2042 error(311); 2042 error(311);
2043 } else 2043 } else
2044 declare_local(decl, initflg); 2044 declare_local(decl, initflg);
2045 } 2045 }
2046 
2047 if (initflg && !*current_initerr()) 
2048 initstack_init(); 
2049} 2046}
2050 2047
2051/* 2048/*
2052 * Copies information about usage into a new symbol table entry of 2049 * Copies information about usage into a new symbol table entry of
2053 * the same symbol. 2050 * the same symbol.
2054 */ 2051 */
2055void 2052void
2056copy_usage_info(sym_t *sym, sym_t *rdsym) 2053copy_usage_info(sym_t *sym, sym_t *rdsym)
2057{ 2054{
2058 2055
2059 sym->s_set_pos = rdsym->s_set_pos; 2056 sym->s_set_pos = rdsym->s_set_pos;
2060 sym->s_use_pos = rdsym->s_use_pos; 2057 sym->s_use_pos = rdsym->s_use_pos;
2061 sym->s_set = rdsym->s_set; 2058 sym->s_set = rdsym->s_set;
@@ -2406,27 +2403,26 @@ declare_argument(sym_t *sym, bool initfl @@ -2406,27 +2403,26 @@ declare_argument(sym_t *sym, bool initfl
2406 rmsym(dcs->d_redeclared_symbol); 2403 rmsym(dcs->d_redeclared_symbol);
2407 sym->s_arg = true; 2404 sym->s_arg = true;
2408 } 2405 }
2409 2406
2410 if (!sym->s_arg) { 2407 if (!sym->s_arg) {
2411 /* declared argument %s is missing */ 2408 /* declared argument %s is missing */
2412 error(53, sym->s_name); 2409 error(53, sym->s_name);
2413 sym->s_arg = true; 2410 sym->s_arg = true;
2414 } 2411 }
2415 2412
2416 if (initflg) { 2413 if (initflg) {
2417 /* cannot initialize parameter: %s */ 2414 /* cannot initialize parameter: %s */
2418 error(52, sym->s_name); 2415 error(52, sym->s_name);
2419 *current_initerr() = true; 
2420 } 2416 }
2421 2417
2422 if ((t = sym->s_type->t_tspec) == ARRAY) { 2418 if ((t = sym->s_type->t_tspec) == ARRAY) {
2423 sym->s_type = incref(sym->s_type->t_subt, PTR); 2419 sym->s_type = incref(sym->s_type->t_subt, PTR);
2424 } else if (t == FUNC) { 2420 } else if (t == FUNC) {
2425 if (tflag) 2421 if (tflag)
2426 /* a function is declared as an argument: %s */ 2422 /* a function is declared as an argument: %s */
2427 warning(50, sym->s_name); 2423 warning(50, sym->s_name);
2428 sym->s_type = incref(sym->s_type, PTR); 2424 sym->s_type = incref(sym->s_type, PTR);
2429 } else if (t == FLOAT) { 2425 } else if (t == FLOAT) {
2430 if (tflag) 2426 if (tflag)
2431 sym->s_type = gettyp(DOUBLE); 2427 sym->s_type = gettyp(DOUBLE);
2432 } 2428 }
@@ -2741,27 +2737,27 @@ declare_local(sym_t *dsym, bool initflg) @@ -2741,27 +2737,27 @@ declare_local(sym_t *dsym, bool initflg)
2741 2737
2742 } 2738 }
2743 2739
2744 if (dcs->d_redeclared_symbol->s_block_level == block_level) { 2740 if (dcs->d_redeclared_symbol->s_block_level == block_level) {
2745 2741
2746 /* redeclaration of %s */ 2742 /* redeclaration of %s */
2747 error(27, dsym->s_name); 2743 error(27, dsym->s_name);
2748 rmsym(dcs->d_redeclared_symbol); 2744 rmsym(dcs->d_redeclared_symbol);
2749 2745
2750 } 2746 }
2751 2747
2752 } 2748 }
2753 2749
2754 if (initflg && !(*current_initerr() = check_init(dsym))) { 2750 if (initflg && !check_init(dsym)) {
2755 dsym->s_def = DEF; 2751 dsym->s_def = DEF;
2756 mark_as_set(dsym); 2752 mark_as_set(dsym);
2757 } 2753 }
2758 2754
2759 if (dsym->s_scl == TYPEDEF) { 2755 if (dsym->s_scl == TYPEDEF) {
2760 dsym->s_type = duptyp(dsym->s_type); 2756 dsym->s_type = duptyp(dsym->s_type);
2761 dsym->s_type->t_typedef = true; 2757 dsym->s_type->t_typedef = true;
2762 settdsym(dsym->s_type, dsym); 2758 settdsym(dsym->s_type, dsym);
2763 } 2759 }
2764 2760
2765 /* 2761 /*
2766 * Before we can check the size we must wait for a initialization 2762 * Before we can check the size we must wait for a initialization
2767 * which may follow. 2763 * which may follow.

cvs diff -r1.94 -r1.95 src/usr.bin/xlint/lint1/externs1.h (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/externs1.h 2021/03/28 13:09:43 1.94
+++ src/usr.bin/xlint/lint1/externs1.h 2021/03/30 14:25:28 1.95
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: externs1.h,v 1.94 2021/03/28 13:09:43 rillig Exp $ */ 1/* $NetBSD: externs1.h,v 1.95 2021/03/30 14:25:28 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved. 5 * All Rights Reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -282,33 +282,31 @@ extern void lintlib(int); @@ -282,33 +282,31 @@ extern void lintlib(int);
282extern void linted(int); 282extern void linted(int);
283extern void varargs(int); 283extern void varargs(int);
284extern void printflike(int); 284extern void printflike(int);
285extern void scanflike(int); 285extern void scanflike(int);
286extern void protolib(int); 286extern void protolib(int);
287extern void longlong(int); 287extern void longlong(int);
288extern void bitfieldtype(int); 288extern void bitfieldtype(int);
289 289
290/* 290/*
291 * init.c 291 * init.c
292 */ 292 */
293extern void begin_initialization(sym_t *); 293extern void begin_initialization(sym_t *);
294extern void end_initialization(void); 294extern void end_initialization(void);
295extern bool *current_initerr(void); 
296extern sym_t **current_initsym(void); 295extern sym_t **current_initsym(void);
297 296
298extern void initstack_init(void); 
299extern void init_rbrace(void); 297extern void init_rbrace(void);
300extern void init_lbrace(void); 298extern void init_lbrace(void);
301extern void init_using_expr(tnode_t *); 299extern void init_expr(tnode_t *);
302extern void add_designator_member(sbuf_t *); 300extern void add_designator_member(sbuf_t *);
303extern void add_designator_subscript(range_t); 301extern void add_designator_subscript(range_t);
304 302
305/* 303/*
306 * emit.c 304 * emit.c
307 */ 305 */
308extern void outtype(const type_t *); 306extern void outtype(const type_t *);
309extern const char *ttos(const type_t *); 307extern const char *ttos(const type_t *);
310extern void outsym(const sym_t *, scl_t, def_t); 308extern void outsym(const sym_t *, scl_t, def_t);
311extern void outfdef(const sym_t *, const pos_t *, bool, bool, 309extern void outfdef(const sym_t *, const pos_t *, bool, bool,
312 const sym_t *); 310 const sym_t *);
313extern void outcall(const tnode_t *, bool, bool); 311extern void outcall(const tnode_t *, bool, bool);
314extern void outusg(const sym_t *); 312extern void outusg(const sym_t *);

cvs diff -r1.178 -r1.179 src/usr.bin/xlint/lint1/init.c (expand / switch to unified diff)

--- src/usr.bin/xlint/lint1/init.c 2021/03/29 21:34:17 1.178
+++ src/usr.bin/xlint/lint1/init.c 2021/03/30 14:25:28 1.179
@@ -1,17 +1,18 @@ @@ -1,17 +1,18 @@
1/* $NetBSD: init.c,v 1.178 2021/03/29 21:34:17 rillig Exp $ */ 1/* $NetBSD: init.c,v 1.179 2021/03/30 14:25:28 rillig Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1994, 1995 Jochen Pohl 4 * Copyright (c) 1994, 1995 Jochen Pohl
 5 * Copyright (c) 2021 Roland Illig
5 * All Rights Reserved. 6 * All Rights Reserved.
6 * 7 *
7 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
9 * are met: 10 * are met:
10 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software 16 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 17 * must display the following acknowledgement:
17 * This product includes software developed by Jochen Pohl for 18 * This product includes software developed by Jochen Pohl for
@@ -27,323 +28,213 @@ @@ -27,323 +28,213 @@
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */ 33 */
33 34
34#if HAVE_NBTOOL_CONFIG_H 35#if HAVE_NBTOOL_CONFIG_H
35#include "nbtool_config.h" 36#include "nbtool_config.h"
36#endif 37#endif
37 38
38#include <sys/cdefs.h> 39#include <sys/cdefs.h>
39#if defined(__RCSID) && !defined(lint) 40#if defined(__RCSID) && !defined(lint)
40__RCSID("$NetBSD: init.c,v 1.178 2021/03/29 21:34:17 rillig Exp $"); 41__RCSID("$NetBSD: init.c,v 1.179 2021/03/30 14:25:28 rillig Exp $");
41#endif 42#endif
42 43
43#include <stdlib.h> 44#include <stdlib.h>
44#include <string.h> 45#include <string.h>
45 46
46#include "lint1.h" 47#include "lint1.h"
47 48
48 49
49/* 50/*
50 * Initialization 51 * Initialization of global or local objects, like in:
51 * 
52 * Handles initializations of global or local objects, like in: 
53 * 52 *
54 * int number = 12345; 53 * int number = 12345;
55 * int number_with_braces = { 12345 }; 54 * int number_with_braces = { 12345 };
56 * 55 *
57 * int array_of_unknown_size[] = { 111, 222, 333 }; 56 * int array_of_unknown_size[] = { 111, 222, 333 };
58 * int array_flat[2][2] = { 11, 12, 21, 22 }; 57 * int array_flat[2][2] = { 11, 12, 21, 22 };
59 * int array_nested[2][2] = { { 11, 12 }, { 21, 22 } }; 58 * int array_nested[2][2] = { { 11, 12 }, { 21, 22 } };
60 * 59 *
61 * struct { int x, y; } point = { 3, 4 }; 60 * struct { int x, y; } point = { 3, 4 };
62 * struct { int x, y; } point = { .y = 4, .x = 3 }; 61 * struct { int x, y; } point = { .y = 4, .x = 3 };
63 * 62 *
64 * Any scalar expression in the initializer may be surrounded by arbitrarily 63 * Any scalar expression in the initializer may be surrounded by arbitrarily
65 * many extra pairs of braces, like in the example 'number_with_braces' (C99 64 * many extra pairs of braces, like in the example 'number_with_braces' (C99
66 * 6.7.8p11). 65 * 6.7.8p11).
67 * 66 *
68 * For multi-dimensional arrays, the inner braces may be omitted like in 67 * For multi-dimensional arrays, the inner braces may be omitted like in
69 * array_flat or spelled out like in array_nested. 68 * array_flat or spelled out like in array_nested. This is unusual in
 69 * practice and therefore only supported very basically.
70 * 70 *
71 * For the initializer, the grammar parser calls these functions: 71 * During initialization, the grammar parser calls these functions:
72 * 72 *
73 * begin_initialization 73 * begin_initialization
74 * init_lbrace for each '{' 74 * init_lbrace for each '{'
75 * add_designator_member for each '.member' before '=' 75 * add_designator_member for each '.member' before '='
76 * add_designator_subscript for each '[123]' before '=' 76 * add_designator_subscript for each '[123]' before '='
77 * init_using_expr for each expression 77 * init_expr for each expression
78 * init_rbrace for each '}' 78 * init_rbrace for each '}'
79 * end_initialization 79 * end_initialization
80 * 80 *
81 * Each '{' begins a new brace level, each '}' ends the current brace level. 81 * Each '{' begins a new brace level, each '}' ends the current brace level.
82 * Each brace level has an associated "current object". 82 * Each brace level has an associated "current object".
83 * 83 *
84 * Most of the time, the topmost level of brace_level contains a scalar type, 
85 * and its remaining count toggles between 1 and 0. 
86 * 
87 * See also: 84 * See also:
88 * C99 6.7.8 "Initialization" 85 * C99 6.7.8 "Initialization"
89 * d_c99_init.c for more examples 86 * d_c99_init.c for more examples
90 */ 87 */
91 88
92 
93/* 
94 * Describes a single brace level of an ongoing initialization. 
95 * 
96 * XXX: Since C99, the initializers can be listed in arbitrary order by using 
97 * designators to specify the sub-object to be initialized. The member names 
98 * of non-leaf structs may thus appear repeatedly, as demonstrated in 
99 * d_init_pop_member.c. 
100 * 
101 * See C99 6.7.8, which spans 6 pages full of tricky details and carefully 
102 * selected examples. 
103 */ 
104struct brace_level { 
105 
106 /* 
107 * The type of the current object that is initialized at this brace 
108 * level. 
109 * 
110 * On the outermost element, this is always NULL since the outermost 
111 * initializer-expression may be enclosed in an optional pair of 
112 * braces, as of the current implementation. 
113 * 
114 * FIXME: This approach is wrong. It's not that the outermost 
115 * initializer may be enclosed in additional braces, it's every scalar 
116 * that may be enclosed in additional braces, as of C99 6.7.8p11. 
117 * 
118 * Everywhere else it is nonnull. 
119 */ 
120 type_t *bl_type; 
121 
122 /* 
123 * The type that will be initialized at the next initialization level, 
124 * usually enclosed by another pair of braces. 
125 * 
126 * For an array, it is the element type, but without 'const'. 
127 * 
128 * For a struct or union type, it is one of the member types, but 
129 * without 'const'. 
130 * 
131 * The outermost stack element has no bl_type but nevertheless has 
132 * bl_subtype. For example, in 'int var = { 12345 }', initially there 
133 * is a brace_level with bl_subtype 'int'. When the '{' is processed, 
134 * an element with bl_type 'int' is pushed to the stack. When the 
135 * corresponding '}' is processed, the inner element is popped again. 
136 * 
137 * During initialization, only the top 2 elements of the stack are 
138 * looked at. 
139 * 
140 * XXX: Having bl_subtype here is the wrong approach, it should not be 
141 * necessary at all; see bl_type. 
142 */ 
143 type_t *bl_subtype; 
144 
145 /* 
146 * Whether this level of the initializer requires a '}' to be 
147 * completed. 
148 * 
149 * Multidimensional arrays do not need a closing brace to complete 
150 * an inner array; for example, { 1, 2, 3, 4 } is a valid initializer 
151 * for 'int arr[2][2]'. 
152 * 
153 * XXX: Double-check whether this is the correct approach at all; see 
154 * bl_type. 
155 */ 
156 bool bl_brace: 1; 
157 
158 /* Whether bl_type is an array of unknown size. */ 
159 bool bl_array_of_unknown_size: 1; 
160 
161 /* 
162 * XXX: This feels wrong. Whether or not there has been a named 
163 * initializer (called 'designation' since C99) should not matter at 
164 * all. Even after an initializer with designation, counting of the 
165 * remaining elements continues, see C99 6.7.8p17. 
166 */ 
167 bool bl_seen_named_member: 1; 
168 
169 /* 
170 * For structs, the next member to be initialized by a designator-less 
171 * initializer. 
172 */ 
173 sym_t *bl_next_member; 
174 
175 /* TODO: Add bl_next_subscript for arrays. */ 
176 
177 /* TODO: Understand C99 6.7.8p17 and footnote 128 for unions. */ 
178 
179 /* 
180 * The number of remaining elements to be used by expressions without 
181 * designator. 
182 * 
183 * This says nothing about which members have been initialized or not 
184 * since starting with C99, members may be initialized in arbitrary 
185 * order by using designators. 
186 * 
187 * For an array of unknown size, this is always 0 and thus irrelevant. 
188 * 
189 * XXX: for scalars? 
190 * XXX: for structs? 
191 * XXX: for unions? 
192 * XXX: for arrays? 
193 * 
194 * XXX: Having the count of remaining objects should not be necessary. 
195 * It is probably clearer to use bl_next_member and bl_next_subscript 
196 * for this purpose. 
197 */ 
198 int bl_remaining; 
199 
200 /* 
201 * The initialization state of the enclosing data structure 
202 * (struct, union, array). 
203 * 
204 * XXX: Or for a scalar, for the top-level element, or for expressions 
205 * in redundant braces such as '{{{{ 0 }}}}' (not yet implemented as 
206 * of 2021-03-25). 
207 */ 
208 struct brace_level *bl_enclosing; 
209}; 
210 
211/* 89/*
212 * A single component on the path to the sub-object that is initialized by an 90 * A single component on the path to the sub-object that is initialized by an
213 * initializer expression. Either a struct or union member, or an array 91 * initializer expression. Either a struct or union member, or an array
214 * subscript. 92 * subscript.
215 * 93 *
216 * See also: C99 6.7.8 "Initialization" 94 * C99 6.7.8p6, 6.7.8p7
217 */ 95 */
218struct designator { 96struct designator {
219 const char *dr_name; /* for struct and union */ 97 const char *dr_name; /* for struct and union */
220 /* TODO: add 'dr_subscript' for arrays */ 98 size_t dr_subscript; /* for array */
221 struct designator *dr_next; 99 struct designator *dr_next;
222}; 100};
223 101
224/* 102/*
225 * The optional designation for an initializer, saying which sub-object to 103 * The optional designation for an initializer, saying which sub-object to
226 * initialize. Examples for designations are '.member' or 104 * initialize. Examples for designations are '.member' or
227 * '.member[123].member.member[1][1]'. 105 * '.member[123].member.member[1][1]'.
228 * 106 *
229 * See also: C99 6.7.8 "Initialization" 107 * C99 6.7.8p6, 6.7.8p7
230 */ 108 */
231struct designation { 109struct designation {
232 struct designator *dn_head; 110 struct designator *dn_head;
233 struct designator *dn_tail; 111 struct designator *dn_tail;
234}; 112};
235 113
 114/*
 115 * Describes a single brace level of an ongoing initialization.
 116 *
 117 * See C99 6.7.8p17.
 118 */
 119struct brace_level {
 120 /*
 121 * The type of the current object that is initialized at this brace
 122 * level.
 123 */
 124 const type_t *bl_type;
 125 const sym_t *bl_next_member; /* for structs and unions */
 126 size_t bl_array_next_subscript;
 127 bool bl_array_of_unknown_size: 1;
 128 bool bl_scalar_done: 1; /* for scalars */
 129 bool bl_omitted_braces: 1; /* skip further checks */
 130 struct designation bl_designation; /* .member[123].member */
 131 struct brace_level *bl_enclosing;
 132};
 133
236struct initialization { 134struct initialization {
237 /* 135 /*
238 * is set as soon as a fatal error occurred in the initialization. 136 * Is set as soon as a fatal error occurred in the initialization.
239 * The effect is that the rest of the initialization is ignored 137 * The effect is that the rest of the initialization is ignored
240 * (parsed by yacc, expression trees built, but no initialization 138 * (parsed by yacc, expression trees built, but no initialization
241 * takes place). 139 * takes place).
242 */ 140 */
243 bool in_err; 141 bool in_err;
244 142
245 /* The symbol that is to be initialized. */ 143 /* The symbol that is to be initialized. */
246 sym_t *in_sym; 144 sym_t *in_sym;
247 145
248 /* The innermost brace level. */ 146 /* The innermost brace level. */
249 struct brace_level *in_brace_level; 147 struct brace_level *in_brace_level;
250 148
251 /* 149 struct initialization *in_enclosing;
252 * The C99 designator, if any, for the current initialization 
253 * expression. 
254 */ 
255 struct designation in_designation; 
256 
257 struct initialization *in_next; 
258}; 150};
259 151
260 152
261static struct initialization *init; 
262 
263 
264#ifdef DEBUG 153#ifdef DEBUG
265static int debug_ind = 0; 154static int debug_indentation = 0;
266#endif 155#endif
267 156
268 157
269#ifdef DEBUG 158#ifdef DEBUG
270 159
271static void __printflike(1, 2) 160static void __printflike(1, 2)
272debug_printf(const char *fmt, ...) 161debug_printf(const char *fmt, ...)
273{ 162{
274 va_list va; 163 va_list va;
275 164
276 va_start(va, fmt); 165 va_start(va, fmt);
277 vfprintf(stdout, fmt, va); 166 vfprintf(stdout, fmt, va);
278 va_end(va); 167 va_end(va);
279} 168}
280 169
281static void 170static void
282debug_indent(void) 171debug_indent(void)
283{ 172{
284 173
285 debug_printf("%*s", 2 * debug_ind, ""); 174 debug_printf("%*s", 2 * debug_indentation, "");
286} 175}
287 176
288static void 177static void
289debug_enter(const char *func) 178debug_enter(const char *func)
290{ 179{
291 180
292 printf("%*s+ %s\n", 2 * debug_ind++, "", func); 181 printf("%*s+ %s\n", 2 * debug_indentation++, "", func);
293} 182}
294 183
295static void __printflike(1, 2) 184static void __printflike(1, 2)
296debug_step(const char *fmt, ...) 185debug_step(const char *fmt, ...)
297{ 186{
298 va_list va; 187 va_list va;
299 188
300 debug_indent(); 189 debug_indent();
301 va_start(va, fmt); 190 va_start(va, fmt);
302 vfprintf(stdout, fmt, va); 191 vfprintf(stdout, fmt, va);
303 va_end(va); 192 va_end(va);
304 printf("\n"); 193 printf("\n");
305} 194}
306 195
307static void 196static void
308debug_leave(const char *func) 197debug_leave(const char *func)
309{ 198{
310 199
311 printf("%*s- %s\n", 2 * --debug_ind, "", func); 200 printf("%*s- %s\n", 2 * --debug_indentation, "", func);
312} 201}
313 202
314#define debug_enter() (debug_enter)(__func__) 203#define debug_enter() (debug_enter)(__func__)
315#define debug_leave() (debug_leave)(__func__) 204#define debug_leave() (debug_leave)(__func__)
316 205
317#else 206#else
318 207
 208/* TODO: This is C99 */
319#define debug_printf(fmt, ...) do { } while (false) 209#define debug_printf(fmt, ...) do { } while (false)
320#define debug_indent() do { } while (false) 210#define debug_indent() do { } while (false)
321#define debug_enter() do { } while (false) 211#define debug_enter() do { } while (false)
322#define debug_step(fmt, ...) do { } while (false) 212#define debug_step(fmt, ...) do { } while (false)
323#define debug_leave() do { } while (false) 213#define debug_leave() do { } while (false)
324 214
325#endif 215#endif
326 216
327 217
328static void * 218static void *
329unconst_cast(const void *p) 219unconst_cast(const void *p)
330{ 220{
331 void *r; 221 void *r;
332 222
333 memcpy(&r, &p, sizeof r); 223 memcpy(&r, &p, sizeof r);
334 return r; 224 return r;
335} 225}
336 226
 227/* C99 6.7.8p7 */
337static bool 228static bool
338is_struct_or_union(tspec_t t) 229is_struct_or_union(tspec_t t)
339{ 230{
340 231
341 return t == STRUCT || t == UNION; 232 return t == STRUCT || t == UNION;
342} 233}
343 234
344static bool 235static bool
345has_automatic_storage_duration(const sym_t *sym) 236has_automatic_storage_duration(const sym_t *sym)
346{ 237{
347 238
348 return sym->s_scl == AUTO || sym->s_scl == REG; 239 return sym->s_scl == AUTO || sym->s_scl == REG;
349} 240}
@@ -355,42 +246,95 @@ is_string_array(const type_t *tp, tspec_ @@ -355,42 +246,95 @@ is_string_array(const type_t *tp, tspec_
355 tspec_t st; 246 tspec_t st;
356 247
357 if (tp == NULL || tp->t_tspec != ARRAY) 248 if (tp == NULL || tp->t_tspec != ARRAY)
358 return false; 249 return false;
359 250
360 st = tp->t_subt->t_tspec; 251 st = tp->t_subt->t_tspec;
361 return t == CHAR 252 return t == CHAR
362 ? st == CHAR || st == UCHAR || st == SCHAR 253 ? st == CHAR || st == UCHAR || st == SCHAR
363 : st == WCHAR; 254 : st == WCHAR;
364} 255}
365 256
366/* C99 6.7.8p9 */ 257/* C99 6.7.8p9 */
367static bool 258static bool
368is_unnamed_member(const sym_t *m) 259is_unnamed(const sym_t *m)
369{ 260{
370 261
371 return m->s_bitfield && m->s_name == unnamed; 262 return m->s_bitfield && m->s_name == unnamed;
372} 263}
373 264
 265/* C99 6.7.8p9 */
 266static const sym_t *
 267skip_unnamed(const sym_t *m)
 268{
 269
 270 while (m != NULL && is_unnamed(m))
 271 m = m->s_next;
 272 return m;
 273}
 274
374static const sym_t * 275static const sym_t *
375look_up_member(const sym_t *m, const char *name) 276first_named_member(const type_t *tp)
376{ 277{
377 278
378 for (; m != NULL; m = m->s_next) 279 lint_assert(is_struct_or_union(tp->t_tspec));
379 if (!is_unnamed_member(m) && strcmp(m->s_name, name) == 0) 280 return skip_unnamed(tp->t_str->sou_first_member);
 281}
 282
 283static const sym_t *
 284look_up_member(const type_t *tp, const char *name)
 285{
 286 const sym_t *m;
 287
 288 lint_assert(is_struct_or_union(tp->t_tspec));
 289 for (m = tp->t_str->sou_first_member; m != NULL; m = m->s_next)
 290 if (!is_unnamed(m) && strcmp(m->s_name, name) == 0)
380 return m; 291 return m;
381 return NULL; 292 return NULL;
382} 293}
383 294
 295static const type_t *
 296sym_type(const sym_t *sym)
 297{
 298
 299 return sym != NULL ? sym->s_type : NULL;
 300}
 301
 302static const type_t *
 303look_up_member_type(const type_t *tp, const char *name)
 304{
 305 const sym_t *member;
 306
 307 member = look_up_member(tp, name);
 308 if (member == NULL) {
 309 /* TODO: add type information */
 310 /* undefined struct/union member: %s */
 311 error(101, name);
 312 }
 313
 314 return sym_type(member);
 315}
 316
 317static void
 318update_type_of_array_of_unknown_size(sym_t *sym, size_t size)
 319{
 320 type_t *tp;
 321
 322 tp = duptyp(sym->s_type);
 323 tp->t_dim = (int)size;
 324 tp->t_incomplete_array = false;
 325 sym->s_type = tp;
 326}
 327
384 328
385/* In traditional C, bit-fields can be initialized only by integer constants. */ 329/* In traditional C, bit-fields can be initialized only by integer constants. */
386static void 330static void
387check_bit_field_init(const tnode_t *ln, tspec_t lt, tspec_t rt) 331check_bit_field_init(const tnode_t *ln, tspec_t lt, tspec_t rt)
388{ 332{
389 333
390 if (tflag && 334 if (tflag &&
391 is_integer(lt) && 335 is_integer(lt) &&
392 ln->tn_type->t_bitfield && 336 ln->tn_type->t_bitfield &&
393 !is_integer(rt)) { 337 !is_integer(rt)) {
394 /* bit-field initialization is illegal in traditional C */ 338 /* bit-field initialization is illegal in traditional C */
395 warning(186); 339 warning(186);
396 } 340 }
@@ -408,26 +352,38 @@ check_non_constant_initializer(const tno @@ -408,26 +352,38 @@ check_non_constant_initializer(const tno
408 if (constant_addr(tn, &unused_sym, &unused_offs)) 352 if (constant_addr(tn, &unused_sym, &unused_offs))
409 return; 353 return;
410 354
411 if (has_automatic_storage_duration(sym)) { 355 if (has_automatic_storage_duration(sym)) {
412 /* non-constant initializer */ 356 /* non-constant initializer */
413 c99ism(177); 357 c99ism(177);
414 } else { 358 } else {
415 /* non-constant initializer */ 359 /* non-constant initializer */
416 error(177); 360 error(177);
417 } 361 }
418} 362}
419 363
420static void 364static void
 365check_no_auto_aggregate(const sym_t *sym)
 366{
 367
 368 if (tflag &&
 369 has_automatic_storage_duration(sym) &&
 370 !is_scalar(sym->s_type->t_tspec)) {
 371 /* no automatic aggregate initialization in trad. C */
 372 warning(188);
 373 }
 374}
 375
 376static void
421check_init_expr(const type_t *tp, sym_t *sym, tnode_t *tn) 377check_init_expr(const type_t *tp, sym_t *sym, tnode_t *tn)
422{ 378{
423 tnode_t *ln; 379 tnode_t *ln;
424 tspec_t lt, rt; 380 tspec_t lt, rt;
425 struct mbl *tmem; 381 struct mbl *tmem;
426 382
427 /* Create a temporary node for the left side. */ 383 /* Create a temporary node for the left side. */
428 ln = tgetblk(sizeof *ln); 384 ln = tgetblk(sizeof *ln);
429 ln->tn_op = NAME; 385 ln->tn_op = NAME;
430 ln->tn_type = tduptyp(tp); 386 ln->tn_type = tduptyp(tp);
431 ln->tn_type->t_const = false; 387 ln->tn_type->t_const = false;
432 ln->tn_lvalue = true; 388 ln->tn_lvalue = true;
433 ln->tn_sym = sym; 389 ln->tn_sym = sym;
@@ -453,1042 +409,682 @@ check_init_expr(const type_t *tp, sym_t  @@ -453,1042 +409,682 @@ check_init_expr(const type_t *tp, sym_t
453 check_bit_field_init(ln, lt, rt); 409 check_bit_field_init(ln, lt, rt);
454 410
455 /* 411 /*
456 * XXX: Is it correct to do this conversion _after_ the typeok above? 412 * XXX: Is it correct to do this conversion _after_ the typeok above?
457 */ 413 */
458 if (lt != rt || (tp->t_bitfield && tn->tn_op == CON)) 414 if (lt != rt || (tp->t_bitfield && tn->tn_op == CON))
459 tn = convert(INIT, 0, unconst_cast(tp), tn); 415 tn = convert(INIT, 0, unconst_cast(tp), tn);
460 416
461 check_non_constant_initializer(tn, sym); 417 check_non_constant_initializer(tn, sym);
462} 418}
463 419
464 420
465static struct designator * 421static struct designator *
466designator_new(const char *name) 422designator_new(const char *name, size_t subscript)
467{ 423{
468 struct designator *dr; 424 struct designator *dr;
469 425
470 dr = xcalloc(1, sizeof *dr); 426 dr = xcalloc(1, sizeof *dr);
471 dr->dr_name = name; 427 dr->dr_name = name;
 428 dr->dr_subscript = subscript;
472 return dr; 429 return dr;
473} 430}
474 431
475static void 432static void
476designator_free(struct designator *dr) 433designator_free(struct designator *dr)
477{ 434{
478 435
479 free(dr); 436 free(dr);
480} 437}
481 438
482 439
 440static const type_t *
 441designator_look_up(const struct designator *dr, const type_t *tp)
 442{
 443 switch (tp->t_tspec) {
 444 case STRUCT:
 445 case UNION:
 446 if (dr->dr_name == NULL) {
 447 /* syntax error '%s' */
 448 error(249, "designator '[...]' is only for arrays");
 449 return sym_type(first_named_member(tp));
 450 }
 451
 452 return look_up_member_type(tp, dr->dr_name);
 453 case ARRAY:
 454 if (dr->dr_name != NULL) {
 455 /* TODO: reword; kept for compatibility */
 456 /* syntax error '%s' */
 457 error(249,
 458 "named member must only be used with struct/union");
 459 }
 460 return tp->t_subt;
 461 default:
 462 /* syntax error '%s' */
 463 error(249, "scalar type cannot use designator");
 464 return tp;
 465 }
 466}
 467
 468
483#ifdef DEBUG 469#ifdef DEBUG
484static void 470static void
485designation_debug(const struct designation *dn) 471designation_debug(const struct designation *dn)
486{ 472{
487 const struct designator *dr; 473 const struct designator *dr;
488 474
489 if (dn->dn_head == NULL) 475 if (dn->dn_head == NULL)
490 return; 476 return;
491 477
492 debug_indent(); 478 debug_indent();
493 debug_printf("designation: "); 479 debug_printf("designation: ");
494 for (dr = dn->dn_head; dr != NULL; dr = dr->dr_next) 480 for (dr = dn->dn_head; dr != NULL; dr = dr->dr_next) {
495 debug_printf(".%s", dr->dr_name); 481 if (dr->dr_name != NULL) {
 482 debug_printf(".%s", dr->dr_name);
 483 lint_assert(dr->dr_subscript == 0);
 484 } else
 485 debug_printf("[%zu]", dr->dr_subscript);
 486 }
496 debug_printf("\n"); 487 debug_printf("\n");
497} 488}
498#else 489#else
499#define designation_debug(dn) do { } while (false) 490#define designation_debug(dn) do { } while (false)
500#endif 491#endif
501 492
502static void 493static void
503designation_add(struct designation *dn, struct designator *dr) 494designation_add(struct designation *dn, const char *name, size_t subscript)
504{ 495{
 496 struct designator *dr;
 497
 498 dr = designator_new(name, subscript);
505 499
506 if (dn->dn_head != NULL) { 500 if (dn->dn_head != NULL) {
507 dn->dn_tail->dr_next = dr; 501 dn->dn_tail->dr_next = dr;
508 dn->dn_tail = dr; 502 dn->dn_tail = dr;
509 } else { 503 } else {
510 dn->dn_head = dr; 504 dn->dn_head = dr;
511 dn->dn_tail = dr; 505 dn->dn_tail = dr;
512 } 506 }
513 
514 designation_debug(dn); 
515} 507}
516 508
517/* TODO: add support for array subscripts, not only named members */ 
518/* 509/*
519 * TODO: This function should not be necessary at all. There is no need to 510 * Starting at the type of the current object, resolve the type of the
520 * remove the head of the list. 511 * sub-object by following each designator in the list.
521 */ 512 */
 513static const type_t *
 514designation_look_up(const struct designation *dn, const type_t *tp)
 515{
 516 const struct designator *dr;
 517
 518 for (dr = dn->dn_head; dr != NULL && tp != NULL; dr = dr->dr_next)
 519 tp = designator_look_up(dr, tp);
 520 return tp;
 521}
 522
 523
 524
522static void 525static void
523designation_shift_level(struct designation *dn) 526designation_reset(struct designation *dn)
524{ 527{
525 lint_assert(dn->dn_head != NULL); 528 struct designator *dr, *next;
526 529
527 if (dn->dn_head == dn->dn_tail) { 530 for (dr = dn->dn_head; dr != NULL; dr = next) {
528 designator_free(dn->dn_head); 531 next = dr->dr_next;
529 dn->dn_head = NULL; 532 designator_free(dr);
530 dn->dn_tail = NULL; 
531 } else { 
532 struct designator *head = dn->dn_head; 
533 dn->dn_head = dn->dn_head->dr_next; 
534 designator_free(head); 
535 } 533 }
536 
537 designation_debug(dn); 
538} 534}
539 535
540 536
541static struct brace_level * 537static struct brace_level *
542brace_level_new(type_t *type, type_t *subtype, int remaining, 538brace_level_new(const type_t *tp, struct brace_level *enclosing)
543 struct brace_level *enclosing) 
544{ 539{
545 struct brace_level *bl = xcalloc(1, sizeof(*bl)); 540 struct brace_level *bl;
546 541
547 bl->bl_type = type; 542 bl = xcalloc(1, sizeof(*bl));
548 bl->bl_subtype = subtype; 543 bl->bl_type = tp;
549 bl->bl_remaining = remaining; 
550 bl->bl_enclosing = enclosing; 544 bl->bl_enclosing = enclosing;
 545 if (is_struct_or_union(tp->t_tspec))
 546 bl->bl_next_member = first_named_member(tp);
551 547
552 return bl; 548 return bl;
553} 549}
554 550
555static void 551static void
556brace_level_free(struct brace_level *bl) 552brace_level_free(struct brace_level *bl)
557{ 553{
 554
 555 designation_reset(&bl->bl_designation);
558 free(bl); 556 free(bl);
559} 557}
560 558
561#ifdef DEBUG 559#ifdef DEBUG
562/* 
563 * TODO: only log the top of the stack after each modifying operation 
564 * 
565 * TODO: wrap all write accesses to brace_level in setter functions 
566 */ 
567static void 560static void
568brace_level_debug(const struct brace_level *bl) 561brace_level_debug(const struct brace_level *bl)
569{ 562{
570 if (bl->bl_type != NULL) 
571 debug_printf("type '%s'", type_name(bl->bl_type)); 
572 if (bl->bl_type != NULL && bl->bl_subtype != NULL) 
573 debug_printf(", "); 
574 if (bl->bl_subtype != NULL) 
575 debug_printf("subtype '%s'", type_name(bl->bl_subtype)); 
576 563
577 if (bl->bl_brace) 564 lint_assert(bl->bl_type != NULL);
578 debug_printf(", needs closing brace"); 565 lint_assert(bl->bl_next_member == NULL ||
 566 !is_unnamed(bl->bl_next_member));
 567
 568 debug_printf("type '%s'", type_name(bl->bl_type));
 569
579 if (bl->bl_array_of_unknown_size) 570 if (bl->bl_array_of_unknown_size)
580 debug_printf(", array of unknown size"); 571 debug_printf(", array of unknown size");
581 if (bl->bl_seen_named_member) 
582 debug_printf(", seen named member"); 
583 572
584 const type_t *eff_type = bl->bl_type != NULL 573 if (is_struct_or_union(bl->bl_type->t_tspec) &&
585 ? bl->bl_type : bl->bl_subtype; 574 bl->bl_next_member != NULL)
586 if (eff_type->t_tspec == STRUCT && bl->bl_next_member != NULL) 
587 debug_printf(", next member '%s'", 575 debug_printf(", next member '%s'",
588 bl->bl_next_member->s_name); 576 bl->bl_next_member->s_name);
 577 if (bl->bl_type->t_tspec == ARRAY)
 578 debug_printf(", next array subscript %zu",
 579 bl->bl_array_next_subscript);
589 580
590 debug_printf(", remaining %d\n", bl->bl_remaining); 581 debug_printf("\n");
591} 582}
592#else 583#else
593#define brace_level_debug(bl) do { } while (false) 584#define brace_level_debug(level) do { } while (false)
594#endif 585#endif
595 586
596static void 587static void
597brace_level_assert_struct_or_union(const struct brace_level *bl) 588brace_level_remove_designation(struct brace_level *bl)
598{ 589{
599 lint_assert(is_struct_or_union(bl->bl_type->t_tspec)); 590 struct designator *dr, *next;
600} 
601 591
602static void 592 for (dr = bl->bl_designation.dn_head; dr != NULL; dr = next) {
603brace_level_assert_array(const struct brace_level *bl) 593 next = dr->dr_next;
604{ 594 designator_free(dr);
605 lint_assert(bl->bl_type->t_tspec == ARRAY); 595 }
606} 
607 
608static type_t * 
609brace_level_subtype(struct brace_level *bl) 
610{ 
611 
612 if (bl->bl_subtype != NULL) 
613 return bl->bl_subtype; 
614 596
615 return bl->bl_type; 597 bl->bl_designation.dn_head = NULL;
 598 bl->bl_designation.dn_tail = NULL;
616} 599}
617 600
618static void 
619brace_level_set_array_dimension(struct brace_level *bl, int dim) 
620{ 
621 brace_level_assert_array(bl); 
622 
623 debug_step("setting the array size to %d", dim); 
624 bl->bl_type->t_dim = dim; 
625 debug_indent(); 
626 brace_level_debug(bl); 
627} 
628 601
629static void 602static const type_t *
630brace_level_next_member(struct brace_level *bl) 603brace_level_sub_type_struct_or_union(const struct brace_level *bl)
631{ 604{
632 const sym_t *m; 
633 605
634 brace_level_assert_struct_or_union(bl); 606 if (bl->bl_next_member == NULL) {
635 do { 607 /* too many struct/union initializers */
636 m = bl->bl_next_member = bl->bl_next_member->s_next; 608 error(172);
637 /* XXX: can this assertion be made to fail? */ 609 return NULL;
638 lint_assert(m != NULL); 610 }
639 } while (m->s_bitfield && m->s_name == unnamed); 
640 611
641 debug_indent(); 612 lint_assert(!is_unnamed(bl->bl_next_member));
642 brace_level_debug(bl); 613 return sym_type(bl->bl_next_member);
643} 614}
644 615
645static const sym_t * 616static const type_t *
646brace_level_look_up_member(const struct brace_level *bl, const char *name) 617brace_level_sub_type_array(const struct brace_level *bl)
647{ 618{
648 619
649 brace_level_assert_struct_or_union(bl); 620 if (!bl->bl_type->t_incomplete_array &&
650 return look_up_member(bl->bl_type->t_str->sou_first_member, name); 621 !bl->bl_omitted_braces &&
 622 bl->bl_array_next_subscript >= (size_t)bl->bl_type->t_dim) {
 623 /* too many array initializers, expected %d */
 624 error(173, bl->bl_type->t_dim);
 625 }
 626
 627 return bl->bl_type->t_subt;
651} 628}
652 629
653static sym_t * 630static const type_t *
654brace_level_look_up_first_member_named(struct brace_level *bl, 631brace_level_sub_type_scalar(const struct brace_level *bl)
655 const char *name, int *count) 
656{ 632{
657 sym_t *m; 
658 633
659 for (m = bl->bl_type->t_str->sou_first_member; 634 if (bl->bl_scalar_done) {
660 m != NULL; m = m->s_next) { 635 /* too many initializers */
661 if (is_unnamed_member(m)) 636 error(174);
662 continue; 
663 if (strcmp(m->s_name, name) != 0) 
664 continue; 
665 (*count)++; 
666 break; 
667 } 637 }
668 638
669 return m; 639 return bl->bl_type;
670} 640}
671 641
672static sym_t * 642/* Return the type of the sub-object that is currently being initialized. */
673brace_level_look_up_first_member_unnamed(struct brace_level *bl, int *count) 643static const type_t *
 644brace_level_sub_type(const struct brace_level *bl)
674{ 645{
675 sym_t *m; 
676 646
677 brace_level_assert_struct_or_union(bl); 647 if (bl->bl_designation.dn_head != NULL)
 648 return designation_look_up(&bl->bl_designation, bl->bl_type);
678 649
679 for (m = bl->bl_type->t_str->sou_first_member; 650 switch (bl->bl_type->t_tspec) {
680 m != NULL; m = m->s_next) { 651 case STRUCT:
681 if (is_unnamed_member(m)) 652 case UNION:
682 continue; 653 return brace_level_sub_type_struct_or_union(bl);
683 /* XXX: What is this code for? */ 654 case ARRAY:
684 if (++(*count) == 1) { 655 return brace_level_sub_type_array(bl);
685 bl->bl_next_member = m; 656 default:
686 bl->bl_subtype = m->s_type; 657 return brace_level_sub_type_scalar(bl);
687 } 
688 } 658 }
689 
690 return m; 
691} 659}
692 660
693/* TODO: document me */ 661static void
694/* TODO: think of a better name than 'push' */ 662brace_level_apply_designation(struct brace_level *bl)
695static bool 
696brace_level_push_array(struct brace_level *bl) 
697{ 663{
698 brace_level_assert_array(bl); 664 const struct designator *dr = bl->bl_designation.dn_head;
699 665
700 if (bl->bl_enclosing->bl_seen_named_member) { 666 if (dr == NULL)
701 bl->bl_brace = true; 667 return;
702 debug_step("ARRAY, seen named member, needs closing brace"); 
703 } 
704 668
705 if (is_incomplete(bl->bl_type) && 669 designation_debug(&bl->bl_designation);
706 bl->bl_enclosing->bl_enclosing != NULL) { 
707 /* initialization of an incomplete type */ 
708 error(175); 
709 return false; 
710 } 
711 670
712 bl->bl_subtype = bl->bl_type->t_subt; 671 switch (bl->bl_type->t_tspec) {
713 bl->bl_array_of_unknown_size = is_incomplete(bl->bl_type); 672 case STRUCT:
714 bl->bl_remaining = bl->bl_type->t_dim; 673 case UNION:
715 debug_step("type '%s' remaining %d", 674 if (dr->dr_name == NULL)
716 type_name(bl->bl_type), bl->bl_remaining); 675 return; /* error, silently ignored */
717 return true; 676 bl->bl_next_member = look_up_member(bl->bl_type, dr->dr_name);
 677 break;
 678 case ARRAY:
 679 if (dr->dr_name != NULL)
 680 return; /* error, silently ignored */
 681 bl->bl_array_next_subscript = dr->dr_subscript;
 682 break;
 683 default:
 684 break; /* error, silently ignored */
 685 }
718} 686}
719 687
720/* 688/*
721 * If the removed element was a structure member, we must go 689 * After initializing a sub-object, advance to the next sub-object.
722 * to the next structure member. 
723 * 
724 * XXX: Nothing should ever be "removed" at this point. 
725 * 690 *
726 * TODO: think of a better name than 'pop' 691 * C99 6.7.8p17
727 */ 692 */
728static void 693static void
729brace_level_pop_item_unnamed(struct brace_level *bl) 694brace_level_advance(struct brace_level *bl)
730{ 695{
731 if (bl->bl_remaining > 0 && bl->bl_type->t_tspec == STRUCT && 
732 !bl->bl_seen_named_member) { 
733 brace_level_next_member(bl); 
734 bl->bl_subtype = bl->bl_next_member->s_type; 
735 } 
736} 
737 696
738static bool 697 switch (bl->bl_type->t_tspec) {
739brace_level_check_too_many_initializers(struct brace_level *bl) 698 case STRUCT:
740{ 699 lint_assert(bl->bl_next_member != NULL);
741 if (bl->bl_remaining > 0) 700 bl->bl_next_member = skip_unnamed(bl->bl_next_member->s_next);
742 return true; 701 break;
743 /* 702 case UNION:
744 * FIXME: even with named members, there can be too many initializers 703 bl->bl_next_member = NULL;
745 */ 704 break;
746 if (bl->bl_array_of_unknown_size || bl->bl_seen_named_member) 705 case ARRAY:
747 return true; 706 bl->bl_array_next_subscript++;
748 707 break;
749 tspec_t t = bl->bl_type->t_tspec; 708 default:
750 if (t == ARRAY) { 709 bl->bl_scalar_done = true;
751 /* too many array initializers, expected %d */ 710 break;
752 error(173, bl->bl_type->t_dim); 
753 } else if (is_struct_or_union(t)) { 
754 /* too many struct/union initializers */ 
755 error(172); 
756 } else { 
757 /* too many initializers */ 
758 error(174); 
759 } 711 }
760 return false; 
761} 
762 
763/* Extend an array of unknown size by one element */ 
764static void 
765brace_level_extend_if_array_of_unknown_size(struct brace_level *bl) 
766{ 
767 
768 if (bl->bl_remaining != 0) 
769 return; 
770 /* 
771 * XXX: According to the function name, there should be a 'return' if 
772 * bl_array_of_unknown_size is false. There's probably a test missing 
773 * for that case. 
774 */ 
775 
776 /* 
777 * The only place where an incomplete array may appear is at the 
778 * outermost aggregate bl of the object to be initialized. 
779 */ 
780 lint_assert(bl->bl_enclosing->bl_enclosing == NULL); 
781 lint_assert(bl->bl_type->t_tspec == ARRAY); 
782 
783 debug_step("extending array of unknown size '%s'", 
784 type_name(bl->bl_type)); 
785 bl->bl_remaining = 1; 
786 bl->bl_type->t_dim++; 
787 setcomplete(bl->bl_type, true); 
788 
789 debug_step("extended type is '%s'", type_name(bl->bl_type)); 
790} 712}
791 713
792 714
793static struct initialization * 715static struct initialization *
794initialization_new(sym_t *sym) 716initialization_new(sym_t *sym)
795{ 717{
796 struct initialization *in = xcalloc(1, sizeof(*in)); 718 struct initialization *in;
797 719
 720 in = xcalloc(1, sizeof(*in));
798 in->in_sym = sym; 721 in->in_sym = sym;
799 722
800 return in; 723 return in;
801} 724}
802 725
803static void 726static void
804initialization_free(struct initialization *in) 727initialization_free(struct initialization *in)
805{ 728{
806 struct brace_level *bl, *next; 729 struct brace_level *bl, *next;
807 730
808 for (bl = in->in_brace_level; bl != NULL; bl = next) { 731 for (bl = in->in_brace_level; bl != NULL; bl = next) {
809 next = bl->bl_enclosing; 732 next = bl->bl_enclosing;
810 brace_level_free(bl); 733 brace_level_free(bl);
811 } 734 }
812 735
813 free(in); 736 free(in);
814} 737}
815 738
816#ifdef DEBUG 739#ifdef DEBUG
817/* 
818 * TODO: only call debug_initstack after each push/pop. 
819 */ 
820static void 740static void
821initialization_debug(const struct initialization *in) 741initialization_debug(const struct initialization *in)
822{ 742{
 743 size_t i;
 744 const struct brace_level *bl;
 745
823 if (in->in_brace_level == NULL) { 746 if (in->in_brace_level == NULL) {
824 debug_step("no brace level in the current initialization"); 747 debug_step("no brace level");
825 return; 748 return;
826 } 749 }
827 750
828 size_t i = 0; 751 i = 0;
829 for (const struct brace_level *bl = in->in_brace_level; 752 for (bl = in->in_brace_level; bl != NULL; bl = bl->bl_enclosing) {
830 bl != NULL; bl = bl->bl_enclosing) { 
831 debug_indent(); 753 debug_indent();
832 debug_printf("brace level %zu: ", i); 754 debug_printf("brace level %zu: ", i);
833 brace_level_debug(bl); 755 brace_level_debug(bl);
834 i++; 756 i++;
835 } 757 }
836} 758}
837#else 759#else
838#define initialization_debug(in) do { } while (false) 760#define initialization_debug(in) do { } while (false)
839#endif 761#endif
840 762
841/* 763/*
842 * Initialize the initialization stack by putting an entry for the object 764 * Return the type of the object or sub-object that is currently being
843 * which is to be initialized on it. 765 * initialized.
844 * 
845 * TODO: merge into initialization_new if possible 
846 */ 766 */
847static void 767static const type_t *
848initialization_init(struct initialization *in) 768initialization_sub_type(struct initialization *in)
849{ 
850 if (in->in_err) 
851 return; 
852 
853 debug_enter(); 
854 
855 /* 
856 * If the type which is to be initialized is an incomplete array, 
857 * it must be duplicated. 
858 */ 
859 if (in->in_sym->s_type->t_tspec == ARRAY && is_incomplete(in->in_sym->s_type)) 
860 in->in_sym->s_type = duptyp(in->in_sym->s_type); 
861 /* TODO: does 'duptyp' create a memory leak? */ 
862 
863 in->in_brace_level = brace_level_new(NULL, in->in_sym->s_type, 1, NULL); 
864 
865 initialization_debug(in); 
866 debug_leave(); 
867} 
868 
869static void 
870initialization_set_error(struct initialization *in) 
871{ 769{
872 in->in_err = true; 770 const type_t *tp;
873} 
874 771
875/* TODO: document me */ 772 tp = in->in_brace_level != NULL
876/* TODO: think of a better name than 'push' */ 773 ? brace_level_sub_type(in->in_brace_level)
877static bool 774 : in->in_sym->s_type;
878initialization_push_struct_or_union(struct initialization *in) 775 if (tp == NULL)
879{ 776 in->in_err = true;
880 struct brace_level *bl = in->in_brace_level; 777 return tp;
881 int cnt; 
882 sym_t *m; 
883 
884 if (is_incomplete(bl->bl_type)) { 
885 /* initialization of an incomplete type */ 
886 error(175); 
887 initialization_set_error(in); 
888 return false; 
889 } 
890 
891 cnt = 0; 
892 designation_debug(&in->in_designation); 
893 debug_step("lookup for '%s'%s", 
894 type_name(bl->bl_type), 
895 bl->bl_seen_named_member ? ", seen named member" : ""); 
896 
897 if (in->in_designation.dn_head != NULL) 
898 m = brace_level_look_up_first_member_named(bl, 
899 in->in_designation.dn_head->dr_name, &cnt); 
900 else 
901 m = brace_level_look_up_first_member_unnamed(bl, &cnt); 
902 
903 if (in->in_designation.dn_head != NULL) { 
904 if (m == NULL) { 
905 debug_step("pop struct"); 
906 return true; 
907 } 
908 bl->bl_next_member = m; 
909 bl->bl_subtype = m->s_type; 
910 bl->bl_seen_named_member = true; 
911 debug_step("named member '%s'", 
912 in->in_designation.dn_head->dr_name); 
913 designation_shift_level(&in->in_designation); 
914 cnt = bl->bl_type->t_tspec == STRUCT ? 2 : 1; 
915 } 
916 bl->bl_brace = true; 
917 debug_step("unnamed element with type '%s'%s", 
918 type_name( 
919 bl->bl_type != NULL ? bl->bl_type : bl->bl_subtype), 
920 bl->bl_brace ? ", needs closing brace" : ""); 
921 if (cnt == 0) { 
922 /* cannot init. struct/union with no named member */ 
923 error(179); 
924 initialization_set_error(in); 
925 return false; 
926 } 
927 bl->bl_remaining = bl->bl_type->t_tspec == STRUCT ? cnt : 1; 
928 return false; 
929} 778}
930 779
931static void 780static void
932initialization_end_brace_level(struct initialization *in) 781initialization_begin_brace_level(struct initialization *in)
933{ 782{
934 struct brace_level *bl = in->in_brace_level; 783 const type_t *tp;
935 in->in_brace_level = bl->bl_enclosing; 
936 brace_level_free(bl); 
937} 
938 784
939/* TODO: document me */ 785 if (in->in_err)
940/* TODO: think of a better name than 'push' */ 786 return;
941static void 
942initialization_push(struct initialization *in) 
943{ 
944 struct brace_level *bl; 
945 787
946 debug_enter(); 788 debug_enter();
947 789
948 brace_level_extend_if_array_of_unknown_size(in->in_brace_level); 790 tp = initialization_sub_type(in);
949 791 if (tp == NULL) {
950 bl = in->in_brace_level; 792 in->in_err = true;
951 lint_assert(bl->bl_remaining > 0); 793 goto done;
 794 }
952 795
953 in->in_brace_level = brace_level_new(brace_level_subtype(bl), NULL, 0, 796 if (tflag && in->in_brace_level == NULL)
954 bl); 797 check_no_auto_aggregate(in->in_sym);
955 lint_assert(in->in_brace_level->bl_type != NULL); 
956 lint_assert(in->in_brace_level->bl_type->t_tspec != FUNC); 
957 798
958again: 799 if (tflag && tp->t_tspec == UNION) {
959 bl = in->in_brace_level; 800 /* initialization of union is illegal in traditional C */
 801 warning(238);
 802 }
960 803
961 debug_step("expecting type '%s'", type_name(bl->bl_type)); 804 if (tp->t_tspec == STRUCT && tp->t_str->sou_incomplete) {
962 lint_assert(bl->bl_type != NULL); 805 /* TODO: add type information */
963 switch (bl->bl_type->t_tspec) { 806 /* initialization of an incomplete type */
964 case ARRAY: 807 error(175);
965 if (in->in_designation.dn_head != NULL) { 808 in->in_err = true;
966 debug_step("pop array, named member '%s'%s", 809 goto done;
967 in->in_designation.dn_head->dr_name, 810 }
968 bl->bl_brace ? ", needs closing brace" : ""); 
969 goto pop; 
970 } 
971 811
972 if (!brace_level_push_array(bl)) 812 if (in->in_brace_level != NULL)
973 initialization_set_error(in); 813 brace_level_apply_designation(in->in_brace_level);
974 break; 
975 814
976 case UNION: 815 in->in_brace_level = brace_level_new(tp, in->in_brace_level);
977 if (tflag) 
978 /* initialization of union is illegal in trad. C */ 
979 warning(238); 
980 /* FALLTHROUGH */ 
981 case STRUCT: 
982 if (initialization_push_struct_or_union(in)) 
983 goto pop; 
984 break; 
985 default: 
986 if (in->in_designation.dn_head != NULL) { 
987 debug_step("pop scalar"); 
988 pop: 
989 initialization_end_brace_level(in); 
990 goto again; 
991 } 
992 /* The initialization stack now expects a single scalar. */ 
993 bl->bl_remaining = 1; 
994 break; 
995 } 
996 816
 817done:
997 initialization_debug(in); 818 initialization_debug(in);
998 debug_leave(); 819 debug_leave();
999} 820}
1000 821
1001/* TODO: document me */ 822/* C99 6.7.8p22 */
1002static void 823static void
1003initialization_pop_item_named(struct initialization *in, const char *name) 824initialization_set_size_of_unknown_array(struct initialization *in)
1004{ 825{
1005 struct brace_level *bl = in->in_brace_level; 
1006 const sym_t *m; 
1007 
1008 /* 
1009 * TODO: fix wording of the debug message; this doesn't seem to be 
1010 * related to initializing the named member. 
1011 */ 
1012 debug_step("initializing named member '%s'", name); 
1013 826
1014 if (!is_struct_or_union(bl->bl_type->t_tspec)) { 827 if (in->in_sym->s_type->t_incomplete_array &&
1015 /* syntax error '%s' */ 828 in->in_brace_level->bl_enclosing == NULL)
1016 error(249, "named member must only be used with struct/union"); 829 update_type_of_array_of_unknown_size(in->in_sym,
1017 initialization_set_error(in); 830 in->in_brace_level->bl_array_next_subscript);
1018 return; 
1019 } 
1020 
1021 m = brace_level_look_up_member(bl, name); 
1022 if (m == NULL) { 
1023 /* TODO: add type information to the message */ 
1024 /* undefined struct/union member: %s */ 
1025 error(101, name); 
1026 
1027 designation_shift_level(&in->in_designation); 
1028 bl->bl_seen_named_member = true; 
1029 return; 
1030 } 
1031 
1032 debug_step("found matching member"); 
1033 bl->bl_subtype = m->s_type; 
1034 /* XXX: why ++? */ 
1035 bl->bl_remaining++; 
1036 /* XXX: why is bl_seen_named_member not set? */ 
1037 designation_shift_level(&in->in_designation); 
1038} 831}
1039 832
1040/* TODO: think of a better name than 'pop' */ 
1041static void 833static void
1042initialization_pop_item(struct initialization *in) 834initialization_end_brace_level(struct initialization *in)
1043{ 835{
1044 struct brace_level *bl; 836 struct brace_level *bl;
1045 837
 838 if (in->in_err)
 839 return;
 840
1046 debug_enter(); 841 debug_enter();
1047 842
1048 bl = in->in_brace_level; 843 initialization_set_size_of_unknown_array(in);
1049 debug_indent(); 
1050 debug_printf("popping: "); 
1051 brace_level_debug(bl); 
1052 844
 845 bl = in->in_brace_level;
1053 in->in_brace_level = bl->bl_enclosing; 846 in->in_brace_level = bl->bl_enclosing;
1054 brace_level_free(bl); 847 brace_level_free(bl);
1055 bl = in->in_brace_level; 
1056 lint_assert(bl != NULL); 
1057 
1058 bl->bl_remaining--; 
1059 lint_assert(bl->bl_remaining >= 0); 
1060 debug_step("%d elements remaining", bl->bl_remaining); 
1061 
1062 if (in->in_designation.dn_head != NULL && in->in_designation.dn_head->dr_name != NULL) 
1063 initialization_pop_item_named(in, in->in_designation.dn_head->dr_name); 
1064 else 
1065 brace_level_pop_item_unnamed(bl); 
1066 
1067 initialization_debug(in); 
1068 debug_leave(); 
1069} 
1070 
1071/* 
1072 * Take all entries which cannot be used for further initializers from the 
1073 * stack, but do this only if they do not require a closing brace. 
1074 */ 
1075/* TODO: think of a better name than 'pop' */ 
1076static void 
1077initialization_pop_nobrace(struct initialization *in) 
1078{ 
1079 
1080 debug_enter(); 
1081 while (!in->in_brace_level->bl_brace && 
1082 in->in_brace_level->bl_remaining == 0 && 
1083 !in->in_brace_level->bl_array_of_unknown_size) 
1084 initialization_pop_item(in); 
1085 debug_leave(); 
1086} 
1087 
1088/* 
1089 * Process a '{' in an initializer by starting the initialization of the 
1090 * nested data structure, with bl_type being the bl_subtype of the outer 
1091 * initialization level. 
1092 */ 
1093static void 
1094initialization_next_brace(struct initialization *in) 
1095{ 
1096 848
1097 debug_enter(); 849 if (in->in_brace_level != NULL) {
1098 initialization_debug(in); 850 brace_level_advance(in->in_brace_level);
1099 851 brace_level_remove_designation(in->in_brace_level);
1100 if (!in->in_err && 
1101 !brace_level_check_too_many_initializers(in->in_brace_level)) 
1102 initialization_set_error(in); 
1103 
1104 if (!in->in_err) 
1105 initialization_push(in); 
1106 
1107 if (!in->in_err) { 
1108 in->in_brace_level->bl_brace = true; 
1109 designation_debug(&in->in_designation); 
1110 if (in->in_brace_level->bl_type != NULL) 
1111 debug_step("expecting type '%s'", 
1112 type_name(in->in_brace_level->bl_type)); 
1113 } 852 }
1114 853
1115 initialization_debug(in); 854 initialization_debug(in);
1116 debug_leave(); 855 debug_leave();
1117} 856}
1118 857
1119static void 858static void
1120check_no_auto_aggregate(scl_t sclass, const struct brace_level *bl) 859initialization_add_designator(struct initialization *in,
 860 const char *name, size_t subscript)
1121{ 861{
1122 if (!tflag) 
1123 return; 
1124 if (!(sclass == AUTO || sclass == REG)) 
1125 return; 
1126 if (!(bl->bl_enclosing == NULL)) 
1127 return; 
1128 if (is_scalar(bl->bl_subtype->t_tspec)) 
1129 return; 
1130 862
1131 /* no automatic aggregate initialization in trad. C */ 
1132 warning(188); 
1133} 
1134 
1135static void 
1136initialization_lbrace(struct initialization *in) 
1137{ 
1138 if (in->in_err) 863 if (in->in_err)
1139 return; 864 return;
1140 865
1141 debug_enter(); 866 lint_assert(in->in_brace_level != NULL);
1142 initialization_debug(in); 867 designation_add(&in->in_brace_level->bl_designation, name, subscript);
1143 
1144 check_no_auto_aggregate(in->in_sym->s_scl, in->in_brace_level); 
1145 
1146 /* 
1147 * Remove all entries which cannot be used for further initializers 
1148 * and do not expect a closing brace. 
1149 */ 
1150 initialization_pop_nobrace(in); 
1151 
1152 initialization_next_brace(in); 
1153 
1154 initialization_debug(in); 
1155 debug_leave(); 
1156} 868}
1157 869
1158/* 
1159 * Process a '}' in an initializer by finishing the current level of the 
1160 * initialization stack. 
1161 * 
1162 * Take all entries, including the first which requires a closing brace, 
1163 * from the stack. 
1164 */ 
1165static void 870static void
1166initialization_rbrace(struct initialization *in) 871initialization_remove_designation(struct initialization *in)
1167{ 872{
1168 bool brace; 
1169 
1170 if (in->in_err) 
1171 return; 
1172 873
1173 debug_enter(); 874 if (in->in_brace_level != NULL)
1174 do { 875 brace_level_remove_designation(in->in_brace_level);
1175 brace = in->in_brace_level->bl_brace; 
1176 /* TODO: improve wording of the debug message */ 
1177 debug_step("loop brace=%d", brace); 
1178 initialization_pop_item(in); 
1179 } while (!brace); 
1180 initialization_debug(in); 
1181 debug_leave(); 
1182} 876}
1183 877
1184/* 878/*
1185 * A sub-object of an array is initialized using a designator. This does not 879 * An object with automatic storage duration that has a single initializer
1186 * have to be an array element directly, it can also be used to initialize 880 * expression without braces and is not an array is initialized by delegating
1187 * only a sub-object of the array element. 881 * to the ASSIGN operator.
1188 * 
1189 * C99 example: struct { int member[4]; } var = { [2] = 12345 }; 
1190 * 
1191 * GNU example: struct { int member[4]; } var = { [1 ... 3] = 12345 }; 
1192 * 
1193 * TODO: test the following initialization with an outer and an inner type: 
1194 * 
1195 * .deeply[0].nested = { 
1196 * .deeply[1].nested = { 
1197 * 12345, 
1198 * }, 
1199 * } 
1200 */ 882 */
1201static void 883static bool
1202initialization_add_designator_subscript(struct initialization *in, 884initialization_expr_using_assign(struct initialization *in, tnode_t *rn)
1203 range_t range) 
1204{ 885{
1205 struct brace_level *bl; 886 tnode_t *ln, *tn;
1206 887
1207 debug_enter(); 888 if (!has_automatic_storage_duration(in->in_sym))
1208 if (range.lo == range.hi) 889 return false;
1209 debug_step("subscript is %zu", range.hi); 890 if (in->in_brace_level != NULL)
1210 else 891 return false;
1211 debug_step("subscript range is %zu ... %zu", 892 if (in->in_sym->s_type->t_tspec == ARRAY)
1212 range.lo, range.hi); 893 return false;
1213 894
1214 /* XXX: This call is wrong here, it must be somewhere else. */ 895 debug_step("handing over to ASSIGN");
1215 initialization_pop_nobrace(in); 
1216 896
1217 bl = in->in_brace_level; 897 ln = new_name_node(in->in_sym, 0);
1218 if (bl->bl_array_of_unknown_size) { 898 ln->tn_type = tduptyp(ln->tn_type);
1219 /* No +1 here, extend_if_array_of_unknown_size will add it. */ 899 ln->tn_type->t_const = false;
1220 int auto_dim = (int)range.hi; 
1221 if (auto_dim > bl->bl_type->t_dim) 
1222 brace_level_set_array_dimension(bl, auto_dim); 
1223 } 
1224 900
1225 debug_leave(); 901 tn = build(ASSIGN, ln, rn);
 902 expr(tn, false, false, false, false);
 903
 904 return true;
1226} 905}
1227 906
1228/* Initialize a character array or wchar_t array with a string literal. */ 907/* Initialize a character array or wchar_t array with a string literal. */
1229static bool 908static bool
1230initialization_init_array_using_string(struct initialization *in, tnode_t *tn) 909initialization_init_array_using_string(struct initialization *in, tnode_t *tn)
1231{ 910{
1232 struct brace_level *bl; 911 struct brace_level *bl;
 912 const type_t *tp;
1233 strg_t *strg; 913 strg_t *strg;
1234 914
1235 if (tn->tn_op != STRING) 915 if (tn->tn_op != STRING)
1236 return false; 916 return false;
1237 917
1238 debug_enter(); 
1239 
1240 bl = in->in_brace_level; 918 bl = in->in_brace_level;
 919 tp = initialization_sub_type(in);
1241 strg = tn->tn_string; 920 strg = tn->tn_string;
1242 921
1243 /* 922 if (!is_string_array(tp, strg->st_tspec))
1244 * Check if we have an array type which can be initialized by 923 return false;
1245 * the string. 924 if (bl != NULL && tp->t_tspec != ARRAY &&
1246 */ 925 bl->bl_array_next_subscript != 0)
1247 if (is_string_array(bl->bl_subtype, strg->st_tspec)) { 926 return false;
1248 debug_step("subtype is an array"); 
1249 
1250 /* Put the array at top of stack */ 
1251 initialization_push(in); 
1252 bl = in->in_brace_level; 
1253 
1254 } else if (is_string_array(bl->bl_type, strg->st_tspec)) { 
1255 debug_step("type is an array"); 
1256 
1257 /* 
1258 * If the array is already partly initialized, we are 
1259 * wrong here. 
1260 */ 
1261 if (bl->bl_remaining != bl->bl_type->t_dim) 
1262 goto nope; 
1263 } else 
1264 goto nope; 
1265 
1266 if (bl->bl_array_of_unknown_size) { 
1267 bl->bl_array_of_unknown_size = false; 
1268 bl->bl_type->t_dim = (int)(strg->st_len + 1); 
1269 setcomplete(bl->bl_type, true); 
1270 } else { 
1271 /* 
1272 * TODO: check for buffer overflow in the object to be 
1273 * initialized 
1274 */ 
1275 /* XXX: double-check for off-by-one error */ 
1276 if (bl->bl_type->t_dim < (int)strg->st_len) { 
1277 /* non-null byte ignored in string initializer */ 
1278 warning(187); 
1279 } 
1280 927
1281 /* 928 if (bl != NULL && tp->t_dim < (int)strg->st_len) {
1282 * TODO: C99 6.7.8p14 allows a string literal to be enclosed 929 /* non-null byte ignored in string initializer */
1283 * in optional redundant braces, just like scalars. Add tests 930 warning(187);
1284 * for this. 
1285 */ 
1286 } 931 }
1287 932
1288 /* In every case the array is initialized completely. */ 933 if (tp == in->in_sym->s_type && tp->t_incomplete_array) {
1289 bl->bl_remaining = 0; 934 if (bl != NULL) {
 935 bl->bl_array_next_subscript = strg->st_len + 1;
 936 /* see initialization_set_size_of_unknown_array */
 937 } else
 938 update_type_of_array_of_unknown_size(in->in_sym,
 939 strg->st_len + 1);
 940 }
1290 941
1291 initialization_debug(in); 
1292 debug_leave(); 
1293 return true; 942 return true;
1294nope: 
1295 debug_leave(); 
1296 return false; 
1297} 943}
1298 944
1299/* 945/*
1300 * Initialize a non-array object with automatic storage duration and only a 946 * Initialize a single sub-object as part of the currently ongoing
1301 * single initializer expression without braces by delegating to ASSIGN. 947 * initialization.
1302 */ 948 */
1303static bool 949static void
1304initialization_init_using_assign(struct initialization *in, tnode_t *rn) 950initialization_expr(struct initialization *in, tnode_t *tn)
1305{ 951{
1306 tnode_t *ln, *tn; 952 const type_t *tp;
1307 
1308 if (in->in_sym->s_type->t_tspec == ARRAY) 
1309 return false; 
1310 if (in->in_brace_level->bl_enclosing != NULL) 
1311 return false; 
1312 953
1313 debug_step("handing over to ASSIGN"); 954 if (in->in_err)
 955 return;
1314 956
1315 ln = new_name_node(in->in_sym, 0); 957 if (in->in_brace_level != NULL &&
1316 ln->tn_type = tduptyp(ln->tn_type); 958 in->in_brace_level->bl_omitted_braces)
1317 ln->tn_type->t_const = false; 959 return;
1318 960
1319 tn = build(ASSIGN, ln, rn); 961 debug_enter();
1320 expr(tn, false, false, false, false); 
1321 962
1322 /* XXX: why not clean up the initstack here already? */ 963 if (tn == NULL)
1323 return true; 964 goto advance;
1324} 965 if (initialization_expr_using_assign(in, tn))
 966 goto done;
 967 if (initialization_init_array_using_string(in, tn))
 968 goto advance;
1325 969
1326/* TODO: document me, or think of a better name */ 970 if (in->in_brace_level != NULL)
1327static void 971 brace_level_apply_designation(in->in_brace_level);
1328initialization_next_nobrace(struct initialization *in, tnode_t *tn) 972 tp = initialization_sub_type(in);
1329{ 973 if (tp == NULL)
1330 debug_enter(); 974 goto done;
1331 975
1332 if (in->in_brace_level->bl_type == NULL && 976 if (in->in_brace_level == NULL && !is_scalar(tp->t_tspec)) {
1333 !is_scalar(in->in_brace_level->bl_subtype->t_tspec)) { 
1334 /* {}-enclosed initializer required */ 977 /* {}-enclosed initializer required */
1335 error(181); 978 error(181);
1336 /* XXX: maybe set initerr here */ 979 goto done;
1337 } 980 }
1338 981
1339 if (!in->in_err && 982 /*
1340 !brace_level_check_too_many_initializers(in->in_brace_level)) 983 * Hack to accept initializations with omitted braces, see
1341 initialization_set_error(in); 984 * c99_6_7_8_p28_example5 in test d_c99_init.c. Since both GCC and
1342 985 * Clang already warn about this at level -Wall, there is no point
1343 while (!in->in_err) { 986 * in letting lint check this again.
1344 struct brace_level *bl = in->in_brace_level; 987 */
1345 988 if (is_scalar(tn->tn_type->t_tspec) &&
1346 if (tn->tn_type->t_tspec == STRUCT && 989 tp->t_tspec == ARRAY &&
1347 bl->bl_type == tn->tn_type && 990 in->in_brace_level != NULL) {
1348 bl->bl_enclosing != NULL && 991 in->in_brace_level->bl_omitted_braces = true;
1349 bl->bl_enclosing->bl_enclosing != NULL) { 992 goto done;
1350 bl->bl_brace = false; 
1351 bl->bl_remaining = 1; /* the struct itself */ 
1352 break; 
1353 } 
1354 
1355 if (bl->bl_type != NULL && 
1356 is_scalar(bl->bl_type->t_tspec)) 
1357 break; 
1358 initialization_push(in); 
1359 } 993 }
1360 994
 995 debug_step("expecting '%s', expression has '%s'",
 996 type_name(tp), type_name(tn->tn_type));
 997 check_init_expr(tp, in->in_sym, tn);
 998
 999advance:
 1000 if (in->in_brace_level != NULL)
 1001 brace_level_advance(in->in_brace_level);
 1002done:
 1003 initialization_remove_designation(in);
1361 initialization_debug(in); 1004 initialization_debug(in);
1362 debug_leave(); 1005 debug_leave();
1363} 1006}
1364 1007
1365static void 
1366initialization_expr(struct initialization *in, tnode_t *tn) 
1367{ 
1368 
1369 debug_enter(); 
1370 initialization_debug(in); 
1371 designation_debug(&in->in_designation); 
1372 debug_step("expr:"); 
1373 debug_node(tn, debug_ind + 1); 
1374 1008
1375 if (in->in_err || tn == NULL) 1009static struct initialization *init;
1376 goto done; 
1377 
1378 if (has_automatic_storage_duration(in->in_sym) && 
1379 initialization_init_using_assign(in, tn)) 
1380 goto done; 
1381 
1382 initialization_pop_nobrace(in); 
1383 
1384 if (initialization_init_array_using_string(in, tn)) { 
1385 debug_step("after initializing the string:"); 
1386 goto done_debug; 
1387 } 
1388 
1389 initialization_next_nobrace(in, tn); 
1390 if (in->in_err || tn == NULL) 
1391 goto done_debug; 
1392 
1393 /* Using initsym here is better than nothing. */ 
1394 check_init_expr(in->in_brace_level->bl_type, in->in_sym, tn); 
1395 
1396 in->in_brace_level->bl_remaining--; 
1397 debug_step("%d elements remaining", in->in_brace_level->bl_remaining); 
1398 
1399done_debug: 
1400 initialization_debug(in); 
1401 1010
1402done: 
1403 while (in->in_designation.dn_head != NULL) 
1404 designation_shift_level(&in->in_designation); 
1405 
1406 debug_leave(); 
1407} 
1408 1011
1409static struct initialization * 1012static struct initialization *
1410current_init(void) 1013current_init(void)
1411{ 1014{
1412 1015
1413 lint_assert(init != NULL); 1016 lint_assert(init != NULL);
1414 return init; 1017 return init;
1415} 1018}
1416 1019
1417bool * 
1418current_initerr(void) 
1419{ 
1420 
1421 return &current_init()->in_err; 
1422} 
1423 
1424sym_t ** 1020sym_t **
1425current_initsym(void) 1021current_initsym(void)
1426{ 1022{
1427 1023
1428 return &current_init()->in_sym; 1024 return &current_init()->in_sym;
1429} 1025}
1430 1026
1431void 1027void
1432begin_initialization(sym_t *sym) 1028begin_initialization(sym_t *sym)
1433{ 1029{
1434 struct initialization *in; 1030 struct initialization *in;
1435 1031
1436 debug_step("begin initialization of '%s'", type_name(sym->s_type)); 1032 debug_step("begin initialization of '%s'", type_name(sym->s_type));
 1033#ifdef DEBUG
 1034 debug_indentation++;
 1035#endif
 1036
1437 in = initialization_new(sym); 1037 in = initialization_new(sym);
1438 in->in_next = init; 1038 in->in_enclosing = init;
1439 init = in; 1039 init = in;
1440} 1040}
1441 1041
1442void 1042void
1443end_initialization(void) 1043end_initialization(void)
1444{ 1044{
1445 struct initialization *in; 1045 struct initialization *in;
1446 1046
1447 in = init; 1047 in = init;
1448 init = init->in_next; 1048 init = in->in_enclosing;
1449 initialization_free(in); 1049 initialization_free(in);
 1050
 1051#ifdef DEBUG
 1052 debug_indentation--;
 1053#endif
1450 debug_step("end initialization"); 1054 debug_step("end initialization");
1451} 1055}
1452 1056
1453void 1057void
1454add_designator_member(sbuf_t *sb) 1058add_designator_member(sbuf_t *sb)
1455{ 1059{
1456 1060
1457 designation_add(&current_init()->in_designation, 1061 initialization_add_designator(current_init(), sb->sb_name, 0);
1458 designator_new(sb->sb_name)); 
1459} 1062}
1460 1063
1461void 1064void
1462add_designator_subscript(range_t range) 1065add_designator_subscript(range_t range)
1463{ 1066{
1464 1067
1465 initialization_add_designator_subscript(current_init(), range); 1068 initialization_add_designator(current_init(), NULL, range.hi);
1466} 
1467 
1468void 
1469initstack_init(void) 
1470{ 
1471 
1472 initialization_init(current_init()); 
1473} 1069}
1474 1070
1475void 1071void
1476init_lbrace(void) 1072init_lbrace(void)
1477{ 1073{
1478 1074
1479 initialization_lbrace(current_init()); 1075 initialization_begin_brace_level(current_init());
1480} 1076}
1481 1077
1482void 1078void
1483init_using_expr(tnode_t *tn) 1079init_expr(tnode_t *tn)
1484{ 1080{
1485 1081
1486 initialization_expr(current_init(), tn); 1082 initialization_expr(current_init(), tn);
1487} 1083}
1488 1084
1489void 1085void
1490init_rbrace(void) 1086init_rbrace(void)
1491{ 1087{
1492 1088
1493 initialization_rbrace(current_init()); 1089 initialization_end_brace_level(current_init());
1494} 1090}