1 /* $NetBSD: tree.c,v 1.70 2012/03/27 19:24:03 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: tree.c,v 1.70 2012/03/27 19:24:03 christos Exp $"); 41 #endif 42 43 #include <stdlib.h> 44 #include <string.h> 45 #include <float.h> 46 #include <limits.h> 47 #include <math.h> 48 #include <signal.h> 49 50 #include "lint1.h" 51 #include "cgram.h" 52 #include "externs1.h" 53 54 static tnode_t *getinode(tspec_t, int64_t); 55 static void ptrcmpok(op_t, tnode_t *, tnode_t *); 56 static int asgntypok(op_t, int, tnode_t *, tnode_t *); 57 static void chkbeop(op_t, tnode_t *, tnode_t *); 58 static void chkeop2(op_t, int, tnode_t *, tnode_t *); 59 static void chkeop1(op_t, int, tnode_t *, tnode_t *); 60 static tnode_t *mktnode(op_t, type_t *, tnode_t *, tnode_t *); 61 static void balance(op_t, tnode_t **, tnode_t **); 62 static void incompat(op_t, tspec_t, tspec_t); 63 static void illptrc(mod_t *, type_t *, type_t *); 64 static void mrgqual(type_t **, type_t *, type_t *); 65 static int conmemb(type_t *); 66 static void ptconv(int, tspec_t, tspec_t, type_t *, tnode_t *); 67 static void iiconv(op_t, int, tspec_t, tspec_t, type_t *, tnode_t *); 68 static void piconv(op_t, tspec_t, type_t *, tnode_t *); 69 static void ppconv(op_t, tnode_t *, type_t *); 70 static tnode_t *bldstr(op_t, tnode_t *, tnode_t *); 71 static tnode_t *bldincdec(op_t, tnode_t *); 72 static tnode_t *bldri(op_t, tnode_t *); 73 static tnode_t *bldamper(tnode_t *, int); 74 static tnode_t *bldplmi(op_t, tnode_t *, tnode_t *); 75 static tnode_t *bldshft(op_t, tnode_t *, tnode_t *); 76 static tnode_t *bldcol(tnode_t *, tnode_t *); 77 static tnode_t *bldasgn(op_t, tnode_t *, tnode_t *); 78 static tnode_t *plength(type_t *); 79 static tnode_t *fold(tnode_t *); 80 static tnode_t *foldtst(tnode_t *); 81 static tnode_t *foldflt(tnode_t *); 82 static tnode_t *chkfarg(type_t *, tnode_t *); 83 static tnode_t *parg(int, type_t *, tnode_t *); 84 static void nulleff(tnode_t *); 85 static void displexpr(tnode_t *, int); 86 static void chkaidx(tnode_t *, int); 87 static void chkcomp(op_t, tnode_t *, tnode_t *); 88 static void precconf(tnode_t *); 89 90 extern sig_atomic_t fpe; 91 92 /* 93 * Increase degree of reference. 94 * This is most often used to change type "T" in type "pointer to T". 95 */ 96 type_t * 97 incref(type_t *tp, tspec_t t) 98 { 99 type_t *tp2; 100 101 tp2 = getblk(sizeof (type_t)); 102 tp2->t_tspec = t; 103 tp2->t_subt = tp; 104 return (tp2); 105 } 106 107 /* 108 * same for use in expressions 109 */ 110 type_t * 111 tincref(type_t *tp, tspec_t t) 112 { 113 type_t *tp2; 114 115 tp2 = tgetblk(sizeof (type_t)); 116 tp2->t_tspec = t; 117 tp2->t_subt = tp; 118 return (tp2); 119 } 120 121 /* 122 * Create a node for a constant. 123 */ 124 tnode_t * 125 getcnode(type_t *tp, val_t *v) 126 { 127 tnode_t *n; 128 129 n = getnode(); 130 n->tn_op = CON; 131 n->tn_type = tp; 132 n->tn_val = tgetblk(sizeof (val_t)); 133 n->tn_val->v_tspec = tp->t_tspec; 134 n->tn_val->v_ansiu = v->v_ansiu; 135 n->tn_val->v_u = v->v_u; 136 free(v); 137 return (n); 138 } 139 140 /* 141 * Create a node for a integer constant. 142 */ 143 static tnode_t * 144 getinode(tspec_t t, int64_t q) 145 { 146 tnode_t *n; 147 148 n = getnode(); 149 n->tn_op = CON; 150 n->tn_type = gettyp(t); 151 n->tn_val = tgetblk(sizeof (val_t)); 152 n->tn_val->v_tspec = t; 153 n->tn_val->v_quad = q; 154 return (n); 155 } 156 157 /* 158 * Create a node for a name (symbol table entry). 159 * ntok is the token which follows the name. 160 */ 161 tnode_t * 162 getnnode(sym_t *sym, int ntok) 163 { 164 tnode_t *n; 165 166 if (sym->s_scl == NOSCL) { 167 sym->s_scl = EXTERN; 168 sym->s_def = DECL; 169 if (ntok == T_LPARN) { 170 if (sflag) { 171 /* function implicitly declared to ... */ 172 warning(215); 173 } 174 /* 175 * XXX if tflag is set the symbol should be 176 * exported to level 0 177 */ 178 sym->s_type = incref(sym->s_type, FUNC); 179 } else { 180 if (!blklev) { 181 /* %s undefined */ 182 error(99, sym->s_name); 183 } else { 184 int fixtype; 185 if (strcmp(sym->s_name, "__FUNCTION__") == 0) { 186 gnuism(316); 187 fixtype = 1; 188 } else if (strcmp(sym->s_name, "__func__") == 0) { 189 if (!Sflag) 190 warning(317); 191 fixtype = 1; 192 } else { 193 error(99, sym->s_name); 194 fixtype = 0; 195 } 196 if (fixtype) { 197 sym->s_type = incref(gettyp(CHAR), PTR); 198 sym->s_type->t_const = 1; 199 } 200 } 201 } 202 } 203 204 if (sym->s_kind != FVFT && sym->s_kind != FMOS) 205 LERROR("getnnode()"); 206 207 n = getnode(); 208 n->tn_type = sym->s_type; 209 if (sym->s_scl != ENUMCON) { 210 n->tn_op = NAME; 211 n->tn_sym = sym; 212 if (sym->s_kind == FVFT && sym->s_type->t_tspec != FUNC) 213 n->tn_lvalue = 1; 214 } else { 215 n->tn_op = CON; 216 n->tn_val = tgetblk(sizeof (val_t)); 217 *n->tn_val = sym->s_value; 218 } 219 220 return (n); 221 } 222 223 /* 224 * Create a node for a string. 225 */ 226 tnode_t * 227 getsnode(strg_t *strg) 228 { 229 size_t len; 230 tnode_t *n; 231 232 len = strg->st_len; 233 234 n = getnode(); 235 236 n->tn_op = STRING; 237 n->tn_type = tincref(gettyp(strg->st_tspec), ARRAY); 238 n->tn_type->t_dim = len + 1; 239 n->tn_lvalue = 1; 240 241 n->tn_strg = tgetblk(sizeof (strg_t)); 242 n->tn_strg->st_tspec = strg->st_tspec; 243 n->tn_strg->st_len = len; 244 245 if (strg->st_tspec == CHAR) { 246 n->tn_strg->st_cp = tgetblk(len + 1); 247 (void)memcpy(n->tn_strg->st_cp, strg->st_cp, len + 1); 248 free(strg->st_cp); 249 } else { 250 n->tn_strg->st_wcp = tgetblk((len + 1) * sizeof (wchar_t)); 251 (void)memcpy(n->tn_strg->st_wcp, strg->st_wcp, 252 (len + 1) * sizeof (wchar_t)); 253 free(strg->st_wcp); 254 } 255 free(strg); 256 257 return (n); 258 } 259 260 /* 261 * Returns a symbol which has the same name as the msym argument and is a 262 * member of the struct or union specified by the tn argument. 263 */ 264 sym_t * 265 strmemb(tnode_t *tn, op_t op, sym_t *msym) 266 { 267 str_t *str; 268 type_t *tp; 269 sym_t *sym, *csym; 270 int eq; 271 tspec_t t; 272 273 /* 274 * Remove the member if it was unknown until now (Which means 275 * that no defined struct or union has a member with the same name). 276 */ 277 if (msym->s_scl == NOSCL) { 278 /* undefined struct/union member: %s */ 279 error(101, msym->s_name); 280 rmsym(msym); 281 msym->s_kind = FMOS; 282 msym->s_scl = MOS; 283 msym->s_styp = tgetblk(sizeof (str_t)); 284 msym->s_styp->stag = tgetblk(sizeof (sym_t)); 285 msym->s_styp->stag->s_name = unnamed; 286 msym->s_value.v_tspec = INT; 287 return (msym); 288 } 289 290 /* Set str to the tag of which msym is expected to be a member. */ 291 str = NULL; 292 t = (tp = tn->tn_type)->t_tspec; 293 if (op == POINT) { 294 if (t == STRUCT || t == UNION) 295 str = tp->t_str; 296 } else if (op == ARROW && t == PTR) { 297 t = (tp = tp->t_subt)->t_tspec; 298 if (t == STRUCT || t == UNION) 299 str = tp->t_str; 300 } 301 302 /* 303 * If this struct/union has a member with the name of msym, return 304 * return this it. 305 */ 306 if (str != NULL) { 307 for (sym = msym; sym != NULL; sym = sym->s_link) { 308 if (sym->s_scl != MOS && sym->s_scl != MOU) 309 continue; 310 if (sym->s_styp != str) 311 continue; 312 if (strcmp(sym->s_name, msym->s_name) != 0) 313 continue; 314 return (sym); 315 } 316 } 317 318 /* 319 * Set eq to 0 if there are struct/union members with the same name 320 * and different types and/or offsets. 321 */ 322 eq = 1; 323 for (csym = msym; csym != NULL; csym = csym->s_link) { 324 if (csym->s_scl != MOS && csym->s_scl != MOU) 325 continue; 326 if (strcmp(msym->s_name, csym->s_name) != 0) 327 continue; 328 for (sym = csym->s_link ; sym != NULL; sym = sym->s_link) { 329 int w; 330 331 if (sym->s_scl != MOS && sym->s_scl != MOU) 332 continue; 333 if (strcmp(csym->s_name, sym->s_name) != 0) 334 continue; 335 if (csym->s_value.v_quad != sym->s_value.v_quad) { 336 eq = 0; 337 break; 338 } 339 w = 0; 340 eq = eqtype(csym->s_type, sym->s_type, 0, 0, &w) && !w; 341 if (!eq) 342 break; 343 if (csym->s_field != sym->s_field) { 344 eq = 0; 345 break; 346 } 347 if (csym->s_field) { 348 type_t *tp1, *tp2; 349 350 tp1 = csym->s_type; 351 tp2 = sym->s_type; 352 if (tp1->t_flen != tp2->t_flen) { 353 eq = 0; 354 break; 355 } 356 if (tp1->t_foffs != tp2->t_foffs) { 357 eq = 0; 358 break; 359 } 360 } 361 } 362 if (!eq) 363 break; 364 } 365 366 /* 367 * Now handle the case in which the left operand refers really 368 * to a struct/union, but the right operand is not member of it. 369 */ 370 if (str != NULL) { 371 /* illegal member use: %s */ 372 if (eq && tflag) { 373 warning(102, msym->s_name); 374 } else { 375 error(102, msym->s_name); 376 } 377 return (msym); 378 } 379 380 /* 381 * Now the left operand of ARROW does not point to a struct/union 382 * or the left operand of POINT is no struct/union. 383 */ 384 if (eq) { 385 if (op == POINT) { 386 /* left operand of "." must be struct/union object */ 387 if (tflag) { 388 warning(103); 389 } else { 390 error(103); 391 } 392 } else { 393 /* left operand of "->" must be pointer to ... */ 394 if (tflag && tn->tn_type->t_tspec == PTR) { 395 warning(104); 396 } else { 397 error(104); 398 } 399 } 400 } else { 401 if (tflag) { 402 /* non-unique member requires struct/union %s */ 403 error(105, op == POINT ? "object" : "pointer"); 404 } else { 405 /* unacceptable operand of %s */ 406 error(111, modtab[op].m_name); 407 } 408 } 409 410 return (msym); 411 } 412 413 /* 414 * Create a tree node. Called for most operands except function calls, 415 * sizeof and casts. 416 * 417 * op operator 418 * ln left operand 419 * rn if not NULL, right operand 420 */ 421 tnode_t * 422 build(op_t op, tnode_t *ln, tnode_t *rn) 423 { 424 mod_t *mp; 425 tnode_t *ntn; 426 type_t *rtp; 427 428 mp = &modtab[op]; 429 430 /* If there was an error in one of the operands, return. */ 431 if (ln == NULL || (mp->m_binary && rn == NULL)) 432 return (NULL); 433 434 /* 435 * Apply class conversions to the left operand, but only if its 436 * value is needed or it is compaired with null. 437 */ 438 if (mp->m_vctx || mp->m_tctx) 439 ln = cconv(ln); 440 /* 441 * The right operand is almost always in a test or value context, 442 * except if it is a struct or union member. 443 */ 444 if (mp->m_binary && op != ARROW && op != POINT) 445 rn = cconv(rn); 446 447 /* 448 * Print some warnings for comparisons of unsigned values with 449 * constants lower than or equal to null. This must be done 450 * before promote() because otherwise unsigned char and unsigned 451 * short would be promoted to int. Also types are tested to be 452 * CHAR, which would also become int. 453 */ 454 if (mp->m_comp) 455 chkcomp(op, ln, rn); 456 457 /* 458 * Promote the left operand if it is in a test or value context 459 */ 460 if (mp->m_vctx || mp->m_tctx) 461 ln = promote(op, 0, ln); 462 /* 463 * Promote the right operand, but only if it is no struct or 464 * union member, or if it is not to be assigned to the left operand 465 */ 466 if (mp->m_binary && op != ARROW && op != POINT && 467 op != ASSIGN && op != RETURN) { 468 rn = promote(op, 0, rn); 469 } 470 471 /* 472 * If the result of the operation is different for signed or 473 * unsigned operands and one of the operands is signed only in 474 * ANSI C, print a warning. 475 */ 476 if (mp->m_tlansiu && ln->tn_op == CON && ln->tn_val->v_ansiu) { 477 /* ANSI C treats constant as unsigned, op %s */ 478 warning(218, mp->m_name); 479 ln->tn_val->v_ansiu = 0; 480 } 481 if (mp->m_transiu && rn->tn_op == CON && rn->tn_val->v_ansiu) { 482 /* ANSI C treats constant as unsigned, op %s */ 483 warning(218, mp->m_name); 484 rn->tn_val->v_ansiu = 0; 485 } 486 487 /* Make sure both operands are of the same type */ 488 if (mp->m_balance || (tflag && (op == SHL || op == SHR))) 489 balance(op, &ln, &rn); 490 491 /* 492 * Check types for compatibility with the operation and mutual 493 * compatibility. Return if there are serios problems. 494 */ 495 if (!typeok(op, 0, ln, rn)) 496 return (NULL); 497 498 /* And now create the node. */ 499 switch (op) { 500 case POINT: 501 case ARROW: 502 ntn = bldstr(op, ln, rn); 503 break; 504 case INCAFT: 505 case DECAFT: 506 case INCBEF: 507 case DECBEF: 508 ntn = bldincdec(op, ln); 509 break; 510 case AMPER: 511 ntn = bldamper(ln, 0); 512 break; 513 case STAR: 514 ntn = mktnode(STAR, ln->tn_type->t_subt, ln, NULL); 515 break; 516 case PLUS: 517 case MINUS: 518 ntn = bldplmi(op, ln, rn); 519 break; 520 case SHL: 521 case SHR: 522 ntn = bldshft(op, ln, rn); 523 break; 524 case COLON: 525 ntn = bldcol(ln, rn); 526 break; 527 case ASSIGN: 528 case MULASS: 529 case DIVASS: 530 case MODASS: 531 case ADDASS: 532 case SUBASS: 533 case SHLASS: 534 case SHRASS: 535 case ANDASS: 536 case XORASS: 537 case ORASS: 538 case RETURN: 539 ntn = bldasgn(op, ln, rn); 540 break; 541 case COMMA: 542 case QUEST: 543 ntn = mktnode(op, rn->tn_type, ln, rn); 544 break; 545 case REAL: 546 case IMAG: 547 ntn = bldri(op, ln); 548 break; 549 default: 550 rtp = mp->m_logop ? gettyp(INT) : ln->tn_type; 551 if (!mp->m_binary && rn != NULL) 552 LERROR("build()"); 553 ntn = mktnode(op, rtp, ln, rn); 554 break; 555 } 556 557 /* Return if an error occurred. */ 558 if (ntn == NULL) 559 return (NULL); 560 561 /* Print a warning if precedence confusion is possible */ 562 if (mp->m_tpconf) 563 precconf(ntn); 564 565 /* 566 * Print a warning if one of the operands is in a context where 567 * it is compared with null and if this operand is a constant. 568 */ 569 if (mp->m_tctx) { 570 if (ln->tn_op == CON || 571 ((mp->m_binary && op != QUEST) && rn->tn_op == CON)) { 572 if (hflag && !ccflg) 573 /* constant in conditional context */ 574 warning(161); 575 } 576 } 577 578 /* Fold if the operator requires it */ 579 if (mp->m_fold) { 580 if (ln->tn_op == CON && (!mp->m_binary || rn->tn_op == CON)) { 581 if (mp->m_tctx) { 582 ntn = foldtst(ntn); 583 } else if (isftyp(ntn->tn_type->t_tspec)) { 584 ntn = foldflt(ntn); 585 } else { 586 ntn = fold(ntn); 587 } 588 } else if (op == QUEST && ln->tn_op == CON) { 589 ntn = ln->tn_val->v_quad ? rn->tn_left : rn->tn_right; 590 } 591 } 592 593 return (ntn); 594 } 595 596 /* 597 * Perform class conversions. 598 * 599 * Arrays of type T are converted into pointers to type T. 600 * Functions are converted to pointers to functions. 601 * Lvalues are converted to rvalues. 602 */ 603 tnode_t * 604 cconv(tnode_t *tn) 605 { 606 type_t *tp; 607 608 /* 609 * Array-lvalue (array of type T) is converted into rvalue 610 * (pointer to type T) 611 */ 612 if (tn->tn_type->t_tspec == ARRAY) { 613 if (!tn->tn_lvalue) { 614 /* %soperand of '%s' must be lvalue */ 615 /* XXX print correct operator */ 616 (void)gnuism(114, "", modtab[AMPER].m_name); 617 } 618 tn = mktnode(AMPER, tincref(tn->tn_type->t_subt, PTR), 619 tn, NULL); 620 } 621 622 /* 623 * Expression of type function (function with return value of type T) 624 * in rvalue-expression (pointer to function with return value 625 * of type T) 626 */ 627 if (tn->tn_type->t_tspec == FUNC) 628 tn = bldamper(tn, 1); 629 630 /* lvalue to rvalue */ 631 if (tn->tn_lvalue) { 632 tp = tduptyp(tn->tn_type); 633 tp->t_const = tp->t_volatile = 0; 634 tn = mktnode(LOAD, tp, tn, NULL); 635 } 636 637 return (tn); 638 } 639 640 /* 641 * Perform most type checks. First the types are checked using 642 * informations from modtab[]. After that it is done by hand for 643 * more complicated operators and type combinations. 644 * 645 * If the types are ok, typeok() returns 1, otherwise 0. 646 */ 647 int 648 typeok(op_t op, int arg, tnode_t *ln, tnode_t *rn) 649 { 650 mod_t *mp; 651 tspec_t lt, rt = NOTSPEC, lst = NOTSPEC, rst = NOTSPEC, olt = NOTSPEC, 652 ort = NOTSPEC; 653 type_t *ltp, *rtp = NULL, *lstp = NULL, *rstp = NULL; 654 tnode_t *tn; 655 656 mp = &modtab[op]; 657 658 if ((ltp = ln->tn_type) == NULL) 659 LERROR("typeok()"); 660 661 if ((lt = ltp->t_tspec) == PTR) 662 lst = (lstp = ltp->t_subt)->t_tspec; 663 if (mp->m_binary) { 664 if ((rtp = rn->tn_type) == NULL) 665 LERROR("typeok()"); 666 if ((rt = rtp->t_tspec) == PTR) 667 rst = (rstp = rtp->t_subt)->t_tspec; 668 } 669 670 if (mp->m_rqint) { 671 /* integertypes required */ 672 if (!isityp(lt) || (mp->m_binary && !isityp(rt))) { 673 incompat(op, lt, rt); 674 return (0); 675 } 676 } else if (mp->m_rqintcomp) { 677 /* integertypes required */ 678 if ((!isityp(lt) && !isctyp(lt)) || 679 (mp->m_binary && (!isityp(rt) && !isctyp(rt)))) { 680 incompat(op, lt, rt); 681 return (0); 682 } 683 } else if (mp->m_rqsclt) { 684 /* scalar types required */ 685 if (!issclt(lt) || (mp->m_binary && !issclt(rt))) { 686 incompat(op, lt, rt); 687 return (0); 688 } 689 } else if (mp->m_rqatyp) { 690 /* arithmetic types required */ 691 if (!isatyp(lt) || (mp->m_binary && !isatyp(rt))) { 692 incompat(op, lt, rt); 693 return (0); 694 } 695 } 696 697 if (op == SHL || op == SHR || op == SHLASS || op == SHRASS) { 698 /* 699 * For these operations we need the types before promotion 700 * and balancing. 701 */ 702 for (tn=ln; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left) 703 continue; 704 olt = tn->tn_type->t_tspec; 705 for (tn=rn; tn->tn_op==CVT && !tn->tn_cast; tn=tn->tn_left) 706 continue; 707 ort = tn->tn_type->t_tspec; 708 } 709 710 switch (op) { 711 case POINT: 712 /* 713 * Most errors required by ANSI C are reported in strmemb(). 714 * Here we only must check for totaly wrong things. 715 */ 716 if (lt == FUNC || lt == VOID || ltp->t_isfield || 717 ((lt != STRUCT && lt != UNION) && !ln->tn_lvalue)) { 718 /* Without tflag we got already an error */ 719 if (tflag) 720 /* unacceptable operand of %s */ 721 error(111, mp->m_name); 722 return (0); 723 } 724 /* Now we have an object we can create a pointer to */ 725 break; 726 case ARROW: 727 if (lt != PTR && !(tflag && isityp(lt))) { 728 /* Without tflag we got already an error */ 729 if (tflag) 730 /* unacceptabel operand of %s */ 731 error(111, mp->m_name); 732 return (0); 733 } 734 break; 735 case INCAFT: 736 case DECAFT: 737 case INCBEF: 738 case DECBEF: 739 /* operands have scalar types (checked above) */ 740 if (!ln->tn_lvalue) { 741 if (ln->tn_op == CVT && ln->tn_cast && 742 ln->tn_left->tn_op == LOAD) { 743 /* a cast to non-ptr does not yield an lvalue */ 744 if (ln->tn_type->t_tspec == PTR) 745 break; 746 error(163); 747 } 748 /* %soperand of %s must be lvalue */ 749 error(114, "", mp->m_name); 750 return (0); 751 } else if (ltp->t_const) { 752 /* %soperand of %s must be modifiable lvalue */ 753 if (!tflag) 754 warning(115, "", mp->m_name); 755 } 756 break; 757 case AMPER: 758 if (lt == ARRAY || lt == FUNC) { 759 /* ok, a warning comes later (in bldamper()) */ 760 } else if (!ln->tn_lvalue) { 761 if (ln->tn_op == CVT && ln->tn_cast && 762 ln->tn_left->tn_op == LOAD) { 763 /* a cast to non-ptr does not yield an lvalue */ 764 if (ln->tn_type->t_tspec == PTR) 765 break; 766 error(163); 767 } 768 /* %soperand of %s must be lvalue */ 769 error(114, "", mp->m_name); 770 return (0); 771 } else if (issclt(lt)) { 772 if (ltp->t_isfield) { 773 /* cannot take address of bit-field */ 774 error(112); 775 return (0); 776 } 777 } else if (lt != STRUCT && lt != UNION) { 778 /* unacceptable operand of %s */ 779 error(111, mp->m_name); 780 return (0); 781 } 782 if (ln->tn_op == NAME && ln->tn_sym->s_reg) { 783 /* cannot take address of register %s */ 784 error(113, ln->tn_sym->s_name); 785 return (0); 786 } 787 break; 788 case STAR: 789 /* until now there were no type checks for this operator */ 790 if (lt != PTR) { 791 /* cannot dereference non-pointer type */ 792 error(96); 793 return (0); 794 } 795 break; 796 case PLUS: 797 /* operands have scalar types (checked above) */ 798 if ((lt == PTR && !isityp(rt)) || (rt == PTR && !isityp(lt))) { 799 incompat(op, lt, rt); 800 return (0); 801 } 802 break; 803 case MINUS: 804 /* operands have scalar types (checked above) */ 805 if (lt == PTR && (!isityp(rt) && rt != PTR)) { 806 incompat(op, lt, rt); 807 return (0); 808 } else if (rt == PTR && lt != PTR) { 809 incompat(op, lt, rt); 810 return (0); 811 } 812 if (lt == PTR && rt == PTR) { 813 if (!eqtype(lstp, rstp, 1, 0, NULL)) { 814 /* illegal pointer subtraction */ 815 error(116); 816 } 817 } 818 break; 819 case SHR: 820 /* operands have integer types (checked above) */ 821 if (pflag && !isutyp(lt)) { 822 /* 823 * The left operand is signed. This means that 824 * the operation is (possibly) nonportable. 825 */ 826 /* bitwise operation on signed value nonportable */ 827 if (ln->tn_op != CON) { 828 /* possibly nonportable */ 829 warning(117); 830 } else if (ln->tn_val->v_quad < 0) { 831 warning(120); 832 } 833 } else if (!tflag && !sflag && !isutyp(olt) && isutyp(ort)) { 834 /* 835 * The left operand would become unsigned in 836 * traditional C. 837 */ 838 if (hflag && 839 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 840 /* semantics of %s change in ANSI C; use ... */ 841 warning(118, mp->m_name); 842 } 843 } else if (!tflag && !sflag && !isutyp(olt) && !isutyp(ort) && 844 psize(lt) < psize(rt)) { 845 /* 846 * In traditional C the left operand would be extended, 847 * possibly with 1, and then shifted. 848 */ 849 if (hflag && 850 (ln->tn_op != CON || ln->tn_val->v_quad < 0)) { 851 /* semantics of %s change in ANSI C; use ... */ 852 warning(118, mp->m_name); 853 } 854 } 855 goto shift; 856 case SHL: 857 /* 858 * ANSI C does not perform balancing for shift operations, 859 * but traditional C does. If the width of the right operand 860 * is greather than the width of the left operand, than in 861 * traditional C the left operand would be extendet to the 862 * width of the right operand. For SHL this may result in 863 * different results. 864 */ 865 if (psize(lt) < psize(rt)) { 866 /* 867 * XXX If both operands are constant make sure 868 * that there is really a differencs between 869 * ANSI C and traditional C. 870 */ 871 if (hflag) 872 /* semantics of %s change in ANSI C; use ... */ 873 warning(118, mp->m_name); 874 } 875 shift: 876 if (rn->tn_op == CON) { 877 if (!isutyp(rt) && rn->tn_val->v_quad < 0) { 878 /* negative shift */ 879 warning(121); 880 } else if ((uint64_t)rn->tn_val->v_quad == (uint64_t)size(lt)) { 881 /* shift equal to size fo object */ 882 warning(267); 883 } else if ((uint64_t)rn->tn_val->v_quad > (uint64_t)size(lt)) { 884 /* shift greater than size of object */ 885 warning(122); 886 } 887 } 888 break; 889 case EQ: 890 case NE: 891 /* 892 * Accept some things which are allowed with EQ and NE, 893 * but not with ordered comparisons. 894 */ 895 if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) { 896 if (rn->tn_op == CON && rn->tn_val->v_quad == 0) 897 break; 898 } 899 if (rt == PTR && ((lt == PTR && lst == VOID) || isityp(lt))) { 900 if (ln->tn_op == CON && ln->tn_val->v_quad == 0) 901 break; 902 } 903 /* FALLTHROUGH */ 904 case LT: 905 case GT: 906 case LE: 907 case GE: 908 if ((lt == PTR || rt == PTR) && lt != rt) { 909 if (isityp(lt) || isityp(rt)) { 910 /* illegal comb. of pointer and int., op %s */ 911 warning(123, mp->m_name); 912 } else { 913 incompat(op, lt, rt); 914 return (0); 915 } 916 } else if (lt == PTR && rt == PTR) { 917 ptrcmpok(op, ln, rn); 918 } 919 break; 920 case QUEST: 921 if (!issclt(lt)) { 922 /* first operand must have scalar type, op ? : */ 923 error(170); 924 return (0); 925 } 926 while (rn->tn_op == CVT) 927 rn = rn->tn_left; 928 if (rn->tn_op != COLON) 929 LERROR("typeok()"); 930 break; 931 case COLON: 932 933 if (isatyp(lt) && isatyp(rt)) 934 break; 935 936 if (lt == STRUCT && rt == STRUCT && ltp->t_str == rtp->t_str) 937 break; 938 if (lt == UNION && rt == UNION && ltp->t_str == rtp->t_str) 939 break; 940 941 /* combination of any pointer and 0, 0L or (void *)0 is ok */ 942 if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) { 943 if (rn->tn_op == CON && rn->tn_val->v_quad == 0) 944 break; 945 } 946 if (rt == PTR && ((lt == PTR && lst == VOID) || isityp(lt))) { 947 if (ln->tn_op == CON && ln->tn_val->v_quad == 0) 948 break; 949 } 950 951 if ((lt == PTR && isityp(rt)) || (isityp(lt) && rt == PTR)) { 952 /* illegal comb. of ptr. and int., op %s */ 953 warning(123, mp->m_name); 954 break; 955 } 956 957 if (lt == VOID || rt == VOID) { 958 if (lt != VOID || rt != VOID) 959 /* incompatible types in conditional */ 960 warning(126); 961 break; 962 } 963 964 if (lt == PTR && rt == PTR && ((lst == VOID && rst == FUNC) || 965 (lst == FUNC && rst == VOID))) { 966 /* (void *)0 handled above */ 967 if (sflag) 968 /* ANSI C forbids conv. of %s to %s, op %s */ 969 warning(305, "function pointer", "'void *'", 970 mp->m_name); 971 break; 972 } 973 974 if (rt == PTR && lt == PTR) { 975 if (eqptrtype(lstp, rstp, 1)) 976 break; 977 if (!eqtype(lstp, rstp, 1, 0, NULL)) 978 illptrc(mp, ltp, rtp); 979 break; 980 } 981 982 /* incompatible types in conditional */ 983 error(126); 984 return (0); 985 986 case ASSIGN: 987 case INIT: 988 case FARG: 989 case RETURN: 990 if (!asgntypok(op, arg, ln, rn)) 991 return (0); 992 goto assign; 993 case MULASS: 994 case DIVASS: 995 case MODASS: 996 goto assign; 997 case ADDASS: 998 case SUBASS: 999 /* operands have scalar types (checked above) */ 1000 if ((lt == PTR && !isityp(rt)) || rt == PTR) { 1001 incompat(op, lt, rt); 1002 return (0); 1003 } 1004 goto assign; 1005 case SHLASS: 1006 goto assign; 1007 case SHRASS: 1008 if (pflag && !isutyp(lt) && !(tflag && isutyp(rt))) { 1009 /* bitwise operation on s.v. possibly nonportable */ 1010 warning(117); 1011 } 1012 goto assign; 1013 case ANDASS: 1014 case XORASS: 1015 case ORASS: 1016 goto assign; 1017 assign: 1018 if (!ln->tn_lvalue) { 1019 if (ln->tn_op == CVT && ln->tn_cast && 1020 ln->tn_left->tn_op == LOAD) { 1021 /* a cast to non-ptr does not yield an lvalue */ 1022 if (ln->tn_type->t_tspec == PTR) 1023 break; 1024 error(163); 1025 } 1026 /* %soperand of %s must be lvalue */ 1027 error(114, "left ", mp->m_name); 1028 return (0); 1029 } else if (ltp->t_const || ((lt == STRUCT || lt == UNION) && 1030 conmemb(ltp))) { 1031 /* %soperand of %s must be modifiable lvalue */ 1032 if (!tflag) 1033 warning(115, "left ", mp->m_name); 1034 } 1035 break; 1036 case COMMA: 1037 if (!modtab[ln->tn_op].m_sideeff) 1038 nulleff(ln); 1039 break; 1040 /* LINTED (enumeration values not handled in switch) */ 1041 case CON: 1042 case CASE: 1043 case PUSH: 1044 case LOAD: 1045 case ICALL: 1046 case CVT: 1047 case CALL: 1048 case FSEL: 1049 case STRING: 1050 case NAME: 1051 case LOGOR: 1052 case LOGAND: 1053 case OR: 1054 case XOR: 1055 case AND: 1056 case MOD: 1057 case DIV: 1058 case MULT: 1059 case UMINUS: 1060 case UPLUS: 1061 case DEC: 1062 case INC: 1063 case COMPL: 1064 case NOT: 1065 case NOOP: 1066 case REAL: 1067 case IMAG: 1068 break; 1069 } 1070 1071 if (mp->m_badeop && 1072 (ltp->t_isenum || (mp->m_binary && rtp->t_isenum))) { 1073 chkbeop(op, ln, rn); 1074 } else if (mp->m_enumop && (ltp->t_isenum && rtp && rtp->t_isenum)) { 1075 chkeop2(op, arg, ln, rn); 1076 } else if (mp->m_enumop && (ltp->t_isenum || (rtp && rtp->t_isenum))) { 1077 chkeop1(op, arg, ln, rn); 1078 } 1079 1080 return (1); 1081 } 1082 1083 static void 1084 ptrcmpok(op_t op, tnode_t *ln, tnode_t *rn) 1085 { 1086 type_t *ltp, *rtp; 1087 tspec_t lt, rt; 1088 const char *lts, *rts; 1089 1090 lt = (ltp = ln->tn_type)->t_subt->t_tspec; 1091 rt = (rtp = rn->tn_type)->t_subt->t_tspec; 1092 1093 if (lt == VOID || rt == VOID) { 1094 if (sflag && (lt == FUNC || rt == FUNC)) { 1095 /* (void *)0 already handled in typeok() */ 1096 *(lt == FUNC ? <s : &rts) = "function pointer"; 1097 *(lt == VOID ? <s : &rts) = "'void *'"; 1098 /* ANSI C forbids comparison of %s with %s */ 1099 warning(274, lts, rts); 1100 } 1101 return; 1102 } 1103 1104 if (!eqtype(ltp->t_subt, rtp->t_subt, 1, 0, NULL)) { 1105 illptrc(&modtab[op], ltp, rtp); 1106 return; 1107 } 1108 1109 if (lt == FUNC && rt == FUNC) { 1110 if (sflag && op != EQ && op != NE) 1111 /* ANSI C forbids ordered comp. of func ptr */ 1112 warning(125); 1113 } 1114 } 1115 1116 /* 1117 * Checks type compatibility for ASSIGN, INIT, FARG and RETURN 1118 * and prints warnings/errors if necessary. 1119 * If the types are (almost) compatible, 1 is returned, otherwise 0. 1120 */ 1121 static int 1122 asgntypok(op_t op, int arg, tnode_t *ln, tnode_t *rn) 1123 { 1124 tspec_t lt, rt, lst = NOTSPEC, rst = NOTSPEC; 1125 type_t *ltp, *rtp, *lstp = NULL, *rstp = NULL; 1126 mod_t *mp; 1127 const char *lts, *rts; 1128 char lbuf[128], rbuf[128]; 1129 1130 if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR) 1131 lst = (lstp = ltp->t_subt)->t_tspec; 1132 if ((rt = (rtp = rn->tn_type)->t_tspec) == PTR) 1133 rst = (rstp = rtp->t_subt)->t_tspec; 1134 mp = &modtab[op]; 1135 1136 if (isatyp(lt) && isatyp(rt)) 1137 return (1); 1138 1139 if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION)) 1140 /* both are struct or union */ 1141 return (ltp->t_str == rtp->t_str); 1142 1143 /* 0, 0L and (void *)0 may be assigned to any pointer */ 1144 if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) { 1145 if (rn->tn_op == CON && rn->tn_val->v_quad == 0) 1146 return (1); 1147 } 1148 1149 if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID)) { 1150 /* two pointers, at least one pointer to void */ 1151 if (sflag && (lst == FUNC || rst == FUNC)) { 1152 /* comb. of ptr to func and ptr to void */ 1153 *(lst == FUNC ? <s : &rts) = "function pointer"; 1154 *(lst == VOID ? <s : &rts) = "'void *'"; 1155 switch (op) { 1156 case INIT: 1157 case RETURN: 1158 /* ANSI C forbids conversion of %s to %s */ 1159 warning(303, rts, lts); 1160 break; 1161 case FARG: 1162 /* ANSI C forbids conv. of %s to %s, arg #%d */ 1163 warning(304, rts, lts, arg); 1164 break; 1165 default: 1166 /* ANSI C forbids conv. of %s to %s, op %s */ 1167 warning(305, rts, lts, mp->m_name); 1168 break; 1169 } 1170 } 1171 } 1172 1173 if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID || 1174 eqtype(lstp, rstp, 1, 0, NULL))) { 1175 /* compatible pointer types (qualifiers ignored) */ 1176 if (!tflag && 1177 ((!lstp->t_const && rstp->t_const) || 1178 (!lstp->t_volatile && rstp->t_volatile))) { 1179 /* left side has not all qualifiers of right */ 1180 tyname(lbuf, sizeof(lbuf), lstp); 1181 tyname(rbuf, sizeof(rbuf), rstp); 1182 switch (op) { 1183 case INIT: 1184 case RETURN: 1185 /* incompatible pointer types */ 1186 warning(182, lbuf, rbuf); 1187 break; 1188 case FARG: 1189 /* argument has incompat. ptr. type, arg #%d */ 1190 warning(153, arg, lbuf, rbuf); 1191 break; 1192 default: 1193 /* operands have incompat. ptr. types, op %s */ 1194 warning(128, mp->m_name, lbuf, rbuf); 1195 break; 1196 } 1197 } 1198 return (1); 1199 } 1200 1201 if ((lt == PTR && isityp(rt)) || (isityp(lt) && rt == PTR)) { 1202 switch (op) { 1203 case INIT: 1204 case RETURN: 1205 /* illegal combination of pointer and integer */ 1206 warning(183); 1207 break; 1208 case FARG: 1209 /* illegal comb. of ptr. and int., arg #%d */ 1210 warning(154, arg); 1211 break; 1212 default: 1213 /* illegal comb. of ptr. and int., op %s */ 1214 warning(123, mp->m_name); 1215 break; 1216 } 1217 return (1); 1218 } 1219 1220 if (lt == PTR && rt == PTR) { 1221 switch (op) { 1222 case INIT: 1223 case RETURN: 1224 illptrc(NULL, ltp, rtp); 1225 break; 1226 case FARG: 1227 /* argument has incompatible pointer type, arg #%d */ 1228 warning(153, arg, tyname(lbuf, sizeof(lbuf), ltp), 1229 tyname(rbuf, sizeof(rbuf), rtp)); 1230 break; 1231 default: 1232 illptrc(mp, ltp, rtp); 1233 break; 1234 } 1235 return (1); 1236 } 1237 1238 switch (op) { 1239 case INIT: 1240 /* initialisation type mismatch */ 1241 error(185); 1242 break; 1243 case RETURN: 1244 /* return value type mismatch */ 1245 error(211); 1246 break; 1247 case FARG: 1248 /* argument is incompatible with prototype, arg #%d */ 1249 warning(155, arg); 1250 break; 1251 default: 1252 incompat(op, lt, rt); 1253 break; 1254 } 1255 1256 return (0); 1257 } 1258 1259 /* 1260 * Prints a warning if an operator, which should be senseless for an 1261 * enum type, is applied to an enum type. 1262 */ 1263 static void 1264 chkbeop(op_t op, tnode_t *ln, tnode_t *rn) 1265 { 1266 mod_t *mp; 1267 1268 if (!eflag) 1269 return; 1270 1271 mp = &modtab[op]; 1272 1273 if (!(ln->tn_type->t_isenum || 1274 (mp->m_binary && rn->tn_type->t_isenum))) { 1275 return; 1276 } 1277 1278 /* 1279 * Enum as offset to a pointer is an exception (otherwise enums 1280 * could not be used as array indizes). 1281 */ 1282 if (op == PLUS && 1283 ((ln->tn_type->t_isenum && rn->tn_type->t_tspec == PTR) || 1284 (rn->tn_type->t_isenum && ln->tn_type->t_tspec == PTR))) { 1285 return; 1286 } 1287 1288 /* dubious operation on enum, op %s */ 1289 warning(241, mp->m_name); 1290 1291 } 1292 1293 /* 1294 * Prints a warning if an operator is applied to two different enum types. 1295 */ 1296 static void 1297 chkeop2(op_t op, int arg, tnode_t *ln, tnode_t *rn) 1298 { 1299 mod_t *mp; 1300 1301 mp = &modtab[op]; 1302 1303 if (ln->tn_type->t_enum != rn->tn_type->t_enum) { 1304 switch (op) { 1305 case INIT: 1306 /* enum type mismatch in initialisation */ 1307 warning(210); 1308 break; 1309 case FARG: 1310 /* enum type mismatch, arg #%d */ 1311 warning(156, arg); 1312 break; 1313 case RETURN: 1314 /* return value type mismatch */ 1315 warning(211); 1316 break; 1317 default: 1318 /* enum type mismatch, op %s */ 1319 warning(130, mp->m_name); 1320 break; 1321 } 1322 } else if (Pflag && mp->m_comp && op != EQ && op != NE) { 1323 if (eflag) 1324 /* dubious comparisons of enums */ 1325 warning(243, mp->m_name); 1326 } 1327 } 1328 1329 /* 1330 * Prints a warning if an operator has both enum end other integer 1331 * types. 1332 */ 1333 static void 1334 chkeop1(op_t op, int arg, tnode_t *ln, tnode_t *rn) 1335 { 1336 char lbuf[64], rbuf[64]; 1337 1338 if (!eflag) 1339 return; 1340 1341 switch (op) { 1342 case INIT: 1343 /* 1344 * Initializations with 0 should be allowed. Otherwise, 1345 * we should complain about all uninitialized enums, 1346 * consequently. 1347 */ 1348 if (!rn->tn_type->t_isenum && rn->tn_op == CON && 1349 isityp(rn->tn_type->t_tspec) && rn->tn_val->v_quad == 0) { 1350 return; 1351 } 1352 /* initialisation of '%s' with '%s' */ 1353 warning(277, tyname(lbuf, sizeof(lbuf), ln->tn_type), 1354 tyname(rbuf, sizeof(rbuf), rn->tn_type)); 1355 break; 1356 case FARG: 1357 /* combination of '%s' and '%s', arg #%d */ 1358 warning(278, tyname(lbuf, sizeof(lbuf), ln->tn_type), 1359 tyname(rbuf, sizeof(rbuf), rn->tn_type), arg); 1360 break; 1361 case RETURN: 1362 /* combination of '%s' and '%s' in return */ 1363 warning(279, tyname(lbuf, sizeof(lbuf), ln->tn_type), 1364 tyname(rbuf, sizeof(rbuf), rn->tn_type)); 1365 break; 1366 default: 1367 /* combination of '%s' and %s, op %s */ 1368 warning(242, tyname(lbuf, sizeof(lbuf), ln->tn_type), 1369 tyname(rbuf, sizeof(rbuf), rn->tn_type), 1370 modtab[op].m_name); 1371 break; 1372 } 1373 } 1374 1375 /* 1376 * Build and initialize a new node. 1377 */ 1378 static tnode_t * 1379 mktnode(op_t op, type_t *type, tnode_t *ln, tnode_t *rn) 1380 { 1381 tnode_t *ntn; 1382 tspec_t t; 1383 #ifdef notyet 1384 size_t l; 1385 uint64_t rnum; 1386 #endif 1387 1388 ntn = getnode(); 1389 1390 ntn->tn_op = op; 1391 ntn->tn_type = type; 1392 ntn->tn_left = ln; 1393 ntn->tn_right = rn; 1394 1395 switch (op) { 1396 #ifdef notyet 1397 case SHR: 1398 if (rn->tn_op != CON) 1399 break; 1400 rnum = rn->tn_val->v_quad; 1401 l = tsize(ln->tn_type) / CHAR_BIT; 1402 t = ln->tn_type->t_tspec; 1403 switch (l) { 1404 case 8: 1405 if (rnum >= 56) 1406 t = UCHAR; 1407 else if (rnum >= 48) 1408 t = USHORT; 1409 else if (rnum >= 32) 1410 t = UINT; 1411 break; 1412 case 4: 1413 if (rnum >= 24) 1414 t = UCHAR; 1415 else if (rnum >= 16) 1416 t = USHORT; 1417 break; 1418 case 2: 1419 if (rnum >= 8) 1420 t = UCHAR; 1421 break; 1422 default: 1423 break; 1424 } 1425 if (t != ln->tn_type->t_tspec) 1426 ntn->tn_type->t_tspec = t; 1427 break; 1428 #endif 1429 case STAR: 1430 case FSEL: 1431 if (ln->tn_type->t_tspec == PTR) { 1432 t = ln->tn_type->t_subt->t_tspec; 1433 if (t != FUNC && t != VOID) 1434 ntn->tn_lvalue = 1; 1435 } else { 1436 LERROR("mktnode()"); 1437 } 1438 break; 1439 default: 1440 break; 1441 } 1442 1443 return ntn; 1444 } 1445 1446 /* 1447 * Performs usual conversion of operands to (unsigned) int. 1448 * 1449 * If tflag is set or the operand is a function argument with no 1450 * type information (no prototype or variable # of args), convert 1451 * float to double. 1452 */ 1453 tnode_t * 1454 promote(op_t op, int farg, tnode_t *tn) 1455 { 1456 tspec_t t; 1457 type_t *ntp; 1458 u_int len; 1459 1460 t = tn->tn_type->t_tspec; 1461 1462 if (!isatyp(t)) 1463 return (tn); 1464 1465 if (!tflag) { 1466 /* 1467 * ANSI C requires that the result is always of type INT 1468 * if INT can represent all possible values of the previous 1469 * type. 1470 */ 1471 if (tn->tn_type->t_isfield) { 1472 len = tn->tn_type->t_flen; 1473 if (size(INT) > len) { 1474 t = INT; 1475 } else { 1476 if (size(INT) != len) 1477 LERROR("promote()"); 1478 if (isutyp(t)) { 1479 t = UINT; 1480 } else { 1481 t = INT; 1482 } 1483 } 1484 } else if (t == CHAR || t == UCHAR || t == SCHAR) { 1485 t = (size(CHAR) < size(INT) || t != UCHAR) ? 1486 INT : UINT; 1487 } else if (t == SHORT || t == USHORT) { 1488 t = (size(SHORT) < size(INT) || t == SHORT) ? 1489 INT : UINT; 1490 } else if (t == ENUM) { 1491 t = INT; 1492 } else if (farg && t == FLOAT) { 1493 t = DOUBLE; 1494 } 1495 } else { 1496 /* 1497 * In traditional C, keep unsigned and promote FLOAT 1498 * to DOUBLE. 1499 */ 1500 if (t == UCHAR || t == USHORT) { 1501 t = UINT; 1502 } else if (t == CHAR || t == SCHAR || t == SHORT) { 1503 t = INT; 1504 } else if (t == FLOAT) { 1505 t = DOUBLE; 1506 } else if (t == ENUM) { 1507 t = INT; 1508 } 1509 } 1510 1511 if (t != tn->tn_type->t_tspec) { 1512 ntp = tduptyp(tn->tn_type); 1513 ntp->t_tspec = t; 1514 /* 1515 * Keep t_isenum so we are later able to check compatibility 1516 * of enum types. 1517 */ 1518 tn = convert(op, 0, ntp, tn); 1519 } 1520 1521 return (tn); 1522 } 1523 1524 /* 1525 * Insert conversions which are necessary to give both operands the same 1526 * type. This is done in different ways for traditional C and ANIS C. 1527 */ 1528 static void 1529 balance(op_t op, tnode_t **lnp, tnode_t **rnp) 1530 { 1531 tspec_t lt, rt, t; 1532 int i, u; 1533 type_t *ntp; 1534 static tspec_t tl[] = { 1535 LDOUBLE, DOUBLE, FLOAT, UQUAD, QUAD, ULONG, LONG, UINT, INT, 1536 }; 1537 1538 lt = (*lnp)->tn_type->t_tspec; 1539 rt = (*rnp)->tn_type->t_tspec; 1540 1541 if (!isatyp(lt) || !isatyp(rt)) 1542 return; 1543 1544 if (!tflag) { 1545 if (lt == rt) { 1546 t = lt; 1547 } else if (lt == LCOMPLEX || rt == LCOMPLEX) { 1548 t = LCOMPLEX; 1549 } else if (lt == DCOMPLEX || rt == DCOMPLEX) { 1550 t = DCOMPLEX; 1551 } else if (lt == COMPLEX || rt == COMPLEX) { 1552 t = COMPLEX; 1553 } else if (lt == FCOMPLEX || rt == FCOMPLEX) { 1554 t = FCOMPLEX; 1555 } else if (lt == LDOUBLE || rt == LDOUBLE) { 1556 t = LDOUBLE; 1557 } else if (lt == DOUBLE || rt == DOUBLE) { 1558 t = DOUBLE; 1559 } else if (lt == FLOAT || rt == FLOAT) { 1560 t = FLOAT; 1561 } else { 1562 /* 1563 * If type A has more bits than type B it should 1564 * be able to hold all possible values of type B. 1565 */ 1566 if (size(lt) > size(rt)) { 1567 t = lt; 1568 } else if (size(lt) < size(rt)) { 1569 t = rt; 1570 } else { 1571 for (i = 3; tl[i] != INT; i++) { 1572 if (tl[i] == lt || tl[i] == rt) 1573 break; 1574 } 1575 if ((isutyp(lt) || isutyp(rt)) && 1576 !isutyp(tl[i])) { 1577 i--; 1578 } 1579 t = tl[i]; 1580 } 1581 } 1582 } else { 1583 /* Keep unsigned in traditional C */ 1584 u = isutyp(lt) || isutyp(rt); 1585 for (i = 0; tl[i] != INT; i++) { 1586 if (lt == tl[i] || rt == tl[i]) 1587 break; 1588 } 1589 t = tl[i]; 1590 if (u && isityp(t) && !isutyp(t)) 1591 t = utyp(t); 1592 } 1593 1594 if (t != lt) { 1595 ntp = tduptyp((*lnp)->tn_type); 1596 ntp->t_tspec = t; 1597 *lnp = convert(op, 0, ntp, *lnp); 1598 } 1599 if (t != rt) { 1600 ntp = tduptyp((*rnp)->tn_type); 1601 ntp->t_tspec = t; 1602 *rnp = convert(op, 0, ntp, *rnp); 1603 } 1604 } 1605 1606 /* 1607 * Insert a conversion operator, which converts the type of the node 1608 * to another given type. 1609 * If op is FARG, arg is the number of the argument (used for warnings). 1610 */ 1611 tnode_t * 1612 convert(op_t op, int arg, type_t *tp, tnode_t *tn) 1613 { 1614 tnode_t *ntn; 1615 tspec_t nt, ot, ost = NOTSPEC; 1616 1617 if (tn->tn_lvalue) 1618 LERROR("convert()"); 1619 1620 nt = tp->t_tspec; 1621 if ((ot = tn->tn_type->t_tspec) == PTR) 1622 ost = tn->tn_type->t_subt->t_tspec; 1623 1624 if (!tflag && !sflag && op == FARG) 1625 ptconv(arg, nt, ot, tp, tn); 1626 if (isityp(nt) && isityp(ot)) { 1627 iiconv(op, arg, nt, ot, tp, tn); 1628 } else if (nt == PTR && ((ot == PTR && ost == VOID) || isityp(ot)) && 1629 tn->tn_op == CON && tn->tn_val->v_quad == 0) { 1630 /* 0, 0L and (void *)0 may be assigned to any pointer. */ 1631 } else if (isityp(nt) && ot == PTR) { 1632 piconv(op, nt, tp, tn); 1633 } else if (nt == PTR && ot == PTR) { 1634 ppconv(op, tn, tp); 1635 } 1636 1637 ntn = getnode(); 1638 ntn->tn_op = CVT; 1639 ntn->tn_type = tp; 1640 ntn->tn_cast = op == CVT; 1641 if (tn->tn_op != CON || nt == VOID) { 1642 ntn->tn_left = tn; 1643 } else { 1644 ntn->tn_op = CON; 1645 ntn->tn_val = tgetblk(sizeof (val_t)); 1646 cvtcon(op, arg, ntn->tn_type, ntn->tn_val, tn->tn_val); 1647 } 1648 1649 return (ntn); 1650 } 1651 1652 /* 1653 * Print a warning if a prototype causes a type conversion that is 1654 * different from what would happen to the same argument in the 1655 * absence of a prototype. 1656 * 1657 * Errors/Warnings about illegal type combinations are already printed 1658 * in asgntypok(). 1659 */ 1660 static void 1661 ptconv(int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) 1662 { 1663 tnode_t *ptn; 1664 char buf[64]; 1665 1666 if (!isatyp(nt) || !isatyp(ot)) 1667 return; 1668 1669 /* 1670 * If the type of the formal parameter is char/short, a warning 1671 * would be useless, because functions declared the old style 1672 * can't expect char/short arguments. 1673 */ 1674 if (nt == CHAR || nt == UCHAR || nt == SHORT || nt == USHORT) 1675 return; 1676 1677 /* get default promotion */ 1678 ptn = promote(NOOP, 1, tn); 1679 ot = ptn->tn_type->t_tspec; 1680 1681 /* return if types are the same with and without prototype */ 1682 if (nt == ot || (nt == ENUM && ot == INT)) 1683 return; 1684 1685 if (isftyp(nt) != isftyp(ot) || psize(nt) != psize(ot)) { 1686 /* representation and/or width change */ 1687 if (!isityp(ot) || psize(ot) > psize(INT)) { 1688 /* conversion to '%s' due to prototype, arg #%d */ 1689 warning(259, tyname(buf, sizeof(buf), tp), arg); 1690 } 1691 } else if (hflag) { 1692 /* 1693 * they differ in sign or base type (char, short, int, 1694 * long, long long, float, double, long double) 1695 * 1696 * if they differ only in sign and the argument is a constant 1697 * and the msb of the argument is not set, print no warning 1698 */ 1699 if (ptn->tn_op == CON && isityp(nt) && styp(nt) == styp(ot) && 1700 msb(ptn->tn_val->v_quad, ot, -1) == 0) { 1701 /* ok */ 1702 } else { 1703 /* conversion to '%s' due to prototype, arg #%d */ 1704 warning(259, tyname(buf, sizeof(buf), tp), arg); 1705 } 1706 } 1707 } 1708 1709 /* 1710 * Print warnings for conversions of integer types which my cause 1711 * problems. 1712 */ 1713 /* ARGSUSED */ 1714 static void 1715 iiconv(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) 1716 { 1717 char lbuf[64], rbuf[64], opbuf[16]; 1718 if (tn->tn_op == CON) 1719 return; 1720 1721 if (op == CVT) 1722 return; 1723 1724 if (Pflag && psize(nt) > psize(ot) && isutyp(nt) != isutyp(ot)) { 1725 /* conversion to %s may sign-extend incorrectly (, arg #%d) */ 1726 if (aflag && pflag) { 1727 if (op == FARG) { 1728 warning(297, tyname(lbuf, sizeof(lbuf), tp), 1729 arg); 1730 } else { 1731 warning(131, tyname(lbuf, sizeof(lbuf), tp)); 1732 } 1733 } 1734 } 1735 1736 if (Pflag && psize(nt) > psize(ot)) { 1737 switch (tn->tn_op) { 1738 case PLUS: 1739 case MINUS: 1740 case MULT: 1741 case SHL: 1742 warning(324, 1743 tyname(rbuf, sizeof(rbuf), gettyp(ot)), 1744 tyname(lbuf, sizeof(lbuf), tp), 1745 prtnode(opbuf, sizeof(opbuf), tn)); 1746 break; 1747 default: 1748 break; 1749 } 1750 } 1751 1752 if (psize(nt) < psize(ot) && 1753 (ot == LONG || ot == ULONG || ot == QUAD || ot == UQUAD || 1754 aflag > 1)) { 1755 /* conversion from '%s' may lose accuracy */ 1756 if (aflag) { 1757 if (op == FARG) { 1758 warning(298, 1759 tyname(rbuf, sizeof(rbuf), tn->tn_type), 1760 tyname(lbuf, sizeof(lbuf), tp), 1761 arg); 1762 } else { 1763 warning(132, 1764 tyname(rbuf, sizeof(rbuf), tn->tn_type), 1765 tyname(lbuf, sizeof(lbuf), tp)); 1766 } 1767 } 1768 } 1769 } 1770 1771 /* 1772 * Print warnings for dubious conversions of pointer to integer. 1773 */ 1774 static void 1775 piconv(op_t op, tspec_t nt, type_t *tp, tnode_t *tn) 1776 { 1777 char buf[64]; 1778 1779 if (tn->tn_op == CON) 1780 return; 1781 1782 if (op != CVT) { 1783 /* We got already an error. */ 1784 return; 1785 } 1786 1787 if (psize(nt) < psize(PTR)) { 1788 if (pflag && size(nt) >= size(PTR)) { 1789 /* conv. of pointer to %s may lose bits */ 1790 warning(134, tyname(buf, sizeof(buf), tp)); 1791 } else { 1792 /* conv. of pointer to %s loses bits */ 1793 warning(133, tyname(buf, sizeof(buf), tp)); 1794 } 1795 } 1796 } 1797 1798 /* 1799 * Print warnings for questionable pointer conversions. 1800 */ 1801 static void 1802 ppconv(op_t op, tnode_t *tn, type_t *tp) 1803 { 1804 tspec_t nt, ot; 1805 const char *nts, *ots; 1806 1807 /* 1808 * We got already an error (pointers of different types 1809 * without a cast) or we will not get a warning. 1810 */ 1811 if (op != CVT) 1812 return; 1813 1814 nt = tp->t_subt->t_tspec; 1815 ot = tn->tn_type->t_subt->t_tspec; 1816 1817 if (nt == VOID || ot == VOID) { 1818 if (sflag && (nt == FUNC || ot == FUNC)) { 1819 /* (void *)0 already handled in convert() */ 1820 *(nt == FUNC ? &nts : &ots) = "function pointer"; 1821 *(nt == VOID ? &nts : &ots) = "'void *'"; 1822 /* ANSI C forbids conversion of %s to %s */ 1823 warning(303, ots, nts); 1824 } 1825 return; 1826 } else if (nt == FUNC && ot == FUNC) { 1827 return; 1828 } else if (nt == FUNC || ot == FUNC) { 1829 /* questionable conversion of function pointer */ 1830 warning(229); 1831 return; 1832 } 1833 1834 if (getbound(tp->t_subt) > getbound(tn->tn_type->t_subt)) { 1835 if (hflag) 1836 /* possible pointer alignment problem */ 1837 warning(135); 1838 } 1839 if (((nt == STRUCT || nt == UNION) && 1840 tp->t_subt->t_str != tn->tn_type->t_subt->t_str) || 1841 psize(nt) != psize(ot)) { 1842 if (cflag) { 1843 /* pointer casts may be troublesome */ 1844 warning(247); 1845 } 1846 } 1847 } 1848 1849 /* 1850 * Converts a typed constant in a constant of another type. 1851 * 1852 * op operator which requires conversion 1853 * arg if op is FARG, # of argument 1854 * tp type in which to convert the constant 1855 * nv new constant 1856 * v old constant 1857 */ 1858 void 1859 cvtcon(op_t op, int arg, type_t *tp, val_t *nv, val_t *v) 1860 { 1861 char lbuf[64], rbuf[64]; 1862 tspec_t ot, nt; 1863 ldbl_t max = 0.0, min = 0.0; 1864 int sz, rchk; 1865 int64_t xmask, xmsk1; 1866 int osz, nsz; 1867 1868 ot = v->v_tspec; 1869 nt = nv->v_tspec = tp->t_tspec; 1870 rchk = 0; 1871 1872 if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE) { 1873 switch (nt) { 1874 case BOOL: 1875 max = 1; min = 0; break; 1876 case CHAR: 1877 max = TARG_CHAR_MAX; min = TARG_CHAR_MIN; break; 1878 case UCHAR: 1879 max = TARG_UCHAR_MAX; min = 0; break; 1880 case SCHAR: 1881 max = TARG_SCHAR_MAX; min = TARG_SCHAR_MIN; break; 1882 case SHORT: 1883 max = TARG_SHRT_MAX; min = TARG_SHRT_MIN; break; 1884 case USHORT: 1885 max = TARG_USHRT_MAX; min = 0; break; 1886 case ENUM: 1887 case INT: 1888 max = TARG_INT_MAX; min = TARG_INT_MIN; break; 1889 case UINT: 1890 max = (u_int)TARG_UINT_MAX;min = 0; break; 1891 case LONG: 1892 max = TARG_LONG_MAX; min = TARG_LONG_MIN; break; 1893 case ULONG: 1894 max = (u_long)TARG_ULONG_MAX; min = 0; break; 1895 case QUAD: 1896 max = QUAD_MAX; min = QUAD_MIN; break; 1897 case UQUAD: 1898 max = (uint64_t)UQUAD_MAX; min = 0; break; 1899 case FLOAT: 1900 case FCOMPLEX: 1901 max = FLT_MAX; min = -FLT_MAX; break; 1902 case DOUBLE: 1903 case DCOMPLEX: 1904 max = DBL_MAX; min = -DBL_MAX; break; 1905 case PTR: 1906 /* Got already an error because of float --> ptr */ 1907 case LDOUBLE: 1908 case LCOMPLEX: 1909 max = LDBL_MAX; min = -LDBL_MAX; break; 1910 default: 1911 LERROR("cvtcon()"); 1912 } 1913 if (v->v_ldbl > max || v->v_ldbl < min) { 1914 if (nt == LDOUBLE) 1915 LERROR("cvtcon()"); 1916 if (op == FARG) { 1917 /* conv. of %s to %s is out of rng., arg #%d */ 1918 warning(295, tyname(lbuf, sizeof(lbuf), 1919 gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), 1920 arg); 1921 } else { 1922 /* conversion of %s to %s is out of range */ 1923 warning(119, tyname(lbuf, sizeof(lbuf), 1924 gettyp(ot)), 1925 tyname(rbuf, sizeof(rbuf), tp)); 1926 } 1927 v->v_ldbl = v->v_ldbl > 0 ? max : min; 1928 } 1929 if (nt == FLOAT) { 1930 nv->v_ldbl = (float)v->v_ldbl; 1931 } else if (nt == DOUBLE) { 1932 nv->v_ldbl = (double)v->v_ldbl; 1933 } else if (nt == LDOUBLE) { 1934 nv->v_ldbl = v->v_ldbl; 1935 } else { 1936 nv->v_quad = (nt == PTR || isutyp(nt)) ? 1937 (int64_t)v->v_ldbl : (int64_t)v->v_ldbl; 1938 } 1939 } else { 1940 if (nt == FLOAT) { 1941 nv->v_ldbl = (ot == PTR || isutyp(ot)) ? 1942 (float)(uint64_t)v->v_quad : (float)v->v_quad; 1943 } else if (nt == DOUBLE) { 1944 nv->v_ldbl = (ot == PTR || isutyp(ot)) ? 1945 (double)(uint64_t)v->v_quad : (double)v->v_quad; 1946 } else if (nt == LDOUBLE) { 1947 nv->v_ldbl = (ot == PTR || isutyp(ot)) ? 1948 (ldbl_t)(uint64_t)v->v_quad : (ldbl_t)v->v_quad; 1949 } else { 1950 rchk = 1; /* Check for lost precision. */ 1951 nv->v_quad = v->v_quad; 1952 } 1953 } 1954 1955 if (v->v_ansiu && isftyp(nt)) { 1956 /* ANSI C treats constant as unsigned */ 1957 warning(157); 1958 v->v_ansiu = 0; 1959 } else if (v->v_ansiu && (isityp(nt) && !isutyp(nt) && 1960 psize(nt) > psize(ot))) { 1961 /* ANSI C treats constant as unsigned */ 1962 warning(157); 1963 v->v_ansiu = 0; 1964 } 1965 1966 if (nt != FLOAT && nt != DOUBLE && nt != LDOUBLE) { 1967 sz = tp->t_isfield ? tp->t_flen : size(nt); 1968 nv->v_quad = xsign(nv->v_quad, nt, sz); 1969 } 1970 1971 if (rchk && op != CVT) { 1972 osz = size(ot); 1973 nsz = tp->t_isfield ? tp->t_flen : size(nt); 1974 xmask = qlmasks[nsz] ^ qlmasks[osz]; 1975 xmsk1 = qlmasks[nsz] ^ qlmasks[osz - 1]; 1976 /* 1977 * For bitwise operations we are not interested in the 1978 * value, but in the bits itself. 1979 */ 1980 if (op == ORASS || op == OR || op == XOR) { 1981 /* 1982 * Print a warning if bits which were set are 1983 * lost due to the conversion. 1984 * This can happen with operator ORASS only. 1985 */ 1986 if (nsz < osz && (v->v_quad & xmask) != 0) { 1987 /* constant truncated by conv., op %s */ 1988 warning(306, modtab[op].m_name); 1989 } 1990 } else if (op == ANDASS || op == AND) { 1991 /* 1992 * Print a warning if additional bits are not all 1 1993 * and the most significant bit of the old value is 1, 1994 * or if at least one (but not all) removed bit was 0. 1995 */ 1996 if (nsz > osz && 1997 (nv->v_quad & qbmasks[osz - 1]) != 0 && 1998 (nv->v_quad & xmask) != xmask) { 1999 /* 2000 * extra bits set to 0 in conversion 2001 * of '%s' to '%s', op %s 2002 */ 2003 warning(309, tyname(lbuf, sizeof(lbuf), 2004 gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), 2005 modtab[op].m_name); 2006 } else if (nsz < osz && 2007 (v->v_quad & xmask) != xmask && 2008 (v->v_quad & xmask) != 0) { 2009 /* const. truncated by conv., op %s */ 2010 warning(306, modtab[op].m_name); 2011 } 2012 } else if ((nt != PTR && isutyp(nt)) && 2013 (ot != PTR && !isutyp(ot)) && v->v_quad < 0) { 2014 if (op == ASSIGN) { 2015 /* assignment of negative constant to ... */ 2016 warning(164); 2017 } else if (op == INIT) { 2018 /* initialisation of unsigned with neg. ... */ 2019 warning(221); 2020 } else if (op == FARG) { 2021 /* conversion of neg. const. to ..., arg #%d */ 2022 warning(296, arg); 2023 } else if (modtab[op].m_comp) { 2024 /* we get this warning already in chkcomp() */ 2025 } else { 2026 /* conversion of negative constant to ... */ 2027 warning(222); 2028 } 2029 } else if (nv->v_quad != v->v_quad && nsz <= osz && 2030 (v->v_quad & xmask) != 0 && 2031 (isutyp(ot) || (v->v_quad & xmsk1) != xmsk1)) { 2032 /* 2033 * Loss of significant bit(s). All truncated bits 2034 * of unsigned types or all truncated bits plus the 2035 * msb of the target for signed types are considered 2036 * to be significant bits. Loss of significant bits 2037 * means that at least on of the bits was set in an 2038 * unsigned type or that at least one, but not all of 2039 * the bits was set in an signed type. 2040 * Loss of significant bits means that it is not 2041 * possible, also not with necessary casts, to convert 2042 * back to the original type. A example for a 2043 * necessary cast is: 2044 * char c; int i; c = 128; 2045 * i = c; ** yields -128 ** 2046 * i = (unsigned char)c; ** yields 128 ** 2047 */ 2048 if (op == ASSIGN && tp->t_isfield) { 2049 /* precision lost in bit-field assignment */ 2050 warning(166); 2051 } else if (op == ASSIGN) { 2052 /* constant truncated by assignment */ 2053 warning(165); 2054 } else if (op == INIT && tp->t_isfield) { 2055 /* bit-field initializer does not fit */ 2056 warning(180); 2057 } else if (op == INIT) { 2058 /* initializer does not fit */ 2059 warning(178); 2060 } else if (op == CASE) { 2061 /* case label affected by conversion */ 2062 warning(196); 2063 } else if (op == FARG) { 2064 /* conv. of %s to %s is out of rng., arg #%d */ 2065 warning(295, tyname(lbuf, sizeof(lbuf), 2066 gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), 2067 arg); 2068 } else { 2069 /* conversion of %s to %s is out of range */ 2070 warning(119, tyname(lbuf, sizeof(lbuf), 2071 gettyp(ot)), 2072 tyname(rbuf, sizeof(rbuf), tp)); 2073 } 2074 } else if (nv->v_quad != v->v_quad) { 2075 if (op == ASSIGN && tp->t_isfield) { 2076 /* precision lost in bit-field assignment */ 2077 warning(166); 2078 } else if (op == INIT && tp->t_isfield) { 2079 /* bit-field initializer out of range */ 2080 warning(11); 2081 } else if (op == CASE) { 2082 /* case label affected by conversion */ 2083 warning(196); 2084 } else if (op == FARG) { 2085 /* conv. of %s to %s is out of rng., arg #%d */ 2086 warning(295, tyname(lbuf, sizeof(lbuf), 2087 gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), 2088 arg); 2089 } else { 2090 /* conversion of %s to %s is out of range */ 2091 warning(119, tyname(lbuf, sizeof(lbuf), 2092 gettyp(ot)), 2093 tyname(rbuf, sizeof(rbuf), tp)); 2094 } 2095 } 2096 } 2097 } 2098 2099 /* 2100 * Called if incompatible types were detected. 2101 * Prints a appropriate warning. 2102 */ 2103 static void 2104 incompat(op_t op, tspec_t lt, tspec_t rt) 2105 { 2106 mod_t *mp; 2107 int e = 0; 2108 2109 mp = &modtab[op]; 2110 2111 if (lt == VOID || (mp->m_binary && rt == VOID)) { 2112 /* void type illegal in expression */ 2113 e = 109; 2114 } else if (op == ASSIGN) { 2115 if ((lt == STRUCT || lt == UNION) && 2116 (rt == STRUCT || rt == UNION)) { 2117 /* assignment of different structures */ 2118 e = 240; 2119 } else { 2120 /* assignment type mismatch */ 2121 e = 171; 2122 } 2123 } else if (mp->m_binary) { 2124 /* operands of %s have incompatible types */ 2125 e = 107; 2126 } else { 2127 /* operand of %s has incompatible type */ 2128 e = 108; 2129 } 2130 switch (e) { 2131 case 0: 2132 return; 2133 case 109: 2134 error(e); 2135 return; 2136 case 108: 2137 case 107: 2138 error(e, mp->m_name, basictyname(lt), basictyname(rt)); 2139 return; 2140 default: 2141 error(e, basictyname(lt), basictyname(rt)); 2142 return; 2143 } 2144 } 2145 2146 /* 2147 * Called if incompatible pointer types are detected. 2148 * Print an appropriate warning. 2149 */ 2150 static void 2151 illptrc(mod_t *mp, type_t *ltp, type_t *rtp) 2152 { 2153 tspec_t lt, rt; 2154 2155 if (ltp->t_tspec != PTR || rtp->t_tspec != PTR) 2156 LERROR("illptrc()"); 2157 2158 lt = ltp->t_subt->t_tspec; 2159 rt = rtp->t_subt->t_tspec; 2160 2161 if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION)) { 2162 if (mp == NULL) { 2163 /* illegal structure pointer combination */ 2164 warning(244); 2165 } else { 2166 /* illegal structure pointer combination, op %s */ 2167 warning(245, mp->m_name); 2168 } 2169 } else { 2170 if (mp == NULL) { 2171 /* illegal pointer combination */ 2172 warning(184); 2173 } else { 2174 /* illegal pointer combination, op %s */ 2175 warning(124, mp->m_name); 2176 } 2177 } 2178 } 2179 2180 /* 2181 * Make sure type (*tpp)->t_subt has at least the qualifiers 2182 * of tp1->t_subt and tp2->t_subt. 2183 */ 2184 static void 2185 mrgqual(type_t **tpp, type_t *tp1, type_t *tp2) 2186 { 2187 2188 if ((*tpp)->t_tspec != PTR || 2189 tp1->t_tspec != PTR || tp2->t_tspec != PTR) { 2190 LERROR("mrgqual()"); 2191 } 2192 2193 if ((*tpp)->t_subt->t_const == 2194 (tp1->t_subt->t_const | tp2->t_subt->t_const) && 2195 (*tpp)->t_subt->t_volatile == 2196 (tp1->t_subt->t_volatile | tp2->t_subt->t_volatile)) { 2197 return; 2198 } 2199 2200 *tpp = tduptyp(*tpp); 2201 (*tpp)->t_subt = tduptyp((*tpp)->t_subt); 2202 (*tpp)->t_subt->t_const = 2203 tp1->t_subt->t_const | tp2->t_subt->t_const; 2204 (*tpp)->t_subt->t_volatile = 2205 tp1->t_subt->t_volatile | tp2->t_subt->t_volatile; 2206 } 2207 2208 /* 2209 * Returns 1 if the given structure or union has a constant member 2210 * (maybe recursively). 2211 */ 2212 static int 2213 conmemb(type_t *tp) 2214 { 2215 sym_t *m; 2216 tspec_t t; 2217 2218 if ((t = tp->t_tspec) != STRUCT && t != UNION) 2219 LERROR("conmemb()"); 2220 for (m = tp->t_str->memb; m != NULL; m = m->s_nxt) { 2221 tp = m->s_type; 2222 if (tp->t_const) 2223 return (1); 2224 if ((t = tp->t_tspec) == STRUCT || t == UNION) { 2225 if (conmemb(m->s_type)) 2226 return (1); 2227 } 2228 } 2229 return (0); 2230 } 2231 2232 /* 2233 * Create a new node for one of the operators POINT and ARROW. 2234 */ 2235 static tnode_t * 2236 bldstr(op_t op, tnode_t *ln, tnode_t *rn) 2237 { 2238 tnode_t *ntn, *ctn; 2239 int nolval; 2240 2241 if (rn->tn_op != NAME) 2242 LERROR("bldstr()"); 2243 if (rn->tn_sym->s_value.v_tspec != INT) 2244 LERROR("bldstr()"); 2245 if (rn->tn_sym->s_scl != MOS && rn->tn_sym->s_scl != MOU) 2246 LERROR("bldstr()"); 2247 2248 /* 2249 * Remember if the left operand is an lvalue (structure members 2250 * are lvalues if and only if the structure itself is an lvalue). 2251 */ 2252 nolval = op == POINT && !ln->tn_lvalue; 2253 2254 if (op == POINT) { 2255 ln = bldamper(ln, 1); 2256 } else if (ln->tn_type->t_tspec != PTR) { 2257 if (!tflag || !isityp(ln->tn_type->t_tspec)) 2258 LERROR("bldstr()"); 2259 ln = convert(NOOP, 0, tincref(gettyp(VOID), PTR), ln); 2260 } 2261 2262 #if PTRDIFF_IS_LONG 2263 ctn = getinode(LONG, rn->tn_sym->s_value.v_quad / CHAR_BIT); 2264 #else 2265 ctn = getinode(INT, rn->tn_sym->s_value.v_quad / CHAR_BIT); 2266 #endif 2267 2268 ntn = mktnode(PLUS, tincref(rn->tn_type, PTR), ln, ctn); 2269 if (ln->tn_op == CON) 2270 ntn = fold(ntn); 2271 2272 if (rn->tn_type->t_isfield) { 2273 ntn = mktnode(FSEL, ntn->tn_type->t_subt, ntn, NULL); 2274 } else { 2275 ntn = mktnode(STAR, ntn->tn_type->t_subt, ntn, NULL); 2276 } 2277 2278 if (nolval) 2279 ntn->tn_lvalue = 0; 2280 2281 return (ntn); 2282 } 2283 2284 /* 2285 * Create a node for INCAFT, INCBEF, DECAFT and DECBEF. 2286 */ 2287 static tnode_t * 2288 bldincdec(op_t op, tnode_t *ln) 2289 { 2290 tnode_t *cn, *ntn; 2291 2292 if (ln == NULL) 2293 LERROR("bldincdec()"); 2294 2295 if (ln->tn_type->t_tspec == PTR) { 2296 cn = plength(ln->tn_type); 2297 } else { 2298 cn = getinode(INT, (int64_t)1); 2299 } 2300 ntn = mktnode(op, ln->tn_type, ln, cn); 2301 2302 return (ntn); 2303 } 2304 2305 /* 2306 * Create a node for REAL, IMAG 2307 */ 2308 static tnode_t * 2309 bldri(op_t op, tnode_t *ln) 2310 { 2311 tnode_t *cn, *ntn; 2312 char buf[64]; 2313 2314 if (ln == NULL) 2315 LERROR("bldincdec()"); 2316 2317 switch (ln->tn_type->t_tspec) { 2318 case LCOMPLEX: 2319 cn = getinode(LDOUBLE, (int64_t)1); 2320 break; 2321 case DCOMPLEX: 2322 cn = getinode(DOUBLE, (int64_t)1); 2323 break; 2324 case FCOMPLEX: 2325 cn = getinode(FLOAT, (int64_t)1); 2326 break; 2327 default: 2328 error(276, op == REAL ? "real" : "imag", 2329 tyname(buf, sizeof(buf), ln->tn_type)); 2330 return NULL; 2331 } 2332 ntn = mktnode(op, cn->tn_type, ln, cn); 2333 2334 return (ntn); 2335 } 2336 /* 2337 * Create a tree node for the & operator 2338 */ 2339 static tnode_t * 2340 bldamper(tnode_t *tn, int noign) 2341 { 2342 tnode_t *ntn; 2343 tspec_t t; 2344 2345 if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) { 2346 /* & before array or function: ignored */ 2347 if (tflag) 2348 warning(127); 2349 return (tn); 2350 } 2351 2352 /* eliminate &* */ 2353 if (tn->tn_op == STAR && 2354 tn->tn_left->tn_type->t_tspec == PTR && 2355 tn->tn_left->tn_type->t_subt == tn->tn_type) { 2356 return (tn->tn_left); 2357 } 2358 2359 ntn = mktnode(AMPER, tincref(tn->tn_type, PTR), tn, NULL); 2360 2361 return (ntn); 2362 } 2363 2364 /* 2365 * Create a node for operators PLUS and MINUS. 2366 */ 2367 static tnode_t * 2368 bldplmi(op_t op, tnode_t *ln, tnode_t *rn) 2369 { 2370 tnode_t *ntn, *ctn; 2371 type_t *tp; 2372 2373 /* If pointer and integer, then pointer to the lhs. */ 2374 if (rn->tn_type->t_tspec == PTR && isityp(ln->tn_type->t_tspec)) { 2375 ntn = ln; 2376 ln = rn; 2377 rn = ntn; 2378 } 2379 2380 if (ln->tn_type->t_tspec == PTR && rn->tn_type->t_tspec != PTR) { 2381 2382 if (!isityp(rn->tn_type->t_tspec)) 2383 LERROR("bldplmi()"); 2384 2385 ctn = plength(ln->tn_type); 2386 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) 2387 rn = convert(NOOP, 0, ctn->tn_type, rn); 2388 rn = mktnode(MULT, rn->tn_type, rn, ctn); 2389 if (rn->tn_left->tn_op == CON) 2390 rn = fold(rn); 2391 ntn = mktnode(op, ln->tn_type, ln, rn); 2392 2393 } else if (rn->tn_type->t_tspec == PTR) { 2394 2395 if (ln->tn_type->t_tspec != PTR || op != MINUS) 2396 LERROR("bldplmi()"); 2397 #if PTRDIFF_IS_LONG 2398 tp = gettyp(LONG); 2399 #else 2400 tp = gettyp(INT); 2401 #endif 2402 ntn = mktnode(op, tp, ln, rn); 2403 if (ln->tn_op == CON && rn->tn_op == CON) 2404 ntn = fold(ntn); 2405 ctn = plength(ln->tn_type); 2406 balance(NOOP, &ntn, &ctn); 2407 ntn = mktnode(DIV, tp, ntn, ctn); 2408 2409 } else { 2410 2411 ntn = mktnode(op, ln->tn_type, ln, rn); 2412 2413 } 2414 return (ntn); 2415 } 2416 2417 /* 2418 * Create a node for operators SHL and SHR. 2419 */ 2420 static tnode_t * 2421 bldshft(op_t op, tnode_t *ln, tnode_t *rn) 2422 { 2423 tspec_t t; 2424 tnode_t *ntn; 2425 2426 if ((t = rn->tn_type->t_tspec) != INT && t != UINT) 2427 rn = convert(CVT, 0, gettyp(INT), rn); 2428 ntn = mktnode(op, ln->tn_type, ln, rn); 2429 return (ntn); 2430 } 2431 2432 /* 2433 * Create a node for COLON. 2434 */ 2435 static tnode_t * 2436 bldcol(tnode_t *ln, tnode_t *rn) 2437 { 2438 tspec_t lt, rt, pdt; 2439 type_t *rtp; 2440 tnode_t *ntn; 2441 2442 lt = ln->tn_type->t_tspec; 2443 rt = rn->tn_type->t_tspec; 2444 #if PTRDIFF_IS_LONG 2445 pdt = LONG; 2446 #else 2447 pdt = INT; 2448 #endif 2449 2450 /* 2451 * Arithmetic types are balanced, all other type combinations 2452 * still need to be handled. 2453 */ 2454 if (isatyp(lt) && isatyp(rt)) { 2455 rtp = ln->tn_type; 2456 } else if (lt == VOID || rt == VOID) { 2457 rtp = gettyp(VOID); 2458 } else if (lt == STRUCT || lt == UNION) { 2459 /* Both types must be identical. */ 2460 if (rt != STRUCT && rt != UNION) 2461 LERROR("bldcol()"); 2462 if (ln->tn_type->t_str != rn->tn_type->t_str) 2463 LERROR("bldcol()"); 2464 if (incompl(ln->tn_type)) { 2465 /* unknown operand size, op %s */ 2466 error(138, modtab[COLON].m_name); 2467 return (NULL); 2468 } 2469 rtp = ln->tn_type; 2470 } else if (lt == PTR && isityp(rt)) { 2471 if (rt != pdt) { 2472 rn = convert(NOOP, 0, gettyp(pdt), rn); 2473 rt = pdt; 2474 } 2475 rtp = ln->tn_type; 2476 } else if (rt == PTR && isityp(lt)) { 2477 if (lt != pdt) { 2478 ln = convert(NOOP, 0, gettyp(pdt), ln); 2479 lt = pdt; 2480 } 2481 rtp = rn->tn_type; 2482 } else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID) { 2483 if (rt != PTR) 2484 LERROR("bldcol()"); 2485 rtp = ln->tn_type; 2486 mrgqual(&rtp, ln->tn_type, rn->tn_type); 2487 } else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID) { 2488 if (lt != PTR) 2489 LERROR("bldcol()"); 2490 rtp = rn->tn_type; 2491 mrgqual(&rtp, ln->tn_type, rn->tn_type); 2492 } else { 2493 if (lt != PTR || rt != PTR) 2494 LERROR("bldcol()"); 2495 /* 2496 * XXX For now we simply take the left type. This is 2497 * probably wrong, if one type contains a functionprototype 2498 * and the other one, at the same place, only an old style 2499 * declaration. 2500 */ 2501 rtp = ln->tn_type; 2502 mrgqual(&rtp, ln->tn_type, rn->tn_type); 2503 } 2504 2505 ntn = mktnode(COLON, rtp, ln, rn); 2506 2507 return (ntn); 2508 } 2509 2510 /* 2511 * Create a node for an assignment operator (both = and op= ). 2512 */ 2513 static tnode_t * 2514 bldasgn(op_t op, tnode_t *ln, tnode_t *rn) 2515 { 2516 tspec_t lt, rt; 2517 tnode_t *ntn, *ctn; 2518 2519 if (ln == NULL || rn == NULL) 2520 LERROR("bldasgn()"); 2521 2522 lt = ln->tn_type->t_tspec; 2523 rt = rn->tn_type->t_tspec; 2524 2525 if ((op == ADDASS || op == SUBASS) && lt == PTR) { 2526 if (!isityp(rt)) 2527 LERROR("bldasgn()"); 2528 ctn = plength(ln->tn_type); 2529 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) 2530 rn = convert(NOOP, 0, ctn->tn_type, rn); 2531 rn = mktnode(MULT, rn->tn_type, rn, ctn); 2532 if (rn->tn_left->tn_op == CON) 2533 rn = fold(rn); 2534 } 2535 2536 if ((op == ASSIGN || op == RETURN) && (lt == STRUCT || rt == STRUCT)) { 2537 if (rt != lt || ln->tn_type->t_str != rn->tn_type->t_str) 2538 LERROR("bldasgn()"); 2539 if (incompl(ln->tn_type)) { 2540 if (op == RETURN) { 2541 /* cannot return incomplete type */ 2542 error(212); 2543 } else { 2544 /* unknown operand size, op %s */ 2545 error(138, modtab[op].m_name); 2546 } 2547 return (NULL); 2548 } 2549 } 2550 2551 if (op == SHLASS) { 2552 if (psize(lt) < psize(rt)) { 2553 if (hflag) 2554 /* semantics of %s change in ANSI C; use ... */ 2555 warning(118, "<<="); 2556 } 2557 } else if (op != SHRASS) { 2558 if (op == ASSIGN || lt != PTR) { 2559 if (lt != rt || 2560 (ln->tn_type->t_isfield && rn->tn_op == CON)) { 2561 rn = convert(op, 0, ln->tn_type, rn); 2562 rt = lt; 2563 } 2564 } 2565 } 2566 2567 ntn = mktnode(op, ln->tn_type, ln, rn); 2568 2569 return (ntn); 2570 } 2571 2572 /* 2573 * Get length of type tp->t_subt. 2574 */ 2575 static tnode_t * 2576 plength(type_t *tp) 2577 { 2578 int elem, elsz; 2579 tspec_t st; 2580 2581 if (tp->t_tspec != PTR) 2582 LERROR("plength()"); 2583 tp = tp->t_subt; 2584 2585 elem = 1; 2586 elsz = 0; 2587 2588 while (tp->t_tspec == ARRAY) { 2589 elem *= tp->t_dim; 2590 tp = tp->t_subt; 2591 } 2592 2593 switch (tp->t_tspec) { 2594 case FUNC: 2595 /* pointer to function is not allowed here */ 2596 error(110); 2597 break; 2598 case VOID: 2599 /* cannot do pointer arithmetic on operand of ... */ 2600 (void)gnuism(136); 2601 break; 2602 case STRUCT: 2603 case UNION: 2604 if ((elsz = tp->t_str->size) == 0) 2605 /* cannot do pointer arithmetic on operand of ... */ 2606 error(136); 2607 break; 2608 case ENUM: 2609 if (incompl(tp)) { 2610 /* cannot do pointer arithmetic on operand of ... */ 2611 warning(136); 2612 } 2613 /* FALLTHROUGH */ 2614 default: 2615 if ((elsz = size(tp->t_tspec)) == 0) { 2616 /* cannot do pointer arithmetic on operand of ... */ 2617 error(136); 2618 } else if (elsz == -1) { 2619 LERROR("plength()"); 2620 } 2621 break; 2622 } 2623 2624 if (elem == 0 && elsz != 0) { 2625 /* cannot do pointer arithmetic on operand of ... */ 2626 error(136); 2627 } 2628 2629 if (elsz == 0) 2630 elsz = CHAR_BIT; 2631 2632 #if PTRDIFF_IS_LONG 2633 st = LONG; 2634 #else 2635 st = INT; 2636 #endif 2637 2638 return (getinode(st, (int64_t)(elem * elsz / CHAR_BIT))); 2639 } 2640 2641 /* 2642 * XXX 2643 * Note: There appear to be a number of bugs in detecting overflow in 2644 * this function. An audit and a set of proper regression tests are needed. 2645 * --Perry Metzger, Nov. 16, 2001 2646 */ 2647 /* 2648 * Do only as much as necessary to compute constant expressions. 2649 * Called only if the operator allows folding and (both) operands 2650 * are constants. 2651 */ 2652 static tnode_t * 2653 fold(tnode_t *tn) 2654 { 2655 val_t *v; 2656 tspec_t t; 2657 int utyp, ovfl; 2658 int64_t sl, sr = 0, q = 0, mask; 2659 uint64_t ul, ur = 0; 2660 tnode_t *cn; 2661 2662 v = xcalloc(1, sizeof (val_t)); 2663 v->v_tspec = t = tn->tn_type->t_tspec; 2664 2665 utyp = t == PTR || isutyp(t); 2666 ul = sl = tn->tn_left->tn_val->v_quad; 2667 if (modtab[tn->tn_op].m_binary) 2668 ur = sr = tn->tn_right->tn_val->v_quad; 2669 2670 mask = qlmasks[size(t)]; 2671 ovfl = 0; 2672 2673 switch (tn->tn_op) { 2674 case UPLUS: 2675 q = sl; 2676 break; 2677 case UMINUS: 2678 q = -sl; 2679 if (sl != 0 && msb(q, t, -1) == msb(sl, t, -1)) 2680 ovfl = 1; 2681 break; 2682 case COMPL: 2683 q = ~sl; 2684 break; 2685 case MULT: 2686 if (utyp) { 2687 q = ul * ur; 2688 if (q != (q & mask)) 2689 ovfl = 1; 2690 else if ((ul != 0) && ((q / ul) != ur)) 2691 ovfl = 1; 2692 } else { 2693 q = sl * sr; 2694 if (msb(q, t, -1) != (msb(sl, t, -1) ^ msb(sr, t, -1))) 2695 ovfl = 1; 2696 } 2697 break; 2698 case DIV: 2699 if (sr == 0) { 2700 /* division by 0 */ 2701 error(139); 2702 q = utyp ? UQUAD_MAX : QUAD_MAX; 2703 } else { 2704 q = utyp ? (int64_t)(ul / ur) : sl / sr; 2705 } 2706 break; 2707 case MOD: 2708 if (sr == 0) { 2709 /* modulus by 0 */ 2710 error(140); 2711 q = 0; 2712 } else { 2713 q = utyp ? (int64_t)(ul % ur) : sl % sr; 2714 } 2715 break; 2716 case PLUS: 2717 q = utyp ? (int64_t)(ul + ur) : sl + sr; 2718 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) != 0) { 2719 if (msb(q, t, -1) == 0) 2720 ovfl = 1; 2721 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) == 0) { 2722 if (msb(q, t, -1) != 0) 2723 ovfl = 1; 2724 } 2725 break; 2726 case MINUS: 2727 q = utyp ? (int64_t)(ul - ur) : sl - sr; 2728 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) == 0) { 2729 if (msb(q, t, -1) == 0) 2730 ovfl = 1; 2731 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) != 0) { 2732 if (msb(q, t, -1) != 0) 2733 ovfl = 1; 2734 } 2735 break; 2736 case SHL: 2737 q = utyp ? (int64_t)(ul << sr) : sl << sr; 2738 break; 2739 case SHR: 2740 /* 2741 * The sign must be explicitly extended because 2742 * shifts of signed values are implementation dependent. 2743 */ 2744 q = ul >> sr; 2745 q = xsign(q, t, size(t) - (int)sr); 2746 break; 2747 case LT: 2748 q = utyp ? ul < ur : sl < sr; 2749 break; 2750 case LE: 2751 q = utyp ? ul <= ur : sl <= sr; 2752 break; 2753 case GE: 2754 q = utyp ? ul >= ur : sl >= sr; 2755 break; 2756 case GT: 2757 q = utyp ? ul > ur : sl > sr; 2758 break; 2759 case EQ: 2760 q = utyp ? ul == ur : sl == sr; 2761 break; 2762 case NE: 2763 q = utyp ? ul != ur : sl != sr; 2764 break; 2765 case AND: 2766 q = utyp ? (int64_t)(ul & ur) : sl & sr; 2767 break; 2768 case XOR: 2769 q = utyp ? (int64_t)(ul ^ ur) : sl ^ sr; 2770 break; 2771 case OR: 2772 q = utyp ? (int64_t)(ul | ur) : sl | sr; 2773 break; 2774 default: 2775 LERROR("fold()"); 2776 } 2777 2778 /* XXX does not work for quads. */ 2779 if (ovfl || ((uint64_t)(q | mask) != ~(uint64_t)0 && 2780 (q & ~mask) != 0)) { 2781 if (hflag) 2782 /* integer overflow detected, op %s */ 2783 warning(141, modtab[tn->tn_op].m_name); 2784 } 2785 2786 v->v_quad = xsign(q, t, -1); 2787 2788 cn = getcnode(tn->tn_type, v); 2789 2790 return (cn); 2791 } 2792 2793 /* 2794 * Same for operators whose operands are compared with 0 (test context). 2795 */ 2796 static tnode_t * 2797 foldtst(tnode_t *tn) 2798 { 2799 int l, r = 0; 2800 val_t *v; 2801 2802 v = xcalloc(1, sizeof (val_t)); 2803 v->v_tspec = tn->tn_type->t_tspec; 2804 if (tn->tn_type->t_tspec != INT) 2805 LERROR("foldtst()"); 2806 2807 if (isftyp(tn->tn_left->tn_type->t_tspec)) { 2808 l = tn->tn_left->tn_val->v_ldbl != 0.0; 2809 } else { 2810 l = tn->tn_left->tn_val->v_quad != 0; 2811 } 2812 2813 if (modtab[tn->tn_op].m_binary) { 2814 if (isftyp(tn->tn_right->tn_type->t_tspec)) { 2815 r = tn->tn_right->tn_val->v_ldbl != 0.0; 2816 } else { 2817 r = tn->tn_right->tn_val->v_quad != 0; 2818 } 2819 } 2820 2821 switch (tn->tn_op) { 2822 case NOT: 2823 if (hflag) 2824 /* constant argument to NOT */ 2825 warning(239); 2826 v->v_quad = !l; 2827 break; 2828 case LOGAND: 2829 v->v_quad = l && r; 2830 break; 2831 case LOGOR: 2832 v->v_quad = l || r; 2833 break; 2834 default: 2835 LERROR("foldtst()"); 2836 } 2837 2838 return (getcnode(tn->tn_type, v)); 2839 } 2840 2841 /* 2842 * Same for operands with floating point type. 2843 */ 2844 static tnode_t * 2845 foldflt(tnode_t *tn) 2846 { 2847 val_t *v; 2848 tspec_t t; 2849 ldbl_t l, r = 0; 2850 2851 fpe = 0; 2852 v = xcalloc(1, sizeof (val_t)); 2853 v->v_tspec = t = tn->tn_type->t_tspec; 2854 2855 if (!isftyp(t)) 2856 LERROR("foldflt()"); 2857 2858 if (t != tn->tn_left->tn_type->t_tspec) 2859 LERROR("foldflt()"); 2860 if (modtab[tn->tn_op].m_binary && t != tn->tn_right->tn_type->t_tspec) 2861 LERROR("foldflt()"); 2862 2863 l = tn->tn_left->tn_val->v_ldbl; 2864 if (modtab[tn->tn_op].m_binary) 2865 r = tn->tn_right->tn_val->v_ldbl; 2866 2867 switch (tn->tn_op) { 2868 case UPLUS: 2869 v->v_ldbl = l; 2870 break; 2871 case UMINUS: 2872 v->v_ldbl = -l; 2873 break; 2874 case MULT: 2875 v->v_ldbl = l * r; 2876 break; 2877 case DIV: 2878 if (r == 0.0) { 2879 /* division by 0 */ 2880 error(139); 2881 if (t == FLOAT) { 2882 v->v_ldbl = l < 0 ? -FLT_MAX : FLT_MAX; 2883 } else if (t == DOUBLE) { 2884 v->v_ldbl = l < 0 ? -DBL_MAX : DBL_MAX; 2885 } else { 2886 v->v_ldbl = l < 0 ? -LDBL_MAX : LDBL_MAX; 2887 } 2888 } else { 2889 v->v_ldbl = l / r; 2890 } 2891 break; 2892 case PLUS: 2893 v->v_ldbl = l + r; 2894 break; 2895 case MINUS: 2896 v->v_ldbl = l - r; 2897 break; 2898 case LT: 2899 v->v_quad = l < r; 2900 break; 2901 case LE: 2902 v->v_quad = l <= r; 2903 break; 2904 case GE: 2905 v->v_quad = l >= r; 2906 break; 2907 case GT: 2908 v->v_quad = l > r; 2909 break; 2910 case EQ: 2911 v->v_quad = l == r; 2912 break; 2913 case NE: 2914 v->v_quad = l != r; 2915 break; 2916 default: 2917 LERROR("foldflt()"); 2918 } 2919 2920 if (!fpe && isnan((double)v->v_ldbl)) 2921 LERROR("foldflt()"); 2922 if (fpe || !finite((double)v->v_ldbl) || 2923 (t == FLOAT && 2924 (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || 2925 (t == DOUBLE && 2926 (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) { 2927 /* floating point overflow detected, op %s */ 2928 warning(142, modtab[tn->tn_op].m_name); 2929 if (t == FLOAT) { 2930 v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX; 2931 } else if (t == DOUBLE) { 2932 v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX; 2933 } else { 2934 v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX; 2935 } 2936 fpe = 0; 2937 } 2938 2939 return (getcnode(tn->tn_type, v)); 2940 } 2941 2942 2943 /* 2944 * Create a constant node for sizeof. 2945 */ 2946 tnode_t * 2947 bldszof(type_t *tp) 2948 { 2949 tspec_t st; 2950 #if SIZEOF_IS_ULONG 2951 st = ULONG; 2952 #else 2953 st = UINT; 2954 #endif 2955 return getinode(st, tsize(tp) / CHAR_BIT); 2956 } 2957 2958 int64_t 2959 tsize(type_t *tp) 2960 { 2961 int elem, elsz; 2962 2963 elem = 1; 2964 while (tp->t_tspec == ARRAY) { 2965 elem *= tp->t_dim; 2966 tp = tp->t_subt; 2967 } 2968 if (elem == 0) { 2969 /* cannot take size of incomplete type */ 2970 error(143); 2971 elem = 1; 2972 } 2973 switch (tp->t_tspec) { 2974 case FUNC: 2975 /* cannot take size of function */ 2976 error(144); 2977 elsz = 1; 2978 break; 2979 case STRUCT: 2980 case UNION: 2981 if (incompl(tp)) { 2982 /* cannot take size of incomplete type */ 2983 error(143); 2984 elsz = 1; 2985 } else { 2986 elsz = tp->t_str->size; 2987 } 2988 break; 2989 case ENUM: 2990 if (incompl(tp)) { 2991 /* cannot take size of incomplete type */ 2992 warning(143); 2993 } 2994 /* FALLTHROUGH */ 2995 default: 2996 if (tp->t_isfield) { 2997 /* cannot take size of bit-field */ 2998 error(145); 2999 } 3000 if (tp->t_tspec == VOID) { 3001 /* cannot take size of void */ 3002 error(146); 3003 elsz = 1; 3004 } else { 3005 elsz = size(tp->t_tspec); 3006 if (elsz <= 0) 3007 LERROR("bldszof()"); 3008 } 3009 break; 3010 } 3011 3012 return (int64_t)(elem * elsz); 3013 } 3014 3015 /* 3016 */ 3017 tnode_t * 3018 bldalof(type_t *tp) 3019 { 3020 tspec_t st; 3021 3022 switch (tp->t_tspec) { 3023 case ARRAY: 3024 break; 3025 3026 case FUNC: 3027 /* cannot take align of function */ 3028 error(144); 3029 return 0; 3030 3031 case STRUCT: 3032 case UNION: 3033 if (incompl(tp)) { 3034 /* cannot take align of incomplete type */ 3035 error(143); 3036 return 0; 3037 } 3038 break; 3039 case ENUM: 3040 break; 3041 default: 3042 if (tp->t_isfield) { 3043 /* cannot take align of bit-field */ 3044 error(145); 3045 return 0; 3046 } 3047 if (tp->t_tspec == VOID) { 3048 /* cannot take alignsize of void */ 3049 error(146); 3050 return 0; 3051 } 3052 break; 3053 } 3054 3055 #if SIZEOF_IS_ULONG 3056 st = ULONG; 3057 #else 3058 st = UINT; 3059 #endif 3060 3061 return getinode(st, (int64_t)getbound(tp)); 3062 } 3063 3064 /* 3065 * Type casts. 3066 */ 3067 tnode_t * 3068 cast(tnode_t *tn, type_t *tp) 3069 { 3070 tspec_t nt, ot; 3071 3072 if (tn == NULL) 3073 return (NULL); 3074 3075 tn = cconv(tn); 3076 3077 nt = tp->t_tspec; 3078 ot = tn->tn_type->t_tspec; 3079 3080 if (nt == VOID) { 3081 /* 3082 * XXX ANSI C requires scalar types or void (Plauger&Brodie). 3083 * But this seams really questionable. 3084 */ 3085 } else if (nt == STRUCT || nt == UNION || nt == ARRAY || nt == FUNC) { 3086 /* invalid cast expression */ 3087 error(147); 3088 return (NULL); 3089 } else if (ot == STRUCT || ot == UNION) { 3090 /* invalid cast expression */ 3091 error(147); 3092 return (NULL); 3093 } else if (ot == VOID) { 3094 /* improper cast of void expression */ 3095 error(148); 3096 return (NULL); 3097 } else if (isityp(nt) && issclt(ot)) { 3098 /* ok */ 3099 } else if (isftyp(nt) && isatyp(ot)) { 3100 /* ok */ 3101 } else if (nt == PTR && isityp(ot)) { 3102 /* ok */ 3103 } else if (nt == PTR && ot == PTR) { 3104 if (!tp->t_subt->t_const && tn->tn_type->t_subt->t_const) { 3105 if (hflag) 3106 /* cast discards 'const' from ... */ 3107 warning(275); 3108 } 3109 } else { 3110 /* invalid cast expression */ 3111 error(147); 3112 return (NULL); 3113 } 3114 3115 tn = convert(CVT, 0, tp, tn); 3116 tn->tn_cast = 1; 3117 3118 return (tn); 3119 } 3120 3121 /* 3122 * Create the node for a function argument. 3123 * All necessary conversions and type checks are done in funccall(), because 3124 * in funcarg() we have no information about expected argument types. 3125 */ 3126 tnode_t * 3127 funcarg(tnode_t *args, tnode_t *arg) 3128 { 3129 tnode_t *ntn; 3130 3131 /* 3132 * If there was a serious error in the expression for the argument, 3133 * create a dummy argument so the positions of the remaining arguments 3134 * will not change. 3135 */ 3136 if (arg == NULL) 3137 arg = getinode(INT, (int64_t)0); 3138 3139 ntn = mktnode(PUSH, arg->tn_type, arg, args); 3140 3141 return (ntn); 3142 } 3143 3144 /* 3145 * Create the node for a function call. Also check types of 3146 * function arguments and insert conversions, if necessary. 3147 */ 3148 tnode_t * 3149 funccall(tnode_t *func, tnode_t *args) 3150 { 3151 tnode_t *ntn; 3152 op_t fcop; 3153 3154 if (func == NULL) 3155 return (NULL); 3156 3157 if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) { 3158 fcop = CALL; 3159 } else { 3160 fcop = ICALL; 3161 } 3162 3163 /* 3164 * after cconv() func will always be a pointer to a function 3165 * if it is a valid function designator. 3166 */ 3167 func = cconv(func); 3168 3169 if (func->tn_type->t_tspec != PTR || 3170 func->tn_type->t_subt->t_tspec != FUNC) { 3171 /* illegal function */ 3172 error(149); 3173 return (NULL); 3174 } 3175 3176 args = chkfarg(func->tn_type->t_subt, args); 3177 3178 ntn = mktnode(fcop, func->tn_type->t_subt->t_subt, func, args); 3179 3180 return (ntn); 3181 } 3182 3183 /* 3184 * Check types of all function arguments and insert conversions, 3185 * if necessary. 3186 */ 3187 static tnode_t * 3188 chkfarg(type_t *ftp, tnode_t *args) 3189 { 3190 tnode_t *arg; 3191 sym_t *asym; 3192 tspec_t at; 3193 int narg, npar, n, i; 3194 3195 /* get # of args in the prototype */ 3196 npar = 0; 3197 for (asym = ftp->t_args; asym != NULL; asym = asym->s_nxt) 3198 npar++; 3199 3200 /* get # of args in function call */ 3201 narg = 0; 3202 for (arg = args; arg != NULL; arg = arg->tn_right) 3203 narg++; 3204 3205 asym = ftp->t_args; 3206 if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) { 3207 /* argument mismatch: %d arg%s passed, %d expected */ 3208 error(150, narg, narg > 1 ? "s" : "", npar); 3209 asym = NULL; 3210 } 3211 3212 for (n = 1; n <= narg; n++) { 3213 3214 /* 3215 * The rightmost argument is at the top of the argument 3216 * subtree. 3217 */ 3218 for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) 3219 continue; 3220 3221 /* some things which are always not allowd */ 3222 if ((at = arg->tn_left->tn_type->t_tspec) == VOID) { 3223 /* void expressions may not be arguments, arg #%d */ 3224 error(151, n); 3225 return (NULL); 3226 } else if ((at == STRUCT || at == UNION) && 3227 incompl(arg->tn_left->tn_type)) { 3228 /* argument cannot have unknown size, arg #%d */ 3229 error(152, n); 3230 return (NULL); 3231 } else if (isityp(at) && arg->tn_left->tn_type->t_isenum && 3232 incompl(arg->tn_left->tn_type)) { 3233 /* argument cannot have unknown size, arg #%d */ 3234 warning(152, n); 3235 } 3236 3237 /* class conversions (arg in value context) */ 3238 arg->tn_left = cconv(arg->tn_left); 3239 3240 if (asym != NULL) { 3241 arg->tn_left = parg(n, asym->s_type, arg->tn_left); 3242 } else { 3243 arg->tn_left = promote(NOOP, 1, arg->tn_left); 3244 } 3245 arg->tn_type = arg->tn_left->tn_type; 3246 3247 if (asym != NULL) 3248 asym = asym->s_nxt; 3249 } 3250 3251 return (args); 3252 } 3253 3254 /* 3255 * Compare the type of an argument with the corresponding type of a 3256 * prototype parameter. If it is a valid combination, but both types 3257 * are not the same, insert a conversion to convert the argument into 3258 * the type of the parameter. 3259 */ 3260 static tnode_t * 3261 parg( int n, /* pos of arg */ 3262 type_t *tp, /* expected type (from prototype) */ 3263 tnode_t *tn) /* argument */ 3264 { 3265 tnode_t *ln; 3266 int dowarn; 3267 3268 ln = xcalloc(1, sizeof (tnode_t)); 3269 ln->tn_type = tduptyp(tp); 3270 ln->tn_type->t_const = 0; 3271 ln->tn_lvalue = 1; 3272 if (typeok(FARG, n, ln, tn)) { 3273 if (!eqtype(tp, tn->tn_type, 1, 0, (dowarn = 0, &dowarn)) || dowarn) 3274 tn = convert(FARG, n, tp, tn); 3275 } 3276 free(ln); 3277 return (tn); 3278 } 3279 3280 /* 3281 * Return the value of an integral constant expression. 3282 * If the expression is not constant or its type is not an integer 3283 * type, an error message is printed. 3284 */ 3285 val_t * 3286 constant(tnode_t *tn, int required) 3287 { 3288 val_t *v; 3289 3290 if (tn != NULL) 3291 tn = cconv(tn); 3292 if (tn != NULL) 3293 tn = promote(NOOP, 0, tn); 3294 3295 v = xcalloc(1, sizeof (val_t)); 3296 3297 if (tn == NULL) { 3298 if (nerr == 0) 3299 LERROR("constant()"); 3300 v->v_tspec = INT; 3301 v->v_quad = 1; 3302 return (v); 3303 } 3304 3305 v->v_tspec = tn->tn_type->t_tspec; 3306 3307 if (tn->tn_op == CON) { 3308 if (tn->tn_type->t_tspec != tn->tn_val->v_tspec) 3309 LERROR("constant()"); 3310 if (isityp(tn->tn_val->v_tspec)) { 3311 v->v_ansiu = tn->tn_val->v_ansiu; 3312 v->v_quad = tn->tn_val->v_quad; 3313 return (v); 3314 } 3315 v->v_quad = tn->tn_val->v_ldbl; 3316 } else { 3317 v->v_quad = 1; 3318 } 3319 3320 /* integral constant expression expected */ 3321 if (required) 3322 error(55); 3323 else 3324 c99ism(318); 3325 3326 if (!isityp(v->v_tspec)) 3327 v->v_tspec = INT; 3328 3329 return (v); 3330 } 3331 3332 /* 3333 * Perform some tests on expressions which can't be done in build() and 3334 * functions called by build(). These tests must be done here because 3335 * we need some information about the context in which the operations 3336 * are performed. 3337 * After all tests are performed, expr() frees the memory which is used 3338 * for the expression. 3339 */ 3340 void 3341 expr(tnode_t *tn, int vctx, int tctx, int dofreeblk) 3342 { 3343 3344 if (tn == NULL && nerr == 0) 3345 LERROR("expr()"); 3346 3347 if (tn == NULL) { 3348 tfreeblk(); 3349 return; 3350 } 3351 3352 /* expr() is also called in global initialisations */ 3353 if (dcs->d_ctx != EXTERN) 3354 chkreach(); 3355 3356 chkmisc(tn, vctx, tctx, !tctx, 0, 0, 0); 3357 if (tn->tn_op == ASSIGN) { 3358 if (hflag && tctx) 3359 /* assignment in conditional context */ 3360 warning(159); 3361 } else if (tn->tn_op == CON) { 3362 if (hflag && tctx && !ccflg) 3363 /* constant in conditional context */ 3364 warning(161); 3365 } 3366 if (!modtab[tn->tn_op].m_sideeff) { 3367 /* 3368 * for left operands of COMMA this warning is already 3369 * printed 3370 */ 3371 if (tn->tn_op != COMMA && !vctx && !tctx) 3372 nulleff(tn); 3373 } 3374 if (dflag) 3375 displexpr(tn, 0); 3376 3377 /* free the tree memory */ 3378 if (dofreeblk) 3379 tfreeblk(); 3380 } 3381 3382 static void 3383 nulleff(tnode_t *tn) 3384 { 3385 3386 if (!hflag) 3387 return; 3388 3389 while (!modtab[tn->tn_op].m_sideeff) { 3390 if (tn->tn_op == CVT && tn->tn_type->t_tspec == VOID) { 3391 tn = tn->tn_left; 3392 } else if (tn->tn_op == LOGAND || tn->tn_op == LOGOR) { 3393 /* 3394 * && and || have a side effect if the right operand 3395 * has a side effect. 3396 */ 3397 tn = tn->tn_right; 3398 } else if (tn->tn_op == QUEST) { 3399 /* 3400 * ? has a side effect if at least one of its right 3401 * operands has a side effect 3402 */ 3403 tn = tn->tn_right; 3404 } else if (tn->tn_op == COLON || tn->tn_op == COMMA) { 3405 /* 3406 * : has a side effect if at least one of its operands 3407 * has a side effect 3408 */ 3409 if (modtab[tn->tn_left->tn_op].m_sideeff) { 3410 tn = tn->tn_left; 3411 } else if (modtab[tn->tn_right->tn_op].m_sideeff) { 3412 tn = tn->tn_right; 3413 } else { 3414 break; 3415 } 3416 } else { 3417 break; 3418 } 3419 } 3420 if (!modtab[tn->tn_op].m_sideeff) 3421 /* expression has null effect */ 3422 warning(129); 3423 } 3424 3425 /* 3426 * Dump an expression to stdout 3427 * only used for debugging 3428 */ 3429 static void 3430 displexpr(tnode_t *tn, int offs) 3431 { 3432 uint64_t uq; 3433 3434 if (tn == NULL) { 3435 (void)printf("%*s%s\n", offs, "", "NULL"); 3436 return; 3437 } 3438 (void)printf("%*sop %s ", offs, "", modtab[tn->tn_op].m_name); 3439 3440 if (tn->tn_op == NAME) { 3441 (void)printf("%s: %s ", 3442 tn->tn_sym->s_name, scltoa(tn->tn_sym->s_scl)); 3443 } else if (tn->tn_op == CON && isftyp(tn->tn_type->t_tspec)) { 3444 (void)printf("%#g ", (double)tn->tn_val->v_ldbl); 3445 } else if (tn->tn_op == CON && isityp(tn->tn_type->t_tspec)) { 3446 uq = tn->tn_val->v_quad; 3447 (void)printf("0x %08lx %08lx ", (long)(uq >> 32) & 0xffffffffl, 3448 (long)uq & 0xffffffffl); 3449 } else if (tn->tn_op == CON) { 3450 if (tn->tn_type->t_tspec != PTR) 3451 LERROR("displexpr()"); 3452 (void)printf("0x%0*lx ", (int)(sizeof (void *) * CHAR_BIT / 4), 3453 (u_long)tn->tn_val->v_quad); 3454 } else if (tn->tn_op == STRING) { 3455 if (tn->tn_strg->st_tspec == CHAR) { 3456 (void)printf("\"%s\"", tn->tn_strg->st_cp); 3457 } else { 3458 char *s; 3459 size_t n; 3460 n = MB_CUR_MAX * (tn->tn_strg->st_len + 1); 3461 s = xmalloc(n); 3462 (void)wcstombs(s, tn->tn_strg->st_wcp, n); 3463 (void)printf("L\"%s\"", s); 3464 free(s); 3465 } 3466 (void)printf(" "); 3467 } else if (tn->tn_op == FSEL) { 3468 (void)printf("o=%d, l=%d ", tn->tn_type->t_foffs, 3469 tn->tn_type->t_flen); 3470 } 3471 (void)printf("%s\n", ttos(tn->tn_type)); 3472 if (tn->tn_op == NAME || tn->tn_op == CON || tn->tn_op == STRING) 3473 return; 3474 displexpr(tn->tn_left, offs + 2); 3475 if (modtab[tn->tn_op].m_binary || 3476 (tn->tn_op == PUSH && tn->tn_right != NULL)) { 3477 displexpr(tn->tn_right, offs + 2); 3478 } 3479 } 3480 3481 /* 3482 * Called by expr() to recursively perform some tests. 3483 */ 3484 /* ARGSUSED */ 3485 void 3486 chkmisc(tnode_t *tn, int vctx, int tctx, int eqwarn, int fcall, int rvdisc, 3487 int szof) 3488 { 3489 tnode_t *ln, *rn; 3490 mod_t *mp; 3491 int nrvdisc, cvctx, ctctx; 3492 op_t op; 3493 scl_t sc; 3494 dinfo_t *di; 3495 3496 if (tn == NULL) 3497 return; 3498 3499 ln = tn->tn_left; 3500 rn = tn->tn_right; 3501 mp = &modtab[op = tn->tn_op]; 3502 3503 switch (op) { 3504 case AMPER: 3505 if (ln->tn_op == NAME && (reached || rchflg)) { 3506 if (!szof) 3507 setsflg(ln->tn_sym); 3508 setuflg(ln->tn_sym, fcall, szof); 3509 } 3510 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) 3511 /* check the range of array indices */ 3512 chkaidx(ln->tn_left, 1); 3513 break; 3514 case LOAD: 3515 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) 3516 /* check the range of array indices */ 3517 chkaidx(ln->tn_left, 0); 3518 /* FALLTHROUGH */ 3519 case PUSH: 3520 case INCBEF: 3521 case DECBEF: 3522 case INCAFT: 3523 case DECAFT: 3524 case ADDASS: 3525 case SUBASS: 3526 case MULASS: 3527 case DIVASS: 3528 case MODASS: 3529 case ANDASS: 3530 case ORASS: 3531 case XORASS: 3532 case SHLASS: 3533 case SHRASS: 3534 case REAL: 3535 case IMAG: 3536 if (ln->tn_op == NAME && (reached || rchflg)) { 3537 sc = ln->tn_sym->s_scl; 3538 /* 3539 * Look if there was a asm statement in one of the 3540 * compound statements we are in. If not, we don't 3541 * print a warning. 3542 */ 3543 for (di = dcs; di != NULL; di = di->d_nxt) { 3544 if (di->d_asm) 3545 break; 3546 } 3547 if (sc != EXTERN && sc != STATIC && 3548 !ln->tn_sym->s_set && !szof && di == NULL) { 3549 /* %s may be used before set */ 3550 warning(158, ln->tn_sym->s_name); 3551 setsflg(ln->tn_sym); 3552 } 3553 setuflg(ln->tn_sym, 0, 0); 3554 } 3555 break; 3556 case ASSIGN: 3557 if (ln->tn_op == NAME && !szof && (reached || rchflg)) { 3558 setsflg(ln->tn_sym); 3559 if (ln->tn_sym->s_scl == EXTERN) 3560 outusg(ln->tn_sym); 3561 } 3562 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) 3563 /* check the range of array indices */ 3564 chkaidx(ln->tn_left, 0); 3565 break; 3566 case CALL: 3567 if (ln->tn_op != AMPER || ln->tn_left->tn_op != NAME) 3568 LERROR("chkmisc()"); 3569 if (!szof) 3570 outcall(tn, vctx || tctx, rvdisc); 3571 break; 3572 case EQ: 3573 /* equality operator "==" found where "=" was exp. */ 3574 if (hflag && eqwarn) 3575 warning(160); 3576 break; 3577 case CON: 3578 case NAME: 3579 case STRING: 3580 return; 3581 /* LINTED (enumeration values not handled in switch) */ 3582 case OR: 3583 case XOR: 3584 case NE: 3585 case GE: 3586 case GT: 3587 case LE: 3588 case LT: 3589 case SHR: 3590 case SHL: 3591 case MINUS: 3592 case PLUS: 3593 case MOD: 3594 case DIV: 3595 case MULT: 3596 case STAR: 3597 case UMINUS: 3598 case UPLUS: 3599 case DEC: 3600 case INC: 3601 case COMPL: 3602 case NOT: 3603 case POINT: 3604 case ARROW: 3605 case NOOP: 3606 case AND: 3607 case FARG: 3608 case CASE: 3609 case INIT: 3610 case RETURN: 3611 case ICALL: 3612 case CVT: 3613 case COMMA: 3614 case FSEL: 3615 case COLON: 3616 case QUEST: 3617 case LOGOR: 3618 case LOGAND: 3619 break; 3620 } 3621 3622 cvctx = mp->m_vctx; 3623 ctctx = mp->m_tctx; 3624 /* 3625 * values of operands of ':' are not used if the type of at least 3626 * one of the operands (for gcc compatibility) is void 3627 * XXX test/value context of QUEST should probably be used as 3628 * context for both operands of COLON 3629 */ 3630 if (op == COLON && tn->tn_type->t_tspec == VOID) 3631 cvctx = ctctx = 0; 3632 nrvdisc = op == CVT && tn->tn_type->t_tspec == VOID; 3633 chkmisc(ln, cvctx, ctctx, mp->m_eqwarn, op == CALL, nrvdisc, szof); 3634 3635 switch (op) { 3636 case PUSH: 3637 if (rn != NULL) 3638 chkmisc(rn, 0, 0, mp->m_eqwarn, 0, 0, szof); 3639 break; 3640 case LOGAND: 3641 case LOGOR: 3642 chkmisc(rn, 0, 1, mp->m_eqwarn, 0, 0, szof); 3643 break; 3644 case COLON: 3645 chkmisc(rn, cvctx, ctctx, mp->m_eqwarn, 0, 0, szof); 3646 break; 3647 case COMMA: 3648 chkmisc(rn, vctx, tctx, mp->m_eqwarn, 0, 0, szof); 3649 break; 3650 default: 3651 if (mp->m_binary) 3652 chkmisc(rn, 1, 0, mp->m_eqwarn, 0, 0, szof); 3653 break; 3654 } 3655 3656 } 3657 3658 /* 3659 * Checks the range of array indices, if possible. 3660 * amper is set if only the address of the element is used. This 3661 * means that the index is allowd to refere to the first element 3662 * after the array. 3663 */ 3664 static void 3665 chkaidx(tnode_t *tn, int amper) 3666 { 3667 int dim; 3668 tnode_t *ln, *rn; 3669 int elsz; 3670 int64_t con; 3671 3672 ln = tn->tn_left; 3673 rn = tn->tn_right; 3674 3675 /* We can only check constant indices. */ 3676 if (rn->tn_op != CON) 3677 return; 3678 3679 /* Return if the left node does not stem from an array. */ 3680 if (ln->tn_op != AMPER) 3681 return; 3682 if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME) 3683 return; 3684 if (ln->tn_left->tn_type->t_tspec != ARRAY) 3685 return; 3686 3687 /* 3688 * For incomplete array types, we can print a warning only if 3689 * the index is negative. 3690 */ 3691 if (incompl(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0) 3692 return; 3693 3694 /* Get the size of one array element */ 3695 if ((elsz = length(ln->tn_type->t_subt, NULL)) == 0) 3696 return; 3697 elsz /= CHAR_BIT; 3698 3699 /* Change the unit of the index from bytes to element size. */ 3700 if (isutyp(rn->tn_type->t_tspec)) { 3701 con = (uint64_t)rn->tn_val->v_quad / elsz; 3702 } else { 3703 con = rn->tn_val->v_quad / elsz; 3704 } 3705 3706 dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0); 3707 3708 if (!isutyp(rn->tn_type->t_tspec) && con < 0) { 3709 /* array subscript cannot be negative: %ld */ 3710 warning(167, (long)con); 3711 } else if (dim > 0 && (uint64_t)con >= (uint64_t)dim) { 3712 /* array subscript cannot be > %d: %ld */ 3713 warning(168, dim - 1, (long)con); 3714 } 3715 } 3716 3717 /* 3718 * Check for ordered comparisons of unsigned values with 0. 3719 */ 3720 static void 3721 chkcomp(op_t op, tnode_t *ln, tnode_t *rn) 3722 { 3723 char buf[64]; 3724 tspec_t lt, rt; 3725 mod_t *mp; 3726 3727 lt = ln->tn_type->t_tspec; 3728 rt = rn->tn_type->t_tspec; 3729 mp = &modtab[op]; 3730 3731 if (ln->tn_op != CON && rn->tn_op != CON) 3732 return; 3733 3734 if (!isityp(lt) || !isityp(rt)) 3735 return; 3736 3737 if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON && 3738 (rn->tn_val->v_quad < 0 || 3739 rn->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) { 3740 /* nonportable character comparison, op %s */ 3741 warning(230, mp->m_name); 3742 return; 3743 } 3744 if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON && 3745 (ln->tn_val->v_quad < 0 || 3746 ln->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) { 3747 /* nonportable character comparison, op %s */ 3748 warning(230, mp->m_name); 3749 return; 3750 } 3751 if (isutyp(lt) && !isutyp(rt) && 3752 rn->tn_op == CON && rn->tn_val->v_quad <= 0) { 3753 if (rn->tn_val->v_quad < 0) { 3754 /* comparison of %s with %s, op %s */ 3755 warning(162, tyname(buf, sizeof(buf), ln->tn_type), 3756 "negative constant", mp->m_name); 3757 } else if (op == LT || op == GE || (hflag && op == LE)) { 3758 /* comparison of %s with %s, op %s */ 3759 warning(162, tyname(buf, sizeof(buf), ln->tn_type), 3760 "0", mp->m_name); 3761 } 3762 return; 3763 } 3764 if (isutyp(rt) && !isutyp(lt) && 3765 ln->tn_op == CON && ln->tn_val->v_quad <= 0) { 3766 if (ln->tn_val->v_quad < 0) { 3767 /* comparison of %s with %s, op %s */ 3768 warning(162, "negative constant", 3769 tyname(buf, sizeof(buf), rn->tn_type), mp->m_name); 3770 } else if (op == GT || op == LE || (hflag && op == GE)) { 3771 /* comparison of %s with %s, op %s */ 3772 warning(162, "0", tyname(buf, sizeof(buf), rn->tn_type), 3773 mp->m_name); 3774 } 3775 return; 3776 } 3777 } 3778 3779 /* 3780 * Takes an expression an returns 0 if this expression can be used 3781 * for static initialisation, otherwise -1. 3782 * 3783 * Constant initialisation expressions must be constant or an address 3784 * of a static object with an optional offset. In the first case, 3785 * the result is returned in *offsp. In the second case, the static 3786 * object is returned in *symp and the offset in *offsp. 3787 * 3788 * The expression can consist of PLUS, MINUS, AMPER, NAME, STRING and 3789 * CON. Type conversions are allowed if they do not change binary 3790 * representation (including width). 3791 */ 3792 int 3793 conaddr(tnode_t *tn, sym_t **symp, ptrdiff_t *offsp) 3794 { 3795 sym_t *sym; 3796 ptrdiff_t offs1, offs2; 3797 tspec_t t, ot; 3798 3799 switch (tn->tn_op) { 3800 case MINUS: 3801 if (tn->tn_right->tn_op == CVT) 3802 return conaddr(tn->tn_right, symp, offsp); 3803 else if (tn->tn_right->tn_op != CON) 3804 return (-1); 3805 /* FALLTHROUGH */ 3806 case PLUS: 3807 offs1 = offs2 = 0; 3808 if (tn->tn_left->tn_op == CON) { 3809 offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad; 3810 if (conaddr(tn->tn_right, &sym, &offs2) == -1) 3811 return (-1); 3812 } else if (tn->tn_right->tn_op == CON) { 3813 offs2 = (ptrdiff_t)tn->tn_right->tn_val->v_quad; 3814 if (tn->tn_op == MINUS) 3815 offs2 = -offs2; 3816 if (conaddr(tn->tn_left, &sym, &offs1) == -1) 3817 return (-1); 3818 } else { 3819 return (-1); 3820 } 3821 *symp = sym; 3822 *offsp = offs1 + offs2; 3823 break; 3824 case AMPER: 3825 if (tn->tn_left->tn_op == NAME) { 3826 *symp = tn->tn_left->tn_sym; 3827 *offsp = 0; 3828 } else if (tn->tn_left->tn_op == STRING) { 3829 /* 3830 * If this would be the front end of a compiler we 3831 * would return a label instead of 0. 3832 */ 3833 *offsp = 0; 3834 } 3835 break; 3836 case CVT: 3837 t = tn->tn_type->t_tspec; 3838 ot = tn->tn_left->tn_type->t_tspec; 3839 if ((!isityp(t) && t != PTR) || (!isityp(ot) && ot != PTR)) 3840 return (-1); 3841 #ifdef notdef 3842 /* 3843 * consider: 3844 * struct foo { 3845 * unsigned char a; 3846 * } f = { 3847 * (u_char)(u_long)(&(((struct foo *)0)->a)) 3848 * }; 3849 * since psize(u_long) != psize(u_char) this fails. 3850 */ 3851 else if (psize(t) != psize(ot)) 3852 return (-1); 3853 #endif 3854 if (conaddr(tn->tn_left, symp, offsp) == -1) 3855 return (-1); 3856 break; 3857 default: 3858 return (-1); 3859 } 3860 return (0); 3861 } 3862 3863 /* 3864 * Concatenate two string constants. 3865 */ 3866 strg_t * 3867 catstrg(strg_t *strg1, strg_t *strg2) 3868 { 3869 size_t len1, len2, len; 3870 3871 if (strg1->st_tspec != strg2->st_tspec) { 3872 /* cannot concatenate wide and regular string literals */ 3873 error(292); 3874 return (strg1); 3875 } 3876 3877 len1 = strg1->st_len; 3878 len2 = strg2->st_len + 1; /* + NUL */ 3879 len = len1 + len2; 3880 3881 #define COPY(F) \ 3882 do { \ 3883 strg1->F = xrealloc(strg1->F, len * sizeof(*strg1->F)); \ 3884 (void)memcpy(strg1->F + len1, strg2->F, len2 * sizeof(*strg1->F)); \ 3885 free(strg2->F); \ 3886 } while (/*CONSTCOND*/0) 3887 3888 if (strg1->st_tspec == CHAR) 3889 COPY(st_cp); 3890 else 3891 COPY(st_wcp); 3892 3893 strg1->st_len = len - 1; /* - NUL */; 3894 free(strg2); 3895 3896 return (strg1); 3897 } 3898 3899 /* 3900 * Print a warning if the given node has operands which should be 3901 * parenthesized. 3902 * 3903 * XXX Does not work if an operand is a constant expression. Constant 3904 * expressions are already folded. 3905 */ 3906 static void 3907 precconf(tnode_t *tn) 3908 { 3909 tnode_t *ln, *rn; 3910 op_t lop, rop = NOOP; 3911 int lparn, rparn = 0; 3912 mod_t *mp; 3913 int dowarn; 3914 3915 if (!hflag) 3916 return; 3917 3918 mp = &modtab[tn->tn_op]; 3919 3920 lparn = 0; 3921 for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left) 3922 lparn |= ln->tn_parn; 3923 lparn |= ln->tn_parn; 3924 lop = ln->tn_op; 3925 3926 if (mp->m_binary) { 3927 rparn = 0; 3928 for (rn = tn->tn_right; tn->tn_op == CVT; rn = rn->tn_left) 3929 rparn |= rn->tn_parn; 3930 rparn |= rn->tn_parn; 3931 rop = rn->tn_op; 3932 } 3933 3934 dowarn = 0; 3935 3936 switch (tn->tn_op) { 3937 case SHL: 3938 case SHR: 3939 if (!lparn && (lop == PLUS || lop == MINUS)) { 3940 dowarn = 1; 3941 } else if (!rparn && (rop == PLUS || rop == MINUS)) { 3942 dowarn = 1; 3943 } 3944 break; 3945 case LOGOR: 3946 if (!lparn && lop == LOGAND) { 3947 dowarn = 1; 3948 } else if (!rparn && rop == LOGAND) { 3949 dowarn = 1; 3950 } 3951 break; 3952 case AND: 3953 case XOR: 3954 case OR: 3955 if (!lparn && lop != tn->tn_op) { 3956 if (lop == PLUS || lop == MINUS) { 3957 dowarn = 1; 3958 } else if (lop == AND || lop == XOR) { 3959 dowarn = 1; 3960 } 3961 } 3962 if (!dowarn && !rparn && rop != tn->tn_op) { 3963 if (rop == PLUS || rop == MINUS) { 3964 dowarn = 1; 3965 } else if (rop == AND || rop == XOR) { 3966 dowarn = 1; 3967 } 3968 } 3969 break; 3970 /* LINTED (enumeration values not handled in switch) */ 3971 case DECAFT: 3972 case XORASS: 3973 case SHLASS: 3974 case NOOP: 3975 case ARROW: 3976 case ORASS: 3977 case POINT: 3978 case NAME: 3979 case NOT: 3980 case COMPL: 3981 case CON: 3982 case INC: 3983 case STRING: 3984 case DEC: 3985 case INCBEF: 3986 case DECBEF: 3987 case INCAFT: 3988 case FSEL: 3989 case CALL: 3990 case COMMA: 3991 case CVT: 3992 case ICALL: 3993 case LOAD: 3994 case PUSH: 3995 case RETURN: 3996 case INIT: 3997 case CASE: 3998 case FARG: 3999 case SUBASS: 4000 case ADDASS: 4001 case MODASS: 4002 case DIVASS: 4003 case MULASS: 4004 case ASSIGN: 4005 case COLON: 4006 case QUEST: 4007 case LOGAND: 4008 case NE: 4009 case EQ: 4010 case GE: 4011 case GT: 4012 case LE: 4013 case LT: 4014 case MINUS: 4015 case PLUS: 4016 case MOD: 4017 case DIV: 4018 case MULT: 4019 case AMPER: 4020 case STAR: 4021 case UMINUS: 4022 case SHRASS: 4023 case UPLUS: 4024 case ANDASS: 4025 case REAL: 4026 case IMAG: 4027 break; 4028 } 4029 4030 if (dowarn) { 4031 /* precedence confusion possible: parenthesize! */ 4032 warning(169); 4033 } 4034 4035 } 4036