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