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