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