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