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