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.6 2004/07/07 12:24:00 asmodai 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(void);
56 static void popinit(int);
57 static void pushinit(void);
58 static void testinit(void);
59 static void nextinit(int);
60 static int strginit(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
;
130 * Take all entries, including the first which requires
131 * a closing brace, from the stack.
134 brace
= initstk
->i_brace
;
139 * Take all entries which cannot be used for further
140 * initializers from the stack, but do this only if
141 * they do not require a closing brace.
143 while (!initstk
->i_brace
&&
144 initstk
->i_cnt
== 0 && !initstk
->i_nolimit
) {
159 /* Extend an incomplete array type by one element */
160 if (istk
->i_cnt
== 0) {
162 * Inside of other aggregate types must not be an incomplete
165 if (istk
->i_nxt
->i_nxt
!= NULL
)
166 lerror("pushinit() 1");
168 if (istk
->i_type
->t_tspec
!= ARRAY
)
169 lerror("pushinit() 2");
170 istk
->i_type
->t_dim
++;
171 /* from now its an complete type */
172 setcompl(istk
->i_type
, 0);
175 if (istk
->i_cnt
<= 0)
176 lerror("pushinit() 3");
177 if (istk
->i_type
!= NULL
&& issclt(istk
->i_type
->t_tspec
))
178 lerror("pushinit() 4");
180 initstk
= xcalloc(1, sizeof (istk_t
));
181 initstk
->i_nxt
= istk
;
182 initstk
->i_type
= istk
->i_subt
;
183 if (initstk
->i_type
->t_tspec
== FUNC
)
184 lerror("pushinit() 5");
188 switch (istk
->i_type
->t_tspec
) {
190 if (incompl(istk
->i_type
) && istk
->i_nxt
->i_nxt
!= NULL
) {
191 /* initialisation of an incomplete type */
196 istk
->i_subt
= istk
->i_type
->t_subt
;
197 istk
->i_nolimit
= incompl(istk
->i_type
);
198 istk
->i_cnt
= istk
->i_type
->t_dim
;
202 /* initialisation of union is illegal in trad. C */
206 if (incompl(istk
->i_type
)) {
207 /* initialisation of an incomplete type */
213 for (m
= istk
->i_type
->t_str
->memb
; m
!= NULL
; m
= m
->s_nxt
) {
214 if (m
->s_field
&& m
->s_name
== unnamed
)
218 istk
->i_subt
= m
->s_type
;
222 /* cannot init. struct/union with no named member */
227 istk
->i_cnt
= istk
->i_type
->t_tspec
== STRUCT
? cnt
: 1;
243 * If a closing brace is expected we have at least one initializer
246 if (istk
->i_cnt
== 0 && !istk
->i_nolimit
) {
247 switch (istk
->i_type
->t_tspec
) {
249 /* too many array initializers */
254 /* too many struct/union initializers */
258 /* too many initializers */
270 if (initstk
->i_type
== NULL
&&
271 !issclt(initstk
->i_subt
->t_tspec
)) {
272 /* {}-enclosed initializer required */
276 * Make sure an entry with a scalar type is at the top
281 while (!initerr
&& (initstk
->i_type
== NULL
||
282 !issclt(initstk
->i_type
->t_tspec
))) {
287 if (initstk
->i_type
!= NULL
&&
288 issclt(initstk
->i_type
->t_tspec
)) {
289 /* invalid initializer */
298 initstk
->i_brace
= 1;
308 if ((initsym
->s_scl
== AUTO
|| initsym
->s_scl
== REG
) &&
309 initstk
->i_nxt
== NULL
) {
310 if (tflag
&& !issclt(initstk
->i_subt
->t_tspec
))
311 /* no automatic aggregate initialization in trad. C*/
316 * Remove all entries which cannot be used for further initializers
317 * and do not expect a closing brace.
343 if (initerr
|| tn
== NULL
)
349 * Do not test for automatic aggregat initialisation. If the
350 * initalizer starts with a brace we have the warning already.
351 * If not, an error will be printed that the initializer must
352 * be enclosed by braces.
356 * Local initialisation of non-array-types with only one expression
357 * without braces is done by ASSIGN
359 if ((sc
== AUTO
|| sc
== REG
) &&
360 initsym
->s_type
->t_tspec
!= ARRAY
&& initstk
->i_nxt
== NULL
) {
361 ln
= getnnode(initsym
, 0);
362 ln
->tn_type
= tduptyp(ln
->tn_type
);
363 ln
->tn_type
->t_const
= 0;
364 tn
= build(ASSIGN
, ln
, tn
);
370 * Remove all entries which cannot be used for further initializers
371 * and do not require a closing brace.
375 /* Initialisations by strings are done in strginit(). */
380 if (initerr
|| tn
== NULL
)
385 /* Create a temporary node for the left side. */
386 ln
= tgetblk(sizeof (tnode_t
));
388 ln
->tn_type
= tduptyp(initstk
->i_type
);
389 ln
->tn_type
->t_const
= 0;
391 ln
->tn_sym
= initsym
; /* better than nothing */
395 lt
= ln
->tn_type
->t_tspec
;
396 rt
= tn
->tn_type
->t_tspec
;
399 lerror("mkinit() 1");
401 if (!typeok(INIT
, 0, ln
, tn
))
405 * Store the tree memory. This is nessesary because otherwise
406 * expr() would free it.
412 if (isityp(lt
) && ln
->tn_type
->t_isfield
&& !isityp(rt
)) {
414 * Bit-fields can be initialized in trad. C only by integer
418 /* bit-field initialisation is illegal in trad. C */
422 if (lt
!= rt
|| (initstk
->i_type
->t_isfield
&& tn
->tn_op
== CON
))
423 tn
= convert(INIT
, 0, initstk
->i_type
, tn
);
425 if (tn
!= NULL
&& tn
->tn_op
!= CON
) {
428 if (conaddr(tn
, &sym
, &offs
) == -1) {
429 if (sc
== AUTO
|| sc
== REG
) {
430 /* non-constant initializer */
433 /* non-constant initializer */
445 strginit(tnode_t
*tn
)
452 if (tn
->tn_op
!= STRING
)
459 * Check if we have an array type which can be initialized by
462 if (istk
->i_subt
->t_tspec
== ARRAY
) {
463 t
= istk
->i_subt
->t_subt
->t_tspec
;
464 if (!((strg
->st_tspec
== CHAR
&&
465 (t
== CHAR
|| t
== UCHAR
|| t
== SCHAR
)) ||
466 (strg
->st_tspec
== WCHAR
&& t
== WCHAR
))) {
469 /* Put the array at top of stack */
472 } else if (istk
->i_type
!= NULL
&& istk
->i_type
->t_tspec
== ARRAY
) {
473 t
= istk
->i_type
->t_subt
->t_tspec
;
474 if (!((strg
->st_tspec
== CHAR
&&
475 (t
== CHAR
|| t
== UCHAR
|| t
== SCHAR
)) ||
476 (strg
->st_tspec
== WCHAR
&& t
== WCHAR
))) {
480 * If the array is already partly initialized, we are
483 if (istk
->i_cnt
!= istk
->i_type
->t_dim
)
489 /* Get length without trailing NUL character. */
492 if (istk
->i_nolimit
) {
494 istk
->i_type
->t_dim
= len
+ 1;
495 /* from now complete type */
496 setcompl(istk
->i_type
, 0);
498 if (istk
->i_type
->t_dim
< len
) {
499 /* non-null byte ignored in string initializer */
504 /* In every case the array is initialized completely. */