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