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