Home | History | Annotate | Line # | Download | only in lint1
init.c revision 1.16
      1 /*	$NetBSD: init.c,v 1.16 2002/11/13 21:50:57 christos 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 #if defined(__RCSID) && !defined(lint)
     36 __RCSID("$NetBSD: init.c,v 1.16 2002/11/13 21:50:57 christos Exp $");
     37 #endif
     38 
     39 #include <stdlib.h>
     40 #include <ctype.h>
     41 
     42 #include "lint1.h"
     43 
     44 /*
     45  * initerr is set as soon as a fatal error occurred in an initialisation.
     46  * The effect is that the rest of the initialisation is ignored (parsed
     47  * by yacc, expression trees built, but no initialisation takes place).
     48  */
     49 int	initerr;
     50 
     51 /* Pointer to the symbol which is to be initialized. */
     52 sym_t	*initsym;
     53 
     54 /* Points to the top element of the initialisation stack. */
     55 istk_t	*initstk;
     56 
     57 typedef struct namlist {
     58 	const char *n_name;
     59 	struct namlist *n_prev;
     60 	struct namlist *n_next;
     61 } namlist_t;
     62 
     63 /* Points to a c9x named member; */
     64 namlist_t	*namedmem = NULL;
     65 
     66 
     67 static	void	popi2(void);
     68 static	void	popinit(int);
     69 static	void	pushinit(void);
     70 static	void	testinit(void);
     71 static	void	nextinit(int);
     72 static	int	strginit(tnode_t *);
     73 static	void	memberpop(void);
     74 
     75 #ifndef DEBUG
     76 #define DPRINTF(a)
     77 #else
     78 #define DPRINTF(a) printf a
     79 #endif
     80 
     81 void
     82 memberpush(sb)
     83 	sbuf_t *sb;
     84 {
     85 	namlist_t *nam = xcalloc(1, sizeof (namlist_t));
     86 	nam->n_name = sb->sb_name;
     87 	DPRINTF(("memberpush = %s\n", nam->n_name));
     88 	if (namedmem == NULL) {
     89 		nam->n_prev = nam->n_next = nam;
     90 		namedmem = nam;
     91 	} else {
     92 		namedmem->n_prev->n_next = nam;
     93 		nam->n_prev = namedmem->n_prev;
     94 		nam->n_next = namedmem;
     95 		namedmem->n_prev = nam;
     96 	}
     97 #if 0
     98 	nam->n_next = namedmem;
     99 	namedmem = nam;
    100 #endif
    101 }
    102 
    103 static void
    104 memberpop()
    105 {
    106 	DPRINTF(("memberpop = %s\n", namedmem->n_name));
    107 	if (namedmem->n_next == namedmem) {
    108 		free(namedmem);
    109 		namedmem = NULL;
    110 	} else {
    111 		namlist_t *nam = namedmem;
    112 		namedmem = namedmem->n_next;
    113 		free(nam);
    114 	}
    115 #if 0
    116 	namedmem = namedmem->n_next;
    117 	free(nam);
    118 #endif
    119 }
    120 
    121 
    122 /*
    123  * Initialize the initialisation stack by putting an entry for the variable
    124  * which is to be initialized on it.
    125  */
    126 void
    127 prepinit(void)
    128 {
    129 	istk_t	*istk;
    130 
    131 	if (initerr)
    132 		return;
    133 
    134 	/* free memory used in last initialisation */
    135 	while ((istk = initstk) != NULL) {
    136 		initstk = istk->i_nxt;
    137 		free(istk);
    138 	}
    139 
    140 	/*
    141 	 * If the type which is to be initialized is an incomplete type,
    142 	 * it must be duplicated.
    143 	 */
    144 	if (initsym->s_type->t_tspec == ARRAY && incompl(initsym->s_type))
    145 		initsym->s_type = duptyp(initsym->s_type);
    146 
    147 	istk = initstk = xcalloc(1, sizeof (istk_t));
    148 	istk->i_subt = initsym->s_type;
    149 	istk->i_cnt = 1;
    150 
    151 }
    152 
    153 static void
    154 popi2(void)
    155 {
    156 #ifdef DEBUG
    157 	char	buf[64];
    158 #endif
    159 	istk_t	*istk;
    160 	sym_t	*m;
    161 
    162 	initstk = (istk = initstk)->i_nxt;
    163 	if (initstk == NULL)
    164 		LERROR("popi2()");
    165 	free(istk);
    166 
    167 	istk = initstk;
    168 
    169 	istk->i_cnt--;
    170 	if (istk->i_cnt < 0)
    171 		LERROR("popi2()");
    172 
    173 	DPRINTF(("popi2(): %d %s\n", istk->i_cnt,
    174 	    namedmem ? namedmem->n_name : "*null*"));
    175 	if (istk->i_cnt >= 0 && namedmem != NULL) {
    176 		DPRINTF(("popi2(): %d %s %s\n", istk->i_cnt,
    177 		    tyname(buf, sizeof(buf), istk->i_type), namedmem->n_name));
    178 		for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) {
    179 			if (m->s_field && m->s_name == unnamed)
    180 				continue;
    181 			if (strcmp(m->s_name, namedmem->n_name) == 0) {
    182 				istk->i_subt = m->s_type;
    183 				istk->i_cnt++;
    184 				memberpop();
    185 				return;
    186 			}
    187 		}
    188 		error(101, namedmem->n_name);
    189 		memberpop();
    190 		istk->i_namedmem = 1;
    191 		return;
    192 	}
    193 	/*
    194 	 * If the removed element was a structure member, we must go
    195 	 * to the next structure member.
    196 	 */
    197 	if (istk->i_cnt > 0 && istk->i_type->t_tspec == STRUCT &&
    198 	    !istk->i_namedmem) {
    199 		do {
    200 			m = istk->i_mem = istk->i_mem->s_nxt;
    201 			if (m == NULL)
    202 				LERROR("popi2()");
    203 		} while (m->s_field && m->s_name == unnamed);
    204 		istk->i_subt = m->s_type;
    205 	}
    206 }
    207 
    208 static void
    209 popinit(int brace)
    210 {
    211 	DPRINTF(("popinit(%d)\n", brace));
    212 
    213 	if (brace) {
    214 		/*
    215 		 * Take all entries, including the first which requires
    216 		 * a closing brace, from the stack.
    217 		 */
    218 		do {
    219 			brace = initstk->i_brace;
    220 			popi2();
    221 		} while (!brace);
    222 	} else {
    223 		/*
    224 		 * Take all entries which cannot be used for further
    225 		 * initializers from the stack, but do this only if
    226 		 * they do not require a closing brace.
    227 		 */
    228 		while (!initstk->i_brace &&
    229 		       initstk->i_cnt == 0 && !initstk->i_nolimit) {
    230 			popi2();
    231 		}
    232 	}
    233 }
    234 
    235 static void
    236 pushinit(void)
    237 {
    238 #ifdef DEBUG
    239 	char	buf[64];
    240 #endif
    241 	istk_t	*istk;
    242 	int	cnt;
    243 	sym_t	*m;
    244 
    245 	istk = initstk;
    246 
    247 	/* Extend an incomplete array type by one element */
    248 	if (istk->i_cnt == 0) {
    249 		DPRINTF(("pushinit(extend) %s\n", tyname(buf, sizeof(buf),
    250 		    istk->i_type)));
    251 		/*
    252 		 * Inside of other aggregate types must not be an incomplete
    253 		 * type.
    254 		 */
    255 		if (istk->i_nxt->i_nxt != NULL)
    256 			LERROR("pushinit()");
    257 		istk->i_cnt = 1;
    258 		if (istk->i_type->t_tspec != ARRAY)
    259 			LERROR("pushinit()");
    260 		istk->i_type->t_dim++;
    261 		/* from now its an complete type */
    262 		setcompl(istk->i_type, 0);
    263 	}
    264 
    265 	if (istk->i_cnt <= 0)
    266 		LERROR("pushinit()");
    267 	if (istk->i_type != NULL && issclt(istk->i_type->t_tspec))
    268 		LERROR("pushinit()");
    269 
    270 	initstk = xcalloc(1, sizeof (istk_t));
    271 	initstk->i_nxt = istk;
    272 	initstk->i_type = istk->i_subt;
    273 	if (initstk->i_type->t_tspec == FUNC)
    274 		LERROR("pushinit()");
    275 
    276 again:
    277 	istk = initstk;
    278 
    279 	DPRINTF(("pushinit(%s)\n", tyname(buf, sizeof(buf), istk->i_type)));
    280 	switch (istk->i_type->t_tspec) {
    281 	case ARRAY:
    282 		if (namedmem) {
    283 			DPRINTF(("pushinit ARRAY %s\n", namedmem->n_name));
    284 			free(istk);
    285 			initstk = initstk->i_nxt;
    286 			goto again;
    287 		}
    288 		if (incompl(istk->i_type) && istk->i_nxt->i_nxt != NULL) {
    289 			/* initialisation of an incomplete type */
    290 			error(175);
    291 			initerr = 1;
    292 			return;
    293 		}
    294 		istk->i_subt = istk->i_type->t_subt;
    295 		istk->i_nolimit = incompl(istk->i_type);
    296 		istk->i_cnt = istk->i_type->t_dim;
    297 		DPRINTF(("elements array %s[%d] %s\n",
    298 		    tyname(buf, sizeof(buf), istk->i_subt), istk->i_cnt,
    299 		    namedmem ? namedmem->n_name : "*none*"));
    300 		break;
    301 	case UNION:
    302 		if (tflag)
    303 			/* initialisation of union is illegal in trad. C */
    304 			warning(238);
    305 		/* FALLTHROUGH */
    306 	case STRUCT:
    307 		if (incompl(istk->i_type)) {
    308 			/* initialisation of an incomplete type */
    309 			error(175);
    310 			initerr = 1;
    311 			return;
    312 		}
    313 		cnt = 0;
    314 		DPRINTF(("2. member lookup %s %s\n",
    315 		    tyname(buf, sizeof(buf), istk->i_type),
    316 		    namedmem ? namedmem->n_name : "*none*"));
    317 		for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) {
    318 			if (m->s_field && m->s_name == unnamed)
    319 				continue;
    320 			if (namedmem != NULL) {
    321 				DPRINTF(("pushinit():[member:%s, looking:%s]\n",
    322 				    m->s_name, namedmem->n_name));
    323 				if (strcmp(m->s_name, namedmem->n_name) == 0) {
    324 					cnt++;
    325 					break;
    326 				} else
    327 					continue;
    328 			}
    329 			if (++cnt == 1) {
    330 				istk->i_mem = m;
    331 				istk->i_subt = m->s_type;
    332 			}
    333 		}
    334 		if (namedmem != NULL) {
    335 			istk->i_namedmem = 1;
    336 			if (m == NULL) {
    337 				error(101, namedmem->n_name);
    338 				initerr = 1;
    339 			} else {
    340 				istk->i_mem = m;
    341 				istk->i_subt = m->s_type;
    342 			}
    343 			memberpop();
    344 			cnt = istk->i_type->t_tspec == STRUCT ? 2 : 1;
    345 		}
    346 		if (cnt == 0) {
    347 			/* cannot init. struct/union with no named member */
    348 			error(179);
    349 			initerr = 1;
    350 			return;
    351 		}
    352 		istk->i_cnt = istk->i_type->t_tspec == STRUCT ? cnt : 1;
    353 		break;
    354 	default:
    355 		if (namedmem) {
    356 			DPRINTF(("pushinit(): pop\n"));
    357 			free(istk);
    358 			initstk = initstk->i_nxt;
    359 			goto again;
    360 		}
    361 		istk->i_cnt = 1;
    362 		break;
    363 	}
    364 }
    365 
    366 static void
    367 testinit(void)
    368 {
    369 	istk_t	*istk;
    370 
    371 	istk = initstk;
    372 
    373 	/*
    374 	 * If a closing brace is expected we have at least one initializer
    375 	 * too much.
    376 	 */
    377 	if (istk->i_cnt == 0 && !istk->i_nolimit && !istk->i_namedmem) {
    378 		switch (istk->i_type->t_tspec) {
    379 		case ARRAY:
    380 			/* too many array initializers */
    381 			error(173);
    382 			break;
    383 		case STRUCT:
    384 		case UNION:
    385 			/* too many struct/union initializers */
    386 			error(172);
    387 			break;
    388 		default:
    389 			/* too many initializers */
    390 			error(174);
    391 			break;
    392 		}
    393 		initerr = 1;
    394 	}
    395 }
    396 
    397 static void
    398 nextinit(int brace)
    399 {
    400 	char buf[64];
    401 
    402 	DPRINTF(("nextinit(%d)\n", brace));
    403 	if (!brace) {
    404 		if (initstk->i_type == NULL &&
    405 		    !issclt(initstk->i_subt->t_tspec)) {
    406 			/* {}-enclosed initializer required */
    407 			error(181);
    408 		}
    409 		/*
    410 		 * Make sure an entry with a scalar type is at the top
    411 		 * of the stack.
    412 		 */
    413 		if (!initerr)
    414 			testinit();
    415 		while (!initerr && (initstk->i_type == NULL ||
    416 				    !issclt(initstk->i_type->t_tspec))) {
    417 			if (!initerr)
    418 				pushinit();
    419 		}
    420 	} else {
    421 		if (initstk->i_type != NULL &&
    422 		    issclt(initstk->i_type->t_tspec)) {
    423 			/* invalid initializer */
    424 			error(176, tyname(buf, sizeof(buf), initstk->i_type));
    425 			initerr = 1;
    426 		}
    427 		if (!initerr)
    428 			testinit();
    429 		if (!initerr)
    430 			pushinit();
    431 		if (!initerr)
    432 			initstk->i_brace = 1;
    433 	}
    434 }
    435 
    436 void
    437 initlbr(void)
    438 {
    439 
    440 	if (initerr)
    441 		return;
    442 
    443 	if ((initsym->s_scl == AUTO || initsym->s_scl == REG) &&
    444 	    initstk->i_nxt == NULL) {
    445 		if (tflag && !issclt(initstk->i_subt->t_tspec))
    446 			/* no automatic aggregate initialization in trad. C*/
    447 			warning(188);
    448 	}
    449 
    450 	/*
    451 	 * Remove all entries which cannot be used for further initializers
    452 	 * and do not expect a closing brace.
    453 	 */
    454 	popinit(0);
    455 
    456 	nextinit(1);
    457 }
    458 
    459 void
    460 initrbr(void)
    461 {
    462 
    463 	if (initerr)
    464 		return;
    465 
    466 	popinit(1);
    467 }
    468 
    469 void
    470 mkinit(tnode_t *tn)
    471 {
    472 	ptrdiff_t offs;
    473 	sym_t	*sym;
    474 	tspec_t	lt, rt;
    475 	tnode_t	*ln;
    476 	struct	mbl *tmem;
    477 	scl_t	sc;
    478 #ifdef DEBUG
    479 	char	buf[64];
    480 #endif
    481 
    482 	DPRINTF(("mkinit(%s)\n", tyname(buf, sizeof(buf), tn->tn_type)));
    483 	if (initerr || tn == NULL)
    484 		goto end;
    485 
    486 	sc = initsym->s_scl;
    487 
    488 	/*
    489 	 * Do not test for automatic aggregate initialisation. If the
    490 	 * initializer starts with a brace we have the warning already.
    491 	 * If not, an error will be printed that the initializer must
    492 	 * be enclosed by braces.
    493 	 */
    494 
    495 	/*
    496 	 * Local initialisation of non-array-types with only one expression
    497 	 * without braces is done by ASSIGN
    498 	 */
    499 	if ((sc == AUTO || sc == REG) &&
    500 	    initsym->s_type->t_tspec != ARRAY && initstk->i_nxt == NULL) {
    501 		ln = getnnode(initsym, 0);
    502 		ln->tn_type = tduptyp(ln->tn_type);
    503 		ln->tn_type->t_const = 0;
    504 		tn = build(ASSIGN, ln, tn);
    505 		expr(tn, 0, 0, 1);
    506 		goto end;
    507 	}
    508 
    509 	/*
    510 	 * Remove all entries which cannot be used for further initializers
    511 	 * and do not require a closing brace.
    512 	 */
    513 	popinit(0);
    514 
    515 	/* Initialisations by strings are done in strginit(). */
    516 	if (strginit(tn))
    517 		goto end;
    518 
    519 	nextinit(0);
    520 	if (initerr || tn == NULL)
    521 		goto end;
    522 
    523 	initstk->i_cnt--;
    524 	DPRINTF(("mkinit() cnt=%d tn=%p\n", initstk->i_cnt, tn));
    525 	/* Create a temporary node for the left side. */
    526 	ln = tgetblk(sizeof (tnode_t));
    527 	ln->tn_op = NAME;
    528 	ln->tn_type = tduptyp(initstk->i_type);
    529 	ln->tn_type->t_const = 0;
    530 	ln->tn_lvalue = 1;
    531 	ln->tn_sym = initsym;		/* better than nothing */
    532 
    533 	tn = cconv(tn);
    534 
    535 	lt = ln->tn_type->t_tspec;
    536 	rt = tn->tn_type->t_tspec;
    537 
    538 	if (!issclt(lt))
    539 		LERROR("mkinit()");
    540 
    541 	if (!typeok(INIT, 0, ln, tn))
    542 		goto end;
    543 
    544 	/*
    545 	 * Store the tree memory. This is nessesary because otherwise
    546 	 * expr() would free it.
    547 	 */
    548 	tmem = tsave();
    549 	expr(tn, 1, 0, 1);
    550 	trestor(tmem);
    551 
    552 	if (isityp(lt) && ln->tn_type->t_isfield && !isityp(rt)) {
    553 		/*
    554 		 * Bit-fields can be initialized in trad. C only by integer
    555 		 * constants.
    556 		 */
    557 		if (tflag)
    558 			/* bit-field initialisation is illegal in trad. C */
    559 			warning(186);
    560 	}
    561 
    562 	if (lt != rt || (initstk->i_type->t_isfield && tn->tn_op == CON))
    563 		tn = convert(INIT, 0, initstk->i_type, tn);
    564 
    565 	if (tn != NULL && tn->tn_op != CON) {
    566 		sym = NULL;
    567 		offs = 0;
    568 		if (conaddr(tn, &sym, &offs) == -1) {
    569 			if (sc == AUTO || sc == REG) {
    570 				/* non-constant initializer */
    571 				(void)gnuism(177);
    572 			} else {
    573 				/* non-constant initializer */
    574 				error(177);
    575 			}
    576 		}
    577 	}
    578 
    579  end:
    580 	/*
    581 	 * We only free the block, if we are not a compound declaration
    582 	 * We know that the only symbols that start with a digit are the
    583 	 * ones we allocate with mktempsym() for compound declarations
    584 	 */
    585 	if (!isdigit((unsigned char)initsym->s_name[0]))
    586 		tfreeblk();
    587 }
    588 
    589 
    590 static int
    591 strginit(tnode_t *tn)
    592 {
    593 	tspec_t	t;
    594 	istk_t	*istk;
    595 	int	len;
    596 	strg_t	*strg;
    597 
    598 	if (tn->tn_op != STRING)
    599 		return (0);
    600 
    601 	istk = initstk;
    602 	strg = tn->tn_strg;
    603 
    604 	/*
    605 	 * Check if we have an array type which can be initialized by
    606 	 * the string.
    607 	 */
    608 	if (istk->i_subt != NULL && istk->i_subt->t_tspec == ARRAY) {
    609 		t = istk->i_subt->t_subt->t_tspec;
    610 		if (!((strg->st_tspec == CHAR &&
    611 		       (t == CHAR || t == UCHAR || t == SCHAR)) ||
    612 		      (strg->st_tspec == WCHAR && t == WCHAR))) {
    613 			return (0);
    614 		}
    615 		/* Put the array at top of stack */
    616 		pushinit();
    617 		istk = initstk;
    618 	} else if (istk->i_type != NULL && istk->i_type->t_tspec == ARRAY) {
    619 		t = istk->i_type->t_subt->t_tspec;
    620 		if (!((strg->st_tspec == CHAR &&
    621 		       (t == CHAR || t == UCHAR || t == SCHAR)) ||
    622 		      (strg->st_tspec == WCHAR && t == WCHAR))) {
    623 			return (0);
    624 		}
    625 		/*
    626 		 * If the array is already partly initialized, we are
    627 		 * wrong here.
    628 		 */
    629 		if (istk->i_cnt != istk->i_type->t_dim)
    630 			return (0);
    631 	} else {
    632 		return (0);
    633 	}
    634 
    635 	/* Get length without trailing NUL character. */
    636 	len = strg->st_len;
    637 
    638 	if (istk->i_nolimit) {
    639 		istk->i_nolimit = 0;
    640 		istk->i_type->t_dim = len + 1;
    641 		/* from now complete type */
    642 		setcompl(istk->i_type, 0);
    643 	} else {
    644 		if (istk->i_type->t_dim < len) {
    645 			/* non-null byte ignored in string initializer */
    646 			warning(187);
    647 		}
    648 	}
    649 
    650 	/* In every case the array is initialized completely. */
    651 	istk->i_cnt = 0;
    652 
    653 	return (1);
    654 }
    655