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