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