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