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