1 /* $NetBSD: init.c,v 1.4 1995/10/02 17:21:37 jpo Exp $ */
4 * Copyright (c) 1994, 1995 Jochen Pohl
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
33 * $NetBSD: init.c,v 1.4 1995/10/02 17:21:37 jpo Exp $
34 * $DragonFly: src/usr.bin/xlint/lint1/init.c,v 1.3 2003/11/03 19:14:36 eirikn Exp $
42 * initerr is set as soon as a fatal error occured in an initialisation.
43 * The effect is that the rest of the initialisation is ignored (parsed
44 * by yacc, expression trees built, but no initialisation takes place).
48 /* Pointer to the symbol which is to be initialized. */
51 /* Points to the top element of the initialisation stack. */
55 static void popi2 __P((void));
56 static void popinit __P((int));
57 static void pushinit __P((void));
58 static void testinit __P((void));
59 static void nextinit __P((int));
60 static int strginit __P((tnode_t *));
64 * Initialize the initialisation stack by putting an entry for the variable
65 * which is to be initialized on it.
75 /* free memory used in last initialisation */
76 while ((istk = initstk) != NULL) {
77 initstk = istk->i_nxt;
82 * If the type which is to be initialized is an incomplete type,
83 * it must be duplicated.
85 if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type))
86 initsym->s_type = duptyp(initsym->s_type);
88 istk = initstk = xcalloc(1, sizeof (istk_t));
89 istk->i_subt = initsym->s_type;
100 initstk = (istk = initstk)->i_nxt;
112 * If the removed element was a structure member, we must go
113 * to the next structure member.
115 if (istk->i_cnt > 0 && istk->i_type->t_tspec == STRUCT) {
117 m = istk->i_mem = istk->i_mem->s_nxt;
120 } while (m->s_field && m->s_name == unnamed);
121 istk->i_subt = m->s_type;
131 * Take all entries, including the first which requires
132 * a closing brace, from the stack.
135 brace = initstk->i_brace;
140 * Take all entries which cannot be used for further
141 * initializers from the stack, but do this only if
142 * they do not require a closing brace.
144 while (!initstk->i_brace &&
145 initstk->i_cnt == 0 && !initstk->i_nolimit) {
160 /* Extend an incomplete array type by one element */
161 if (istk->i_cnt == 0) {
163 * Inside of other aggregate types must not be an incomplete
166 if (istk->i_nxt->i_nxt != NULL)
167 lerror("pushinit() 1");
169 if (istk->i_type->t_tspec != ARRAY)
170 lerror("pushinit() 2");
171 istk->i_type->t_dim++;
172 /* from now its an complete type */
173 setcompl(istk->i_type, 0);
176 if (istk->i_cnt <= 0)
177 lerror("pushinit() 3");
178 if (istk->i_type != NULL && issclt(istk->i_type->t_tspec))
179 lerror("pushinit() 4");
181 initstk = xcalloc(1, sizeof (istk_t));
182 initstk->i_nxt = istk;
183 initstk->i_type = istk->i_subt;
184 if (initstk->i_type->t_tspec == FUNC)
185 lerror("pushinit() 5");
189 switch (istk->i_type->t_tspec) {
191 if (incompl(istk->i_type) && istk->i_nxt->i_nxt != NULL) {
192 /* initialisation of an incomplete type */
197 istk->i_subt = istk->i_type->t_subt;
198 istk->i_nolimit = incompl(istk->i_type);
199 istk->i_cnt = istk->i_type->t_dim;
203 /* initialisation of union is illegal in trad. C */
207 if (incompl(istk->i_type)) {
208 /* initialisation of an incomplete type */
214 for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) {
215 if (m->s_field && m->s_name == unnamed)
219 istk->i_subt = m->s_type;
223 /* cannot init. struct/union with no named member */
228 istk->i_cnt = istk->i_type->t_tspec == STRUCT ? cnt : 1;
244 * If a closing brace is expected we have at least one initializer
247 if (istk->i_cnt == 0 && !istk->i_nolimit) {
248 switch (istk->i_type->t_tspec) {
250 /* too many array initializers */
255 /* too many struct/union initializers */
259 /* too many initializers */
272 if (initstk->i_type == NULL &&
273 !issclt(initstk->i_subt->t_tspec)) {
274 /* {}-enclosed initializer required */
278 * Make sure an entry with a scalar type is at the top
283 while (!initerr && (initstk->i_type == NULL ||
284 !issclt(initstk->i_type->t_tspec))) {
289 if (initstk->i_type != NULL &&
290 issclt(initstk->i_type->t_tspec)) {
291 /* invalid initializer */
300 initstk->i_brace = 1;
310 if ((initsym->s_scl == AUTO || initsym->s_scl == REG) &&
311 initstk->i_nxt == NULL) {
312 if (tflag && !issclt(initstk->i_subt->t_tspec))
313 /* no automatic aggregate initialization in trad. C*/
318 * Remove all entries which cannot be used for further initializers
319 * and do not expect a closing brace.
346 if (initerr || tn == NULL)
352 * Do not test for automatic aggregat initialisation. If the
353 * initalizer starts with a brace we have the warning already.
354 * If not, an error will be printed that the initializer must
355 * be enclosed by braces.
359 * Local initialisation of non-array-types with only one expression
360 * without braces is done by ASSIGN
362 if ((sc == AUTO || sc == REG) &&
363 initsym->s_type->t_tspec != ARRAY && initstk->i_nxt == NULL) {
364 ln = getnnode(initsym, 0);
365 ln->tn_type = tduptyp(ln->tn_type);
366 ln->tn_type->t_const = 0;
367 tn = build(ASSIGN, ln, tn);
373 * Remove all entries which cannot be used for further initializers
374 * and do not require a closing brace.
378 /* Initialisations by strings are done in strginit(). */
383 if (initerr || tn == NULL)
388 /* Create a temporary node for the left side. */
389 ln = tgetblk(sizeof (tnode_t));
391 ln->tn_type = tduptyp(initstk->i_type);
392 ln->tn_type->t_const = 0;
394 ln->tn_sym = initsym; /* better than nothing */
398 lt = ln->tn_type->t_tspec;
399 rt = tn->tn_type->t_tspec;
402 lerror("mkinit() 1");
404 if (!typeok(INIT, 0, ln, tn))
408 * Store the tree memory. This is nessesary because otherwise
409 * expr() would free it.
415 if (isityp(lt) && ln->tn_type->t_isfield && !isityp(rt)) {
417 * Bit-fields can be initialized in trad. C only by integer
421 /* bit-field initialisation is illegal in trad. C */
425 if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON))
426 tn = convert(INIT, 0, initstk->i_type, tn);
428 if (tn != NULL && tn->tn_op != CON) {
431 if (conaddr(tn, &sym, &offs) == -1) {
432 if (sc == AUTO || sc == REG) {
433 /* non-constant initializer */
436 /* non-constant initializer */
456 if (tn->tn_op != STRING)
463 * Check if we have an array type which can be initialized by
466 if (istk->i_subt->t_tspec == ARRAY) {
467 t = istk->i_subt->t_subt->t_tspec;
468 if (!((strg->st_tspec == CHAR &&
469 (t == CHAR || t == UCHAR || t == SCHAR)) ||
470 (strg->st_tspec == WCHAR && t == WCHAR))) {
473 /* Put the array at top of stack */
476 } else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) {
477 t = istk->i_type->t_subt->t_tspec;
478 if (!((strg->st_tspec == CHAR &&
479 (t == CHAR || t == UCHAR || t == SCHAR)) ||
480 (strg->st_tspec == WCHAR && t == WCHAR))) {
484 * If the array is already partly initialized, we are
487 if (istk->i_cnt != istk->i_type->t_dim)
493 /* Get length without trailing NUL character. */
496 if (istk->i_nolimit) {
498 istk->i_type->t_dim = len + 1;
499 /* from now complete type */
500 setcompl(istk->i_type, 0);
502 if (istk->i_type->t_dim < len) {
503 /* non-null byte ignored in string initializer */
508 /* In every case the array is initialized completely. */