init.c revision 1.70 1 /* $NetBSD: init.c,v 1.70 2021/02/20 16:34:57 rillig Exp $ */
2
3 /*
4 * Copyright (c) 1994, 1995 Jochen Pohl
5 * All Rights Reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Jochen Pohl for
18 * The NetBSD Project.
19 * 4. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * 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 * 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 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 #if HAVE_NBTOOL_CONFIG_H
35 #include "nbtool_config.h"
36 #endif
37
38 #include <sys/cdefs.h>
39 #if defined(__RCSID) && !defined(lint)
40 __RCSID("$NetBSD: init.c,v 1.70 2021/02/20 16:34:57 rillig Exp $");
41 #endif
42
43 #include <stdlib.h>
44 #include <string.h>
45
46 #include "lint1.h"
47
48
49 /*
50 * Type of stack which is used for initialisation of aggregate types.
51 *
52 * XXX: Since C99, a stack is an inappropriate data structure for modelling
53 * an initialization, since the designators don't have to be listed in a
54 * particular order and can designate parts of sub-objects. The member names
55 * of non-leaf structs may thus appear repeatedly, as demonstrated in
56 * d_init_pop_member.c.
57 *
58 * XXX: During initialization, there may be members of the top-level struct
59 * that are partially initialized. The simple i_remaining cannot model this
60 * appropriately.
61 *
62 * See C99 6.7.8, which spans 6 pages full of tricky details and carefully
63 * selected examples.
64 */
65 typedef struct istk {
66 type_t *i_type; /* type of initialisation */
67 type_t *i_subt; /* type of next level */
68 bool i_brace : 1; /* need } for pop */
69 bool i_nolimit : 1; /* incomplete array type */
70 bool i_namedmem : 1; /* has c9x named members */
71 sym_t *i_mem; /* next structure member */
72 int i_remaining; /* # of remaining elements */
73 struct istk *i_next; /* previous level */
74 } istk_t;
75
76 /*
77 * The names for a nested C99 initialization designator, in a circular list.
78 *
79 * Example:
80 * struct stat st = {
81 * .st_size = 123,
82 * .st_mtim.tv_sec = 45,
83 * .st_mtim.tv_nsec
84 * };
85 *
86 * During initialization, this list first contains ["st_size"], then
87 * ["st_mtim", "tv_sec"], then ["st_mtim", "tv_nsec"].
88 */
89 typedef struct namlist {
90 const char *n_name;
91 struct namlist *n_prev;
92 struct namlist *n_next;
93 } namlist_t;
94
95
96 /*
97 * initerr is set as soon as a fatal error occurred in an initialisation.
98 * The effect is that the rest of the initialisation is ignored (parsed
99 * by yacc, expression trees built, but no initialisation takes place).
100 */
101 bool initerr;
102
103 /* Pointer to the symbol which is to be initialized. */
104 sym_t *initsym;
105
106 /* Points to the top element of the initialisation stack. */
107 istk_t *initstk;
108
109 /* Points to a c9x named member; */
110 namlist_t *namedmem = NULL;
111
112
113 static bool initstack_string(tnode_t *);
114
115 #ifndef DEBUG
116 #define debug_printf(fmt, ...) (void)0
117 #define debug_indent() (void)0
118 #define debug_enter(a) (void)0
119 #define debug_step(fmt, ...) (void)0
120 #define debug_leave(a) (void)0
121 #else
122 static int debug_ind = 0;
123
124 static void __printflike(1, 2)
125 debug_printf(const char *fmt, ...)
126 {
127 va_list va;
128
129 va_start(va, fmt);
130 vfprintf(stdout, fmt, va);
131 va_end(va);
132 }
133
134 static void
135 debug_indent(void)
136 {
137 debug_printf("%*s", 2 * debug_ind, "");
138 }
139
140 static void
141 debug_enter(const char *func)
142 {
143 printf("%*s+ %s\n", 2 * debug_ind++, "", func);
144 }
145
146 static void __printflike(1, 2)
147 debug_step(const char *fmt, ...)
148 {
149 va_list va;
150
151 printf("%*s", 2 * debug_ind, "");
152 va_start(va, fmt);
153 vfprintf(stdout, fmt, va);
154 va_end(va);
155 printf("\n");
156 }
157
158 static void
159 debug_leave(const char *func)
160 {
161 printf("%*s- %s\n", 2 * --debug_ind, "", func);
162 }
163
164 #define debug_enter() debug_enter(__func__)
165 #define debug_leave() debug_leave(__func__)
166
167 #endif
168
169 void
170 push_member(sbuf_t *sb)
171 {
172 namlist_t *nam = xcalloc(1, sizeof (namlist_t));
173 nam->n_name = sb->sb_name;
174
175 debug_step("%s: %s %p", __func__, nam->n_name, nam);
176
177 if (namedmem == NULL) {
178 /*
179 * XXX: Why is this a circular list?
180 * XXX: Why is this a doubly-linked list?
181 * A simple stack should suffice.
182 */
183 nam->n_prev = nam->n_next = nam;
184 namedmem = nam;
185 } else {
186 namedmem->n_prev->n_next = nam;
187 nam->n_prev = namedmem->n_prev;
188 nam->n_next = namedmem;
189 namedmem->n_prev = nam;
190 }
191 }
192
193 static void
194 pop_member(void)
195 {
196 debug_step("%s: %s %p", __func__, namedmem->n_name, namedmem);
197 if (namedmem->n_next == namedmem) {
198 free(namedmem);
199 namedmem = NULL;
200 } else {
201 namlist_t *nam = namedmem;
202 namedmem = namedmem->n_next;
203 nam->n_prev->n_next = nam->n_next;
204 nam->n_next->n_prev = nam->n_prev;
205 free(nam);
206 }
207 }
208
209 static void
210 debug_named_member(void)
211 {
212 namlist_t *name;
213
214 if (namedmem == NULL)
215 return;
216 name = namedmem;
217 debug_indent();
218 debug_printf("named member:");
219 do {
220 debug_printf(" %s", name->n_name);
221 name = name->n_next;
222 } while (name != namedmem);
223 debug_printf("\n");
224 }
225
226 /*
227 * Initialize the initialisation stack by putting an entry for the variable
228 * which is to be initialized on it.
229 */
230 void
231 initstack_init(void)
232 {
233 istk_t *istk;
234
235 if (initerr)
236 return;
237
238 /* free memory used in last initialisation */
239 while ((istk = initstk) != NULL) {
240 initstk = istk->i_next;
241 free(istk);
242 }
243
244 debug_enter();
245
246 /*
247 * If the type which is to be initialized is an incomplete type,
248 * it must be duplicated.
249 */
250 if (initsym->s_type->t_tspec == ARRAY && is_incomplete(initsym->s_type))
251 initsym->s_type = duptyp(initsym->s_type);
252
253 istk = initstk = xcalloc(1, sizeof (istk_t));
254 istk->i_subt = initsym->s_type;
255 istk->i_remaining = 1;
256
257 debug_leave();
258 }
259
260 static void
261 initstack_pop_item(void)
262 {
263 istk_t *istk;
264 sym_t *m;
265
266 debug_enter();
267
268 istk = initstk;
269 debug_step("pop type=%s, brace=%d remaining=%d named=%d",
270 type_name(istk->i_type ? istk->i_type : istk->i_subt),
271 istk->i_brace, istk->i_remaining, istk->i_namedmem);
272
273 initstk = istk->i_next;
274 free(istk);
275 istk = initstk;
276 lint_assert(istk != NULL);
277
278 debug_step("top type=%s, brace=%d remaining=%d named=%d",
279 type_name(istk->i_type ? istk->i_type : istk->i_subt),
280 istk->i_brace, istk->i_remaining, istk->i_namedmem);
281
282 istk->i_remaining--;
283 lint_assert(istk->i_remaining >= 0);
284
285 debug_step("top remaining=%d rhs.name=%s",
286 istk->i_remaining, namedmem ? namedmem->n_name : "*null*");
287
288 if (istk->i_remaining >= 0 && namedmem != NULL) {
289
290 debug_step("named remaining=%d type=%s, rhs.name=%s",
291 istk->i_remaining, type_name(istk->i_type),
292 namedmem->n_name);
293
294 for (m = istk->i_type->t_str->sou_first_member;
295 m != NULL; m = m->s_next) {
296 debug_step("pop lhs.name=%s rhs.name=%s",
297 m->s_name, namedmem->n_name);
298 if (m->s_bitfield && m->s_name == unnamed)
299 continue;
300 if (strcmp(m->s_name, namedmem->n_name) == 0) {
301 istk->i_subt = m->s_type;
302 istk->i_remaining++;
303 pop_member();
304 debug_leave();
305 return;
306 }
307 }
308 /* undefined struct/union member: %s */
309 error(101, namedmem->n_name);
310 debug_step("end rhs.name=%s", namedmem->n_name);
311 pop_member();
312 istk->i_namedmem = true;
313 debug_leave();
314 return;
315 }
316 /*
317 * If the removed element was a structure member, we must go
318 * to the next structure member.
319 */
320 if (istk->i_remaining > 0 && istk->i_type->t_tspec == STRUCT &&
321 !istk->i_namedmem) {
322 do {
323 m = istk->i_mem = istk->i_mem->s_next;
324 lint_assert(m != NULL);
325 debug_step("pop %s", m->s_name);
326 } while (m->s_bitfield && m->s_name == unnamed);
327 istk->i_subt = m->s_type;
328 }
329 debug_leave();
330 }
331
332 /*
333 * Take all entries, including the first which requires a closing brace,
334 * from the stack.
335 */
336 static void
337 initstack_pop_brace(void)
338 {
339 bool brace;
340
341 debug_enter();
342 do {
343 brace = initstk->i_brace;
344 debug_step("loop brace=%d", brace);
345 initstack_pop_item();
346 } while (!brace);
347 debug_leave();
348 }
349
350 /*
351 * Take all entries which cannot be used for further initializers from the
352 * stack, but do this only if they do not require a closing brace.
353 */
354 static void
355 initstack_pop_nobrace(void)
356 {
357
358 debug_enter();
359 while (!initstk->i_brace && initstk->i_remaining == 0 &&
360 !initstk->i_nolimit)
361 initstack_pop_item();
362 debug_leave();
363 }
364
365 static void
366 initstack_push(void)
367 {
368 istk_t *istk, *inxt;
369 int cnt;
370 sym_t *m;
371
372 debug_enter();
373
374 istk = initstk;
375
376 /* Extend an incomplete array type by one element */
377 if (istk->i_remaining == 0) {
378 debug_step("(extend) %s", type_name(istk->i_type));
379 /*
380 * Inside of other aggregate types must not be an incomplete
381 * type.
382 */
383 lint_assert(istk->i_next->i_next == NULL);
384 istk->i_remaining = 1;
385 lint_assert(istk->i_type->t_tspec == ARRAY);
386 istk->i_type->t_dim++;
387 setcomplete(istk->i_type, true);
388 }
389
390 lint_assert(istk->i_remaining > 0);
391 lint_assert(istk->i_type == NULL || !is_scalar(istk->i_type->t_tspec));
392
393 initstk = xcalloc(1, sizeof (istk_t));
394 initstk->i_next = istk;
395 initstk->i_type = istk->i_subt;
396 lint_assert(initstk->i_type->t_tspec != FUNC);
397
398 again:
399 istk = initstk;
400
401 debug_step("typename %s", type_name(istk->i_type));
402 switch (istk->i_type->t_tspec) {
403 case ARRAY:
404 if (namedmem != NULL) {
405 debug_step("ARRAY %s brace=%d",
406 namedmem->n_name, istk->i_brace);
407 goto pop;
408 } else if (istk->i_next->i_namedmem) {
409 istk->i_brace = true;
410 debug_step("ARRAY brace=%d, namedmem=%d",
411 istk->i_brace, istk->i_next->i_namedmem);
412 }
413
414 if (is_incomplete(istk->i_type) &&
415 istk->i_next->i_next != NULL) {
416 /* initialisation of an incomplete type */
417 error(175);
418 initerr = true;
419 debug_leave();
420 return;
421 }
422 istk->i_subt = istk->i_type->t_subt;
423 istk->i_nolimit = is_incomplete(istk->i_type);
424 istk->i_remaining = istk->i_type->t_dim;
425 debug_step("elements array %s[%d] %s",
426 type_name(istk->i_subt), istk->i_remaining,
427 namedmem ? namedmem->n_name : "*none*");
428 break;
429 case UNION:
430 if (tflag)
431 /* initialisation of union is illegal in trad. C */
432 warning(238);
433 /* FALLTHROUGH */
434 case STRUCT:
435 if (is_incomplete(istk->i_type)) {
436 /* initialisation of an incomplete type */
437 error(175);
438 initerr = true;
439 debug_leave();
440 return;
441 }
442 cnt = 0;
443 debug_step("lookup type=%s, name=%s named=%d",
444 type_name(istk->i_type),
445 namedmem ? namedmem->n_name : "*none*", istk->i_namedmem);
446 for (m = istk->i_type->t_str->sou_first_member;
447 m != NULL; m = m->s_next) {
448 if (m->s_bitfield && m->s_name == unnamed)
449 continue;
450 if (namedmem != NULL) {
451 debug_step("named lhs.member=%s, rhs.member=%s",
452 m->s_name, namedmem->n_name);
453 if (strcmp(m->s_name, namedmem->n_name) == 0) {
454 cnt++;
455 break;
456 } else
457 continue;
458 }
459 if (++cnt == 1) {
460 istk->i_mem = m;
461 istk->i_subt = m->s_type;
462 }
463 }
464 if (namedmem != NULL) {
465 if (m == NULL) {
466 debug_step("pop struct");
467 goto pop;
468 }
469 istk->i_mem = m;
470 istk->i_subt = m->s_type;
471 istk->i_namedmem = true;
472 debug_step("named name=%s", namedmem->n_name);
473 pop_member();
474 cnt = istk->i_type->t_tspec == STRUCT ? 2 : 1;
475 }
476 istk->i_brace = true;
477 debug_step("unnamed type=%s, brace=%d",
478 type_name(istk->i_type ? istk->i_type : istk->i_subt),
479 istk->i_brace);
480 if (cnt == 0) {
481 /* cannot init. struct/union with no named member */
482 error(179);
483 initerr = true;
484 debug_leave();
485 return;
486 }
487 istk->i_remaining = istk->i_type->t_tspec == STRUCT ? cnt : 1;
488 break;
489 default:
490 if (namedmem != NULL) {
491 debug_step("pop");
492 pop:
493 inxt = initstk->i_next;
494 free(istk);
495 initstk = inxt;
496 goto again;
497 }
498 istk->i_remaining = 1;
499 break;
500 }
501
502 debug_leave();
503 }
504
505 static void
506 initstack_check_too_many(void)
507 {
508 istk_t *istk;
509
510 istk = initstk;
511
512 /*
513 * If a closing brace is expected we have at least one initializer
514 * too much.
515 */
516 if (istk->i_remaining == 0 && !istk->i_nolimit && !istk->i_namedmem) {
517 switch (istk->i_type->t_tspec) {
518 case ARRAY:
519 /* too many array initializers, expected %d */
520 error(173, istk->i_type->t_dim);
521 break;
522 case STRUCT:
523 case UNION:
524 /* too many struct/union initializers */
525 error(172);
526 break;
527 default:
528 /* too many initializers */
529 error(174);
530 break;
531 }
532 initerr = true;
533 }
534 }
535
536 static void
537 initstack_next_brace(void)
538 {
539
540 debug_enter();
541
542 if (initstk->i_type != NULL && is_scalar(initstk->i_type->t_tspec)) {
543 /* invalid initializer type %s */
544 error(176, type_name(initstk->i_type));
545 initerr = true;
546 }
547 if (!initerr)
548 initstack_check_too_many();
549 if (!initerr)
550 initstack_push();
551 if (!initerr) {
552 initstk->i_brace = true;
553 debug_step("%p %s", namedmem, type_name(
554 initstk->i_type ? initstk->i_type : initstk->i_subt));
555 }
556
557 debug_leave();
558 }
559
560 static void
561 initstack_next_nobrace(void)
562 {
563 debug_enter();
564
565 if (initstk->i_type == NULL && !is_scalar(initstk->i_subt->t_tspec)) {
566 /* {}-enclosed initializer required */
567 error(181);
568 }
569
570 /* Make sure an entry with a scalar type is at the top of the stack. */
571 if (!initerr)
572 initstack_check_too_many();
573 while (!initerr) {
574 if ((initstk->i_type != NULL &&
575 is_scalar(initstk->i_type->t_tspec)))
576 break;
577 initstack_push();
578 }
579
580 debug_leave();
581 }
582
583 void
584 init_lbrace(void)
585 {
586 if (initerr)
587 return;
588
589 debug_enter();
590
591 if ((initsym->s_scl == AUTO || initsym->s_scl == REG) &&
592 initstk->i_next == NULL) {
593 if (tflag && !is_scalar(initstk->i_subt->t_tspec))
594 /* no automatic aggregate initialization in trad. C */
595 warning(188);
596 }
597
598 /*
599 * Remove all entries which cannot be used for further initializers
600 * and do not expect a closing brace.
601 */
602 initstack_pop_nobrace();
603
604 initstack_next_brace();
605
606 debug_leave();
607 }
608
609 void
610 init_rbrace(void)
611 {
612 if (initerr)
613 return;
614
615 debug_enter();
616
617 initstack_pop_brace();
618
619 debug_leave();
620 }
621
622 void
623 init_using_expr(tnode_t *tn)
624 {
625 ptrdiff_t offs;
626 sym_t *sym;
627 tspec_t lt, rt;
628 tnode_t *ln;
629 struct mbl *tmem;
630 scl_t sc;
631
632 debug_enter();
633 debug_named_member();
634 debug_node(tn);
635
636 if (initerr || tn == NULL) {
637 debug_leave();
638 return;
639 }
640
641 sc = initsym->s_scl;
642
643 /*
644 * Do not test for automatic aggregate initialisation. If the
645 * initializer starts with a brace we have the warning already.
646 * If not, an error will be printed that the initializer must
647 * be enclosed by braces.
648 */
649
650 /*
651 * Local initialisation of non-array-types with only one expression
652 * without braces is done by ASSIGN
653 */
654 if ((sc == AUTO || sc == REG) &&
655 initsym->s_type->t_tspec != ARRAY && initstk->i_next == NULL) {
656 ln = new_name_node(initsym, 0);
657 ln->tn_type = tduptyp(ln->tn_type);
658 ln->tn_type->t_const = false;
659 tn = build(ASSIGN, ln, tn);
660 expr(tn, false, false, false, false);
661 debug_leave();
662 return;
663 }
664
665 /*
666 * Remove all entries which cannot be used for further initializers
667 * and do not require a closing brace.
668 */
669 initstack_pop_nobrace();
670
671 /* Initialisations by strings are done in initstack_string(). */
672 if (initstack_string(tn)) {
673 debug_leave();
674 return;
675 }
676
677 initstack_next_nobrace();
678 if (initerr || tn == NULL) {
679 debug_leave();
680 return;
681 }
682
683 initstk->i_remaining--;
684 debug_step("remaining=%d tn=%p", initstk->i_remaining, tn);
685 /* Create a temporary node for the left side. */
686 ln = tgetblk(sizeof (tnode_t));
687 ln->tn_op = NAME;
688 ln->tn_type = tduptyp(initstk->i_type);
689 ln->tn_type->t_const = false;
690 ln->tn_lvalue = true;
691 ln->tn_sym = initsym; /* better than nothing */
692
693 tn = cconv(tn);
694
695 lt = ln->tn_type->t_tspec;
696 rt = tn->tn_type->t_tspec;
697
698 lint_assert(is_scalar(lt));
699
700 if (!typeok(INIT, 0, ln, tn)) {
701 debug_leave();
702 return;
703 }
704
705 /*
706 * Store the tree memory. This is necessary because otherwise
707 * expr() would free it.
708 */
709 tmem = tsave();
710 expr(tn, true, false, true, false);
711 trestor(tmem);
712
713 if (is_integer(lt) && ln->tn_type->t_bitfield && !is_integer(rt)) {
714 /*
715 * Bit-fields can be initialized in trad. C only by integer
716 * constants.
717 */
718 if (tflag)
719 /* bit-field initialisation is illegal in trad. C */
720 warning(186);
721 }
722
723 if (lt != rt || (initstk->i_type->t_bitfield && tn->tn_op == CON))
724 tn = convert(INIT, 0, initstk->i_type, tn);
725
726 if (tn != NULL && tn->tn_op != CON) {
727 sym = NULL;
728 offs = 0;
729 if (!constant_addr(tn, &sym, &offs)) {
730 if (sc == AUTO || sc == REG) {
731 /* non-constant initializer */
732 c99ism(177);
733 } else {
734 /* non-constant initializer */
735 error(177);
736 }
737 }
738 }
739
740 debug_leave();
741 }
742
743
744 static bool
745 initstack_string(tnode_t *tn)
746 {
747 tspec_t t;
748 istk_t *istk;
749 int len;
750 strg_t *strg;
751
752 if (tn->tn_op != STRING)
753 return false;
754
755 debug_enter();
756
757 istk = initstk;
758 strg = tn->tn_string;
759
760 /*
761 * Check if we have an array type which can be initialized by
762 * the string.
763 */
764 if (istk->i_subt != NULL && istk->i_subt->t_tspec == ARRAY) {
765 debug_step("subt array");
766 t = istk->i_subt->t_subt->t_tspec;
767 if (!((strg->st_tspec == CHAR &&
768 (t == CHAR || t == UCHAR || t == SCHAR)) ||
769 (strg->st_tspec == WCHAR && t == WCHAR))) {
770 debug_leave();
771 return false;
772 }
773 /* Put the array at top of stack */
774 initstack_push();
775 istk = initstk;
776 } else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) {
777 debug_step("type array");
778 t = istk->i_type->t_subt->t_tspec;
779 if (!((strg->st_tspec == CHAR &&
780 (t == CHAR || t == UCHAR || t == SCHAR)) ||
781 (strg->st_tspec == WCHAR && t == WCHAR))) {
782 debug_leave();
783 return false;
784 }
785 /*
786 * If the array is already partly initialized, we are
787 * wrong here.
788 */
789 if (istk->i_remaining != istk->i_type->t_dim)
790 debug_leave();
791 return false;
792 } else {
793 debug_leave();
794 return false;
795 }
796
797 /* Get length without trailing NUL character. */
798 len = strg->st_len;
799
800 if (istk->i_nolimit) {
801 istk->i_nolimit = false;
802 istk->i_type->t_dim = len + 1;
803 setcomplete(istk->i_type, true);
804 } else {
805 if (istk->i_type->t_dim < len) {
806 /* non-null byte ignored in string initializer */
807 warning(187);
808 }
809 }
810
811 /* In every case the array is initialized completely. */
812 istk->i_remaining = 0;
813
814 debug_leave();
815 return true;
816 }
817