Home | History | Annotate | Line # | Download | only in lint1
init.c revision 1.1
      1 /*
      2  * Copyright (c) 1994, 1995 Jochen Pohl
      3  * All Rights Reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. All advertising materials mentioning features or use of this software
     14  *    must display the following acknowledgement:
     15  *      This product includes software developed by Jochen Pohl for
     16  *	The NetBSD Project.
     17  * 4. The name of the author may not be used to endorse or promote products
     18  *    derived from this software without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  *
     31  *	$Id: init.c,v 1.1 1995/07/03 20:56:37 cgd Exp $
     32  */
     33 
     34 #ifndef lint
     35 static char rcsid[] = "$Id: init.c,v 1.1 1995/07/03 20:56:37 cgd 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  */
     47 int	initerr;
     48 
     49 /* Pointer to the symbol which is to be initialized. */
     50 sym_t	*initsym;
     51 
     52 /* Points to the top element of the initialisation stack. */
     53 istk_t	*initstk;
     54 
     55 
     56 static	void	popi2 __P((void));
     57 static	void	popinit __P((int));
     58 static	void	pushinit __P((void));
     59 static	void	testinit __P((void));
     60 static	void	nextinit __P((int));
     61 static	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  */
     68 void
     69 prepinit()
     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 
     95 static void
     96 popi2()
     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 
    126 static void
    127 popinit(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 
    152 static void
    153 pushinit()
    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 
    237 static void
    238 testinit()
    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 
    268 static void
    269 nextinit(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 
    305 void
    306 initlbr()
    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 
    327 void
    328 initrbr()
    329 {
    330 	if (initerr)
    331 		return;
    332 
    333 	popinit(1);
    334 }
    335 
    336 void
    337 mkinit(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 (gflag && (sc == AUTO || sc == REG)) {
    434 				/* non-constant initializer */
    435 				warning(177);
    436 			} else {
    437 				/* non-constant initializer */
    438 				error(177);
    439 			}
    440 		}
    441 	}
    442 
    443  end:
    444 	tfreeblk();
    445 }
    446 
    447 
    448 static int
    449 strginit(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