init.c revision 1.9 1 /* $NetBSD: init.c,v 1.9 2001/09/18 18:15:54 wiz 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 #ifndef lint
36 __RCSID("$NetBSD: init.c,v 1.9 2001/09/18 18:15:54 wiz 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
57 static void popi2(void);
58 static void popinit(int);
59 static void pushinit(void);
60 static void testinit(void);
61 static void nextinit(int);
62 static int strginit(tnode_t *);
63
64
65 /*
66 * Initialize the initialisation stack by putting an entry for the variable
67 * which is to be initialized on it.
68 */
69 void
70 prepinit(void)
71 {
72 istk_t *istk;
73
74 if (initerr)
75 return;
76
77 /* free memory used in last initialisation */
78 while ((istk = initstk) != NULL) {
79 initstk = istk->i_nxt;
80 free(istk);
81 }
82
83 /*
84 * If the type which is to be initialized is an incomplete type,
85 * it must be duplicated.
86 */
87 if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type))
88 initsym->s_type = duptyp(initsym->s_type);
89
90 istk = initstk = xcalloc(1, sizeof (istk_t));
91 istk->i_subt = initsym->s_type;
92 istk->i_cnt = 1;
93
94 }
95
96 static void
97 popi2(void)
98 {
99 istk_t *istk;
100 sym_t *m;
101
102 initstk = (istk = initstk)->i_nxt;
103 if (initstk == NULL)
104 lerror("popi2() 1");
105 free(istk);
106
107 istk = initstk;
108
109 istk->i_cnt--;
110 if (istk->i_cnt < 0)
111 lerror("popi2() 3");
112
113 /*
114 * If the removed element was a structure member, we must go
115 * to the next structure member.
116 */
117 if (istk->i_cnt > 0 && istk->i_type->t_tspec == STRUCT) {
118 do {
119 m = istk->i_mem = istk->i_mem->s_nxt;
120 if (m == NULL)
121 lerror("popi2() 2");
122 } while (m->s_field && m->s_name == unnamed);
123 istk->i_subt = m->s_type;
124 }
125 }
126
127 static void
128 popinit(int brace)
129 {
130
131 if (brace) {
132 /*
133 * Take all entries, including the first which requires
134 * a closing brace, from the stack.
135 */
136 do {
137 brace = initstk->i_brace;
138 popi2();
139 } while (!brace);
140 } else {
141 /*
142 * Take all entries which cannot be used for further
143 * initializers from the stack, but do this only if
144 * they do not require a closing brace.
145 */
146 while (!initstk->i_brace &&
147 initstk->i_cnt == 0 && !initstk->i_nolimit) {
148 popi2();
149 }
150 }
151 }
152
153 static void
154 pushinit(void)
155 {
156 istk_t *istk;
157 int cnt;
158 sym_t *m;
159
160 istk = initstk;
161
162 /* Extend an incomplete array type by one element */
163 if (istk->i_cnt == 0) {
164 /*
165 * Inside of other aggregate types must not be an incomplete
166 * type.
167 */
168 if (istk->i_nxt->i_nxt != NULL)
169 lerror("pushinit() 1");
170 istk->i_cnt = 1;
171 if (istk->i_type->t_tspec != ARRAY)
172 lerror("pushinit() 2");
173 istk->i_type->t_dim++;
174 /* from now its an complete type */
175 setcompl(istk->i_type, 0);
176 }
177
178 if (istk->i_cnt <= 0)
179 lerror("pushinit() 3");
180 if (istk->i_type != NULL && issclt(istk->i_type->t_tspec))
181 lerror("pushinit() 4");
182
183 initstk = xcalloc(1, sizeof (istk_t));
184 initstk->i_nxt = istk;
185 initstk->i_type = istk->i_subt;
186 if (initstk->i_type->t_tspec == FUNC)
187 lerror("pushinit() 5");
188
189 istk = initstk;
190
191 switch (istk->i_type->t_tspec) {
192 case ARRAY:
193 if (incompl(istk->i_type) && istk->i_nxt->i_nxt != NULL) {
194 /* initialisation of an incomplete type */
195 error(175);
196 initerr = 1;
197 return;
198 }
199 istk->i_subt = istk->i_type->t_subt;
200 istk->i_nolimit = incompl(istk->i_type);
201 istk->i_cnt = istk->i_type->t_dim;
202 break;
203 case UNION:
204 if (tflag)
205 /* initialisation of union is illegal in trad. C */
206 warning(238);
207 /* FALLTHROUGH */
208 case STRUCT:
209 if (incompl(istk->i_type)) {
210 /* initialisation of an incomplete type */
211 error(175);
212 initerr = 1;
213 return;
214 }
215 cnt = 0;
216 for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) {
217 if (m->s_field && m->s_name == unnamed)
218 continue;
219 if (++cnt == 1) {
220 istk->i_mem = m;
221 istk->i_subt = m->s_type;
222 }
223 }
224 if (cnt == 0) {
225 /* cannot init. struct/union with no named member */
226 error(179);
227 initerr = 1;
228 return;
229 }
230 istk->i_cnt = istk->i_type->t_tspec == STRUCT ? cnt : 1;
231 break;
232 default:
233 istk->i_cnt = 1;
234 break;
235 }
236 }
237
238 static void
239 testinit(void)
240 {
241 istk_t *istk;
242
243 istk = initstk;
244
245 /*
246 * If a closing brace is expected we have at least one initializer
247 * too much.
248 */
249 if (istk->i_cnt == 0 && !istk->i_nolimit) {
250 switch (istk->i_type->t_tspec) {
251 case ARRAY:
252 /* too many array initializers */
253 error(173);
254 break;
255 case STRUCT:
256 case UNION:
257 /* too many struct/union initializers */
258 error(172);
259 break;
260 default:
261 /* too many initializers */
262 error(174);
263 break;
264 }
265 initerr = 1;
266 }
267 }
268
269 static void
270 nextinit(int brace)
271 {
272
273 if (!brace) {
274 if (initstk->i_type == NULL &&
275 !issclt(initstk->i_subt->t_tspec)) {
276 /* {}-enclosed initializer required */
277 error(181);
278 }
279 /*
280 * Make sure an entry with a scalar type is at the top
281 * of the stack.
282 */
283 if (!initerr)
284 testinit();
285 while (!initerr && (initstk->i_type == NULL ||
286 !issclt(initstk->i_type->t_tspec))) {
287 if (!initerr)
288 pushinit();
289 }
290 } else {
291 if (initstk->i_type != NULL &&
292 issclt(initstk->i_type->t_tspec)) {
293 /* invalid initializer */
294 error(176);
295 initerr = 1;
296 }
297 if (!initerr)
298 testinit();
299 if (!initerr)
300 pushinit();
301 if (!initerr)
302 initstk->i_brace = 1;
303 }
304 }
305
306 void
307 initlbr(void)
308 {
309
310 if (initerr)
311 return;
312
313 if ((initsym->s_scl == AUTO || initsym->s_scl == REG) &&
314 initstk->i_nxt == NULL) {
315 if (tflag && !issclt(initstk->i_subt->t_tspec))
316 /* no automatic aggregate initialization in trad. C*/
317 warning(188);
318 }
319
320 /*
321 * Remove all entries which cannot be used for further initializers
322 * and do not expect a closing brace.
323 */
324 popinit(0);
325
326 nextinit(1);
327 }
328
329 void
330 initrbr(void)
331 {
332
333 if (initerr)
334 return;
335
336 popinit(1);
337 }
338
339 void
340 mkinit(tnode_t *tn)
341 {
342 ptrdiff_t offs;
343 sym_t *sym;
344 tspec_t lt, rt;
345 tnode_t *ln;
346 struct mbl *tmem;
347 scl_t sc;
348
349 if (initerr || tn == NULL)
350 goto end;
351
352 sc = initsym->s_scl;
353
354 /*
355 * Do not test for automatic aggregat initialisation. If the
356 * initializer starts with a brace we have the warning already.
357 * If not, an error will be printed that the initializer must
358 * be enclosed by braces.
359 */
360
361 /*
362 * Local initialisation of non-array-types with only one expression
363 * without braces is done by ASSIGN
364 */
365 if ((sc == AUTO || sc == REG) &&
366 initsym->s_type->t_tspec != ARRAY && initstk->i_nxt == NULL) {
367 ln = getnnode(initsym, 0);
368 ln->tn_type = tduptyp(ln->tn_type);
369 ln->tn_type->t_const = 0;
370 tn = build(ASSIGN, ln, tn);
371 expr(tn, 0, 0);
372 goto end;
373 }
374
375 /*
376 * Remove all entries which cannot be used for further initializers
377 * and do not require a closing brace.
378 */
379 popinit(0);
380
381 /* Initialisations by strings are done in strginit(). */
382 if (strginit(tn))
383 goto end;
384
385 nextinit(0);
386 if (initerr || tn == NULL)
387 goto end;
388
389 initstk->i_cnt--;
390
391 /* Create a temporary node for the left side. */
392 ln = tgetblk(sizeof (tnode_t));
393 ln->tn_op = NAME;
394 ln->tn_type = tduptyp(initstk->i_type);
395 ln->tn_type->t_const = 0;
396 ln->tn_lvalue = 1;
397 ln->tn_sym = initsym; /* better than nothing */
398
399 tn = cconv(tn);
400
401 lt = ln->tn_type->t_tspec;
402 rt = tn->tn_type->t_tspec;
403
404 if (!issclt(lt))
405 lerror("mkinit() 1");
406
407 if (!typeok(INIT, 0, ln, tn))
408 goto end;
409
410 /*
411 * Store the tree memory. This is nessesary because otherwise
412 * expr() would free it.
413 */
414 tmem = tsave();
415 expr(tn, 1, 0);
416 trestor(tmem);
417
418 if (isityp(lt) && ln->tn_type->t_isfield && !isityp(rt)) {
419 /*
420 * Bit-fields can be initialized in trad. C only by integer
421 * constants.
422 */
423 if (tflag)
424 /* bit-field initialisation is illegal in trad. C */
425 warning(186);
426 }
427
428 if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON))
429 tn = convert(INIT, 0, initstk->i_type, tn);
430
431 if (tn != NULL && tn->tn_op != CON) {
432 sym = NULL;
433 offs = 0;
434 if (conaddr(tn, &sym, &offs) == -1) {
435 if (sc == AUTO || sc == REG) {
436 /* non-constant initializer */
437 (void)gnuism(177);
438 } else {
439 /* non-constant initializer */
440 error(177);
441 }
442 }
443 }
444
445 end:
446 tfreeblk();
447 }
448
449
450 static int
451 strginit(tnode_t *tn)
452 {
453 tspec_t t;
454 istk_t *istk;
455 int len;
456 strg_t *strg;
457
458 if (tn->tn_op != STRING)
459 return (0);
460
461 istk = initstk;
462 strg = tn->tn_strg;
463
464 /*
465 * Check if we have an array type which can be initialized by
466 * the string.
467 */
468 if (istk->i_subt->t_tspec == ARRAY) {
469 t = istk->i_subt->t_subt->t_tspec;
470 if (!((strg->st_tspec == CHAR &&
471 (t == CHAR || t == UCHAR || t == SCHAR)) ||
472 (strg->st_tspec == WCHAR && t == WCHAR))) {
473 return (0);
474 }
475 /* Put the array at top of stack */
476 pushinit();
477 istk = initstk;
478 } else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) {
479 t = istk->i_type->t_subt->t_tspec;
480 if (!((strg->st_tspec == CHAR &&
481 (t == CHAR || t == UCHAR || t == SCHAR)) ||
482 (strg->st_tspec == WCHAR && t == WCHAR))) {
483 return (0);
484 }
485 /*
486 * If the array is already partly initialized, we are
487 * wrong here.
488 */
489 if (istk->i_cnt != istk->i_type->t_dim)
490 return (0);
491 } else {
492 return (0);
493 }
494
495 /* Get length without trailing NUL character. */
496 len = strg->st_len;
497
498 if (istk->i_nolimit) {
499 istk->i_nolimit = 0;
500 istk->i_type->t_dim = len + 1;
501 /* from now complete type */
502 setcompl(istk->i_type, 0);
503 } else {
504 if (istk->i_type->t_dim < len) {
505 /* non-null byte ignored in string initializer */
506 warning(187);
507 }
508 }
509
510 /* In every case the array is initialized completely. */
511 istk->i_cnt = 0;
512
513 return (1);
514 }
515