init.c revision 1.54 1 /* $NetBSD: init.c,v 1.54 2021/01/01 19:28:51 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.54 2021/01/01 19:28:51 rillig Exp $");
41 #endif
42
43 #include <ctype.h>
44 #include <stdlib.h>
45 #include <string.h>
46
47 #include "lint1.h"
48
49
50 /*
51 * Type of stack which is used for initialisation of aggregate types.
52 *
53 * XXX: Since C99, a stack is an inappropriate data structure for modelling
54 * an initialization, since the designators don't have to be listed in a
55 * particular order and can designate parts of sub-objects. The member names
56 * of non-leaf structs may thus appear repeatedly, as demonstrated in
57 * d_init_pop_member.c.
58 *
59 * XXX: During initialization, there may be members of the top-level struct
60 * that are partially initialized. The simple i_remaining cannot model this
61 * appropriately.
62 *
63 * See C99 6.7.8, which spans 6 pages full of tricky details and carefully
64 * selected examples.
65 */
66 typedef struct istk {
67 type_t *i_type; /* type of initialisation */
68 type_t *i_subt; /* type of next level */
69 u_int i_brace : 1; /* need } for pop */
70 u_int i_nolimit : 1; /* incomplete array type */
71 u_int i_namedmem : 1; /* has c9x named members */
72 sym_t *i_mem; /* next structure member */
73 int i_remaining; /* # of remaining elements */
74 struct istk *i_next; /* previous level */
75 } istk_t;
76
77 typedef struct namlist {
78 const char *n_name;
79 struct namlist *n_prev;
80 struct namlist *n_next;
81 } namlist_t;
82
83
84 /*
85 * initerr is set as soon as a fatal error occurred in an initialisation.
86 * The effect is that the rest of the initialisation is ignored (parsed
87 * by yacc, expression trees built, but no initialisation takes place).
88 */
89 int initerr;
90
91 /* Pointer to the symbol which is to be initialized. */
92 sym_t *initsym;
93
94 /* Points to the top element of the initialisation stack. */
95 istk_t *initstk;
96
97 /* Points to a c9x named member; */
98 namlist_t *namedmem = NULL;
99
100
101 static int initstack_string(tnode_t *);
102
103 #ifndef DEBUG
104 #define DPRINTF(a)
105 #else
106 #define DPRINTF(a) printf a
107 #endif
108
109 void
110 push_member(sbuf_t *sb)
111 {
112 namlist_t *nam = xcalloc(1, sizeof (namlist_t));
113 nam->n_name = sb->sb_name;
114 DPRINTF(("%s: %s %p\n", __func__, nam->n_name, nam));
115 if (namedmem == NULL) {
116 /*
117 * XXX: Why is this a circular list?
118 * XXX: Why is this a doubly-linked list?
119 * A simple stack should suffice.
120 */
121 nam->n_prev = nam->n_next = nam;
122 namedmem = nam;
123 } else {
124 namedmem->n_prev->n_next = nam;
125 nam->n_prev = namedmem->n_prev;
126 nam->n_next = namedmem;
127 namedmem->n_prev = nam;
128 }
129 }
130
131 static void
132 pop_member(void)
133 {
134 DPRINTF(("%s: %s %p\n", __func__, namedmem->n_name, namedmem));
135 if (namedmem->n_next == namedmem) {
136 free(namedmem);
137 namedmem = NULL;
138 } else {
139 namlist_t *nam = namedmem;
140 namedmem = namedmem->n_next;
141 nam->n_prev->n_next = nam->n_next;
142 nam->n_next->n_prev = nam->n_prev;
143 free(nam);
144 }
145 }
146
147
148 /*
149 * Initialize the initialisation stack by putting an entry for the variable
150 * which is to be initialized on it.
151 */
152 void
153 initstack_init(void)
154 {
155 istk_t *istk;
156
157 if (initerr)
158 return;
159
160 /* free memory used in last initialisation */
161 while ((istk = initstk) != NULL) {
162 initstk = istk->i_next;
163 free(istk);
164 }
165
166 DPRINTF(("%s\n", __func__));
167
168 /*
169 * If the type which is to be initialized is an incomplete type,
170 * it must be duplicated.
171 */
172 if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type))
173 initsym->s_type = duptyp(initsym->s_type);
174
175 istk = initstk = xcalloc(1, sizeof (istk_t));
176 istk->i_subt = initsym->s_type;
177 istk->i_remaining = 1;
178 }
179
180 static void
181 initstack_pop_item(void)
182 {
183 #ifdef DEBUG
184 char buf[64];
185 #endif
186 istk_t *istk;
187 sym_t *m;
188
189 istk = initstk;
190 DPRINTF(("%s: pop type=%s, brace=%d remaining=%d named=%d\n", __func__,
191 tyname(buf, sizeof buf, istk->i_type ? istk->i_type : istk->i_subt),
192 istk->i_brace, istk->i_remaining, istk->i_namedmem));
193
194 initstk = istk->i_next;
195 free(istk);
196 istk = initstk;
197 lint_assert(istk != NULL);
198
199 DPRINTF(("%s: top type=%s, brace=%d remaining=%d named=%d\n", __func__,
200 tyname(buf, sizeof buf, istk->i_type ? istk->i_type : istk->i_subt),
201 istk->i_brace, istk->i_remaining, istk->i_namedmem));
202
203 istk->i_remaining--;
204 lint_assert(istk->i_remaining >= 0);
205
206 DPRINTF(("%s: top remaining=%d rhs.name=%s\n", __func__,
207 istk->i_remaining, namedmem ? namedmem->n_name : "*null*"));
208
209 if (istk->i_remaining >= 0 && namedmem != NULL) {
210
211 DPRINTF(("%s: named remaining=%d type=%s, rhs.name=%s\n",
212 __func__, istk->i_remaining,
213 tyname(buf, sizeof(buf), istk->i_type), namedmem->n_name));
214
215 for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_next) {
216 DPRINTF(("%s: pop lhs.name=%s rhs.name=%s\n", __func__,
217 m->s_name, namedmem->n_name));
218 if (m->s_bitfield && m->s_name == unnamed)
219 continue;
220 if (strcmp(m->s_name, namedmem->n_name) == 0) {
221 istk->i_subt = m->s_type;
222 istk->i_remaining++;
223 pop_member();
224 return;
225 }
226 }
227 /* undefined struct/union member: %s */
228 error(101, namedmem->n_name);
229 DPRINTF(("%s: end rhs.name=%s\n", __func__, namedmem->n_name));
230 pop_member();
231 istk->i_namedmem = 1;
232 return;
233 }
234 /*
235 * If the removed element was a structure member, we must go
236 * to the next structure member.
237 */
238 if (istk->i_remaining > 0 && istk->i_type->t_tspec == STRUCT &&
239 !istk->i_namedmem) {
240 do {
241 m = istk->i_mem = istk->i_mem->s_next;
242 lint_assert(m != NULL);
243 DPRINTF(("%s: pop %s\n", __func__, m->s_name));
244 } while (m->s_bitfield && m->s_name == unnamed);
245 istk->i_subt = m->s_type;
246 }
247 }
248
249 /*
250 * Take all entries, including the first which requires a closing brace,
251 * from the stack.
252 */
253 static void
254 initstack_pop_brace(void)
255 {
256 int brace;
257
258 DPRINTF(("%s\n", __func__));
259 do {
260 brace = initstk->i_brace;
261 DPRINTF(("%s: loop brace=%d\n", __func__, brace));
262 initstack_pop_item();
263 } while (!brace);
264 DPRINTF(("%s: done\n", __func__));
265 }
266
267 /*
268 * Take all entries which cannot be used for further initializers from the
269 * stack, but do this only if they do not require a closing brace.
270 */
271 static void
272 initstack_pop_nobrace(void)
273 {
274
275 DPRINTF(("%s\n", __func__));
276 while (!initstk->i_brace && initstk->i_remaining == 0 &&
277 !initstk->i_nolimit)
278 initstack_pop_item();
279 DPRINTF(("%s: done\n", __func__));
280 }
281
282 static void
283 initstack_push(void)
284 {
285 #ifdef DEBUG
286 char buf[64];
287 #endif
288 istk_t *istk, *inxt;
289 int cnt;
290 sym_t *m;
291
292 istk = initstk;
293
294 /* Extend an incomplete array type by one element */
295 if (istk->i_remaining == 0) {
296 DPRINTF(("%s(extend) %s\n", __func__,
297 tyname(buf, sizeof(buf), istk->i_type)));
298 /*
299 * Inside of other aggregate types must not be an incomplete
300 * type.
301 */
302 lint_assert(istk->i_next->i_next == NULL);
303 istk->i_remaining = 1;
304 lint_assert(istk->i_type->t_tspec == ARRAY);
305 istk->i_type->t_dim++;
306 setcomplete(istk->i_type, 1);
307 }
308
309 lint_assert(istk->i_remaining > 0);
310 lint_assert(istk->i_type == NULL ||
311 !tspec_is_scalar(istk->i_type->t_tspec));
312
313 initstk = xcalloc(1, sizeof (istk_t));
314 initstk->i_next = istk;
315 initstk->i_type = istk->i_subt;
316 lint_assert(initstk->i_type->t_tspec != FUNC);
317
318 again:
319 istk = initstk;
320
321 DPRINTF(("%s(%s)\n", __func__, tyname(buf, sizeof(buf), istk->i_type)));
322 switch (istk->i_type->t_tspec) {
323 case ARRAY:
324 if (namedmem) {
325 DPRINTF(("%s: ARRAY %s brace=%d\n", __func__,
326 namedmem->n_name, istk->i_brace));
327 goto pop;
328 } else if (istk->i_next->i_namedmem) {
329 istk->i_brace = 1;
330 DPRINTF(("%s ARRAY brace=%d, namedmem=%d\n", __func__,
331 istk->i_brace, istk->i_next->i_namedmem));
332 }
333
334 if (incompl(istk->i_type) && istk->i_next->i_next != NULL) {
335 /* initialisation of an incomplete type */
336 error(175);
337 initerr = 1;
338 return;
339 }
340 istk->i_subt = istk->i_type->t_subt;
341 istk->i_nolimit = incompl(istk->i_type);
342 istk->i_remaining = istk->i_type->t_dim;
343 DPRINTF(("%s: elements array %s[%d] %s\n", __func__,
344 tyname(buf, sizeof(buf), istk->i_subt), istk->i_remaining,
345 namedmem ? namedmem->n_name : "*none*"));
346 break;
347 case UNION:
348 if (tflag)
349 /* initialisation of union is illegal in trad. C */
350 warning(238);
351 /* FALLTHROUGH */
352 case STRUCT:
353 if (incompl(istk->i_type)) {
354 /* initialisation of an incomplete type */
355 error(175);
356 initerr = 1;
357 return;
358 }
359 cnt = 0;
360 DPRINTF(("%s: lookup type=%s, name=%s named=%d\n", __func__,
361 tyname(buf, sizeof(buf), istk->i_type),
362 namedmem ? namedmem->n_name : "*none*", istk->i_namedmem));
363 for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_next) {
364 if (m->s_bitfield && m->s_name == unnamed)
365 continue;
366 if (namedmem != NULL) {
367 DPRINTF(("%s: named lhs.member=%s, rhs.member=%s\n",
368 __func__, m->s_name, namedmem->n_name));
369 if (strcmp(m->s_name, namedmem->n_name) == 0) {
370 cnt++;
371 break;
372 } else
373 continue;
374 }
375 if (++cnt == 1) {
376 istk->i_mem = m;
377 istk->i_subt = m->s_type;
378 }
379 }
380 if (namedmem != NULL) {
381 if (m == NULL) {
382 DPRINTF(("%s: pop struct\n", __func__));
383 goto pop;
384 }
385 istk->i_mem = m;
386 istk->i_subt = m->s_type;
387 istk->i_namedmem = 1;
388 DPRINTF(("%s: named name=%s\n", __func__,
389 namedmem->n_name));
390 pop_member();
391 cnt = istk->i_type->t_tspec == STRUCT ? 2 : 1;
392 }
393 istk->i_brace = 1;
394 DPRINTF(("%s: unnamed type=%s, brace=%d\n", __func__,
395 tyname(buf, sizeof(buf),
396 istk->i_type ? istk->i_type : istk->i_subt),
397 istk->i_brace));
398 if (cnt == 0) {
399 /* cannot init. struct/union with no named member */
400 error(179);
401 initerr = 1;
402 return;
403 }
404 istk->i_remaining = istk->i_type->t_tspec == STRUCT ? cnt : 1;
405 break;
406 default:
407 if (namedmem) {
408 DPRINTF(("%s: pop\n", __func__));
409 pop:
410 inxt = initstk->i_next;
411 free(istk);
412 initstk = inxt;
413 goto again;
414 }
415 istk->i_remaining = 1;
416 break;
417 }
418 }
419
420 static void
421 initstack_check_too_many(void)
422 {
423 istk_t *istk;
424
425 istk = initstk;
426
427 /*
428 * If a closing brace is expected we have at least one initializer
429 * too much.
430 */
431 if (istk->i_remaining == 0 && !istk->i_nolimit && !istk->i_namedmem) {
432 switch (istk->i_type->t_tspec) {
433 case ARRAY:
434 /* too many array initializers, expected %d */
435 error(173, istk->i_type->t_dim);
436 break;
437 case STRUCT:
438 case UNION:
439 /* too many struct/union initializers */
440 error(172);
441 break;
442 default:
443 /* too many initializers */
444 error(174);
445 break;
446 }
447 initerr = 1;
448 }
449 }
450
451 static void
452 initstack_next_brace(void)
453 {
454 char buf[64];
455
456 DPRINTF(("%s\n", __func__));
457 if (initstk->i_type != NULL &&
458 tspec_is_scalar(initstk->i_type->t_tspec)) {
459 /* invalid initializer type %s */
460 error(176, tyname(buf, sizeof(buf), initstk->i_type));
461 initerr = 1;
462 }
463 if (!initerr)
464 initstack_check_too_many();
465 if (!initerr)
466 initstack_push();
467 if (!initerr) {
468 initstk->i_brace = 1;
469 DPRINTF(("%s: %p %s\n", __func__,
470 namedmem,
471 tyname(buf, sizeof(buf),
472 initstk->i_type ? initstk->i_type : initstk->i_subt)));
473 }
474 }
475
476 static void
477 initstack_next_nobrace(void)
478 {
479
480 DPRINTF(("%s\n", __func__));
481 if (initstk->i_type == NULL &&
482 !tspec_is_scalar(initstk->i_subt->t_tspec)) {
483 /* {}-enclosed initializer required */
484 error(181);
485 }
486
487 /* Make sure an entry with a scalar type is at the top of the stack. */
488 if (!initerr)
489 initstack_check_too_many();
490 while (!initerr) {
491 if ((initstk->i_type != NULL &&
492 tspec_is_scalar(initstk->i_type->t_tspec)))
493 break;
494 initstack_push();
495 }
496 }
497
498 void
499 init_lbrace(void)
500 {
501 DPRINTF(("%s\n", __func__));
502
503 if (initerr)
504 return;
505
506 if ((initsym->s_scl == AUTO || initsym->s_scl == REG) &&
507 initstk->i_next == NULL) {
508 if (tflag && !tspec_is_scalar(initstk->i_subt->t_tspec))
509 /* no automatic aggregate initialization in trad. C */
510 warning(188);
511 }
512
513 /*
514 * Remove all entries which cannot be used for further initializers
515 * and do not expect a closing brace.
516 */
517 initstack_pop_nobrace();
518
519 initstack_next_brace();
520 }
521
522 void
523 init_rbrace(void)
524 {
525 DPRINTF(("%s\n", __func__));
526
527 if (initerr)
528 return;
529
530 initstack_pop_brace();
531 }
532
533 void
534 mkinit(tnode_t *tn)
535 {
536 ptrdiff_t offs;
537 sym_t *sym;
538 tspec_t lt, rt;
539 tnode_t *ln;
540 struct mbl *tmem;
541 scl_t sc;
542 #ifdef DEBUG
543 char buf[64], sbuf[64];
544 #endif
545
546 DPRINTF(("%s: type=%s, value=%s\n", __func__,
547 tyname(buf, sizeof(buf), tn->tn_type),
548 print_tnode(sbuf, sizeof(sbuf), tn)));
549 if (initerr || tn == NULL)
550 return;
551
552 sc = initsym->s_scl;
553
554 /*
555 * Do not test for automatic aggregate initialisation. If the
556 * initializer starts with a brace we have the warning already.
557 * If not, an error will be printed that the initializer must
558 * be enclosed by braces.
559 */
560
561 /*
562 * Local initialisation of non-array-types with only one expression
563 * without braces is done by ASSIGN
564 */
565 if ((sc == AUTO || sc == REG) &&
566 initsym->s_type->t_tspec != ARRAY && initstk->i_next == NULL) {
567 ln = getnnode(initsym, 0);
568 ln->tn_type = tduptyp(ln->tn_type);
569 ln->tn_type->t_const = 0;
570 tn = build(ASSIGN, ln, tn);
571 expr(tn, 0, 0, 0);
572 return;
573 }
574
575 /*
576 * Remove all entries which cannot be used for further initializers
577 * and do not require a closing brace.
578 */
579 initstack_pop_nobrace();
580
581 /* Initialisations by strings are done in initstack_string(). */
582 if (initstack_string(tn))
583 return;
584
585 initstack_next_nobrace();
586 if (initerr || tn == NULL)
587 return;
588
589 initstk->i_remaining--;
590 DPRINTF(("%s: remaining=%d tn=%p\n", __func__,
591 initstk->i_remaining, tn));
592 /* Create a temporary node for the left side. */
593 ln = tgetblk(sizeof (tnode_t));
594 ln->tn_op = NAME;
595 ln->tn_type = tduptyp(initstk->i_type);
596 ln->tn_type->t_const = 0;
597 ln->tn_lvalue = 1;
598 ln->tn_sym = initsym; /* better than nothing */
599
600 tn = cconv(tn);
601
602 lt = ln->tn_type->t_tspec;
603 rt = tn->tn_type->t_tspec;
604
605 lint_assert(tspec_is_scalar(lt));
606
607 if (!typeok(INIT, 0, ln, tn))
608 return;
609
610 /*
611 * Store the tree memory. This is necessary because otherwise
612 * expr() would free it.
613 */
614 tmem = tsave();
615 expr(tn, 1, 0, 1);
616 trestor(tmem);
617
618 if (tspec_is_int(lt) && ln->tn_type->t_isfield && !tspec_is_int(rt)) {
619 /*
620 * Bit-fields can be initialized in trad. C only by integer
621 * constants.
622 */
623 if (tflag)
624 /* bit-field initialisation is illegal in trad. C */
625 warning(186);
626 }
627
628 if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON))
629 tn = convert(INIT, 0, initstk->i_type, tn);
630
631 if (tn != NULL && tn->tn_op != CON) {
632 sym = NULL;
633 offs = 0;
634 if (conaddr(tn, &sym, &offs) == -1) {
635 if (sc == AUTO || sc == REG) {
636 /* non-constant initializer */
637 (void)c99ism(177);
638 } else {
639 /* non-constant initializer */
640 error(177);
641 }
642 }
643 }
644 }
645
646
647 static int
648 initstack_string(tnode_t *tn)
649 {
650 tspec_t t;
651 istk_t *istk;
652 int len;
653 strg_t *strg;
654
655 if (tn->tn_op != STRING)
656 return 0;
657
658 istk = initstk;
659 strg = tn->tn_string;
660
661 /*
662 * Check if we have an array type which can be initialized by
663 * the string.
664 */
665 if (istk->i_subt != NULL && istk->i_subt->t_tspec == ARRAY) {
666 DPRINTF(("%s: subt array\n", __func__));
667 t = istk->i_subt->t_subt->t_tspec;
668 if (!((strg->st_tspec == CHAR &&
669 (t == CHAR || t == UCHAR || t == SCHAR)) ||
670 (strg->st_tspec == WCHAR && t == WCHAR))) {
671 return 0;
672 }
673 /* Put the array at top of stack */
674 initstack_push();
675 istk = initstk;
676 } else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) {
677 DPRINTF(("%s: type array\n", __func__));
678 t = istk->i_type->t_subt->t_tspec;
679 if (!((strg->st_tspec == CHAR &&
680 (t == CHAR || t == UCHAR || t == SCHAR)) ||
681 (strg->st_tspec == WCHAR && t == WCHAR))) {
682 return 0;
683 }
684 /*
685 * If the array is already partly initialized, we are
686 * wrong here.
687 */
688 if (istk->i_remaining != istk->i_type->t_dim)
689 return 0;
690 } else {
691 return 0;
692 }
693
694 /* Get length without trailing NUL character. */
695 len = strg->st_len;
696
697 if (istk->i_nolimit) {
698 istk->i_nolimit = 0;
699 istk->i_type->t_dim = len + 1;
700 setcomplete(istk->i_type, 1);
701 } else {
702 if (istk->i_type->t_dim < len) {
703 /* non-null byte ignored in string initializer */
704 warning(187);
705 }
706 }
707
708 /* In every case the array is initialized completely. */
709 istk->i_remaining = 0;
710
711 return 1;
712 }
713