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