1 /* $NetBSD: tree.c,v 1.25 2002/02/05 03:04:29 thorpej 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 #if defined(__RCSID) && !defined(lint) 36 __RCSID("$NetBSD: tree.c,v 1.25 2002/02/05 03:04:29 thorpej 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, int64_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, int64_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 occurred. */ 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 ((uint64_t)rn->tn_val->v_quad == size(lt)) { 966 /* shift equal to size fo object */ 967 warning(267); 968 } else if ((uint64_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 int64_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 = (uint64_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 (uint64_t)v->v_ldbl : (int64_t)v->v_ldbl; 1925 } 1926 } else { 1927 if (nt == FLOAT) { 1928 nv->v_ldbl = (ot == PTR || isutyp(ot)) ? 1929 (float)(uint64_t)v->v_quad : (float)v->v_quad; 1930 } else if (nt == DOUBLE) { 1931 nv->v_ldbl = (ot == PTR || isutyp(ot)) ? 1932 (double)(uint64_t)v->v_quad : (double)v->v_quad; 1933 } else if (nt == LDOUBLE) { 1934 nv->v_ldbl = (ot == PTR || isutyp(ot)) ? 1935 (ldbl_t)(uint64_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, (int64_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, (int64_t)(elem * elsz / CHAR_BIT))); 2608 } 2609 2610 /* 2611 * XXX 2612 * Note: There appear to be a number of bugs in detecting overflow in 2613 * this function. An audit and a set of proper regression tests are needed. 2614 * --Perry Metzger, Nov. 16, 2001 2615 */ 2616 /* 2617 * Do only as much as necessary to compute constant expressions. 2618 * Called only if the operator allows folding and (both) operands 2619 * are constants. 2620 */ 2621 static tnode_t * 2622 fold(tnode_t *tn) 2623 { 2624 val_t *v; 2625 tspec_t t; 2626 int utyp, ovfl; 2627 int64_t sl, sr = 0, q = 0, mask; 2628 uint64_t ul, ur = 0; 2629 tnode_t *cn; 2630 2631 v = xcalloc(1, sizeof (val_t)); 2632 v->v_tspec = t = tn->tn_type->t_tspec; 2633 2634 utyp = t == PTR || isutyp(t); 2635 ul = sl = tn->tn_left->tn_val->v_quad; 2636 if (modtab[tn->tn_op].m_binary) 2637 ur = sr = tn->tn_right->tn_val->v_quad; 2638 2639 mask = qlmasks[size(t)]; 2640 ovfl = 0; 2641 2642 switch (tn->tn_op) { 2643 case UPLUS: 2644 q = sl; 2645 break; 2646 case UMINUS: 2647 q = -sl; 2648 if (msb(q, t, -1) == msb(sl, t, -1)) 2649 ovfl = 1; 2650 break; 2651 case COMPL: 2652 q = ~sl; 2653 break; 2654 case MULT: 2655 if (utyp) { 2656 q = ul * ur; 2657 if (q != (q & mask)) 2658 ovfl = 1; 2659 else if ((ul != 0) && ((q / ul) != ur)) 2660 ovfl = 1; 2661 } else { 2662 q = sl * sr; 2663 if (msb(q, t, -1) != (msb(sl, t, -1) ^ msb(sr, t, -1))) 2664 ovfl = 1; 2665 } 2666 break; 2667 case DIV: 2668 if (sr == 0) { 2669 /* division by 0 */ 2670 error(139); 2671 q = utyp ? UQUAD_MAX : QUAD_MAX; 2672 } else { 2673 q = utyp ? ul / ur : sl / sr; 2674 } 2675 break; 2676 case MOD: 2677 if (sr == 0) { 2678 /* modulus by 0 */ 2679 error(140); 2680 q = 0; 2681 } else { 2682 q = utyp ? ul % ur : sl % sr; 2683 } 2684 break; 2685 case PLUS: 2686 q = utyp ? ul + ur : sl + sr; 2687 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) != 0) { 2688 if (msb(q, t, -1) == 0) 2689 ovfl = 1; 2690 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) == 0) { 2691 if (msb(q, t, -1) != 0) 2692 ovfl = 1; 2693 } 2694 break; 2695 case MINUS: 2696 q = utyp ? ul - ur : sl - sr; 2697 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) == 0) { 2698 if (msb(q, t, -1) == 0) 2699 ovfl = 1; 2700 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) != 0) { 2701 if (msb(q, t, -1) != 0) 2702 ovfl = 1; 2703 } 2704 break; 2705 case SHL: 2706 q = utyp ? ul << sr : sl << sr; 2707 break; 2708 case SHR: 2709 /* 2710 * The sign must be explicitly extended because 2711 * shifts of signed values are implementation dependent. 2712 */ 2713 q = ul >> sr; 2714 q = xsign(q, t, size(t) - (int)sr); 2715 break; 2716 case LT: 2717 q = utyp ? ul < ur : sl < sr; 2718 break; 2719 case LE: 2720 q = utyp ? ul <= ur : sl <= sr; 2721 break; 2722 case GE: 2723 q = utyp ? ul >= ur : sl >= sr; 2724 break; 2725 case GT: 2726 q = utyp ? ul > ur : sl > sr; 2727 break; 2728 case EQ: 2729 q = utyp ? ul == ur : sl == sr; 2730 break; 2731 case NE: 2732 q = utyp ? ul != ur : sl != sr; 2733 break; 2734 case AND: 2735 q = utyp ? ul & ur : sl & sr; 2736 break; 2737 case XOR: 2738 q = utyp ? ul ^ ur : sl ^ sr; 2739 break; 2740 case OR: 2741 q = utyp ? ul | ur : sl | sr; 2742 break; 2743 default: 2744 lerror("fold() 5"); 2745 } 2746 2747 /* XXX does not work for quads. */ 2748 if (ovfl || ((q | mask) != ~(uint64_t)0 && (q & ~mask) != 0)) { 2749 if (hflag) 2750 /* integer overflow detected, op %s */ 2751 warning(141, modtab[tn->tn_op].m_name); 2752 } 2753 2754 v->v_quad = xsign(q, t, -1); 2755 2756 cn = getcnode(tn->tn_type, v); 2757 2758 return (cn); 2759 } 2760 2761 /* 2762 * Same for operators whose operands are compared with 0 (test context). 2763 */ 2764 static tnode_t * 2765 foldtst(tnode_t *tn) 2766 { 2767 int l, r = 0; 2768 val_t *v; 2769 2770 v = xcalloc(1, sizeof (val_t)); 2771 v->v_tspec = tn->tn_type->t_tspec; 2772 if (tn->tn_type->t_tspec != INT) 2773 lerror("foldtst() 1"); 2774 2775 if (isftyp(tn->tn_left->tn_type->t_tspec)) { 2776 l = tn->tn_left->tn_val->v_ldbl != 0.0; 2777 } else { 2778 l = tn->tn_left->tn_val->v_quad != 0; 2779 } 2780 2781 if (modtab[tn->tn_op].m_binary) { 2782 if (isftyp(tn->tn_right->tn_type->t_tspec)) { 2783 r = tn->tn_right->tn_val->v_ldbl != 0.0; 2784 } else { 2785 r = tn->tn_right->tn_val->v_quad != 0; 2786 } 2787 } 2788 2789 switch (tn->tn_op) { 2790 case NOT: 2791 if (hflag) 2792 /* constant argument to NOT */ 2793 warning(239); 2794 v->v_quad = !l; 2795 break; 2796 case LOGAND: 2797 v->v_quad = l && r; 2798 break; 2799 case LOGOR: 2800 v->v_quad = l || r; 2801 break; 2802 default: 2803 lerror("foldtst() 1"); 2804 } 2805 2806 return (getcnode(tn->tn_type, v)); 2807 } 2808 2809 /* 2810 * Same for operands with floating point type. 2811 */ 2812 static tnode_t * 2813 foldflt(tnode_t *tn) 2814 { 2815 val_t *v; 2816 tspec_t t; 2817 ldbl_t l, r = 0; 2818 2819 v = xcalloc(1, sizeof (val_t)); 2820 v->v_tspec = t = tn->tn_type->t_tspec; 2821 2822 if (!isftyp(t)) 2823 lerror("foldflt() 1"); 2824 2825 if (t != tn->tn_left->tn_type->t_tspec) 2826 lerror("foldflt() 2"); 2827 if (modtab[tn->tn_op].m_binary && t != tn->tn_right->tn_type->t_tspec) 2828 lerror("foldflt() 3"); 2829 2830 l = tn->tn_left->tn_val->v_ldbl; 2831 if (modtab[tn->tn_op].m_binary) 2832 r = tn->tn_right->tn_val->v_ldbl; 2833 2834 switch (tn->tn_op) { 2835 case UPLUS: 2836 v->v_ldbl = l; 2837 break; 2838 case UMINUS: 2839 v->v_ldbl = -l; 2840 break; 2841 case MULT: 2842 v->v_ldbl = l * r; 2843 break; 2844 case DIV: 2845 if (r == 0.0) { 2846 /* division by 0 */ 2847 error(139); 2848 if (t == FLOAT) { 2849 v->v_ldbl = l < 0 ? -FLT_MAX : FLT_MAX; 2850 } else if (t == DOUBLE) { 2851 v->v_ldbl = l < 0 ? -DBL_MAX : DBL_MAX; 2852 } else { 2853 v->v_ldbl = l < 0 ? -LDBL_MAX : LDBL_MAX; 2854 } 2855 } else { 2856 v->v_ldbl = l / r; 2857 } 2858 break; 2859 case PLUS: 2860 v->v_ldbl = l + r; 2861 break; 2862 case MINUS: 2863 v->v_ldbl = l - r; 2864 break; 2865 case LT: 2866 v->v_quad = l < r; 2867 break; 2868 case LE: 2869 v->v_quad = l <= r; 2870 break; 2871 case GE: 2872 v->v_quad = l >= r; 2873 break; 2874 case GT: 2875 v->v_quad = l > r; 2876 break; 2877 case EQ: 2878 v->v_quad = l == r; 2879 break; 2880 case NE: 2881 v->v_quad = l != r; 2882 break; 2883 default: 2884 lerror("foldflt() 4"); 2885 } 2886 2887 if (isnan((double)v->v_ldbl)) 2888 lerror("foldflt() 5"); 2889 if (!finite((double)v->v_ldbl) || 2890 (t == FLOAT && 2891 (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || 2892 (t == DOUBLE && 2893 (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) { 2894 /* floating point overflow detected, op %s */ 2895 warning(142, modtab[tn->tn_op].m_name); 2896 if (t == FLOAT) { 2897 v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX; 2898 } else if (t == DOUBLE) { 2899 v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX; 2900 } else { 2901 v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX; 2902 } 2903 } 2904 2905 return (getcnode(tn->tn_type, v)); 2906 } 2907 2908 /* 2909 * Create a constant node for sizeof. 2910 */ 2911 tnode_t * 2912 bldszof(type_t *tp) 2913 { 2914 int elem, elsz; 2915 tspec_t st; 2916 2917 elem = 1; 2918 while (tp->t_tspec == ARRAY) { 2919 elem *= tp->t_dim; 2920 tp = tp->t_subt; 2921 } 2922 if (elem == 0) { 2923 /* cannot take size of incomplete type */ 2924 error(143); 2925 elem = 1; 2926 } 2927 switch (tp->t_tspec) { 2928 case FUNC: 2929 /* cannot take size of function */ 2930 error(144); 2931 elsz = 1; 2932 break; 2933 case STRUCT: 2934 case UNION: 2935 if (incompl(tp)) { 2936 /* cannot take size of incomplete type */ 2937 error(143); 2938 elsz = 1; 2939 } else { 2940 elsz = tp->t_str->size; 2941 } 2942 break; 2943 case ENUM: 2944 if (incompl(tp)) { 2945 /* cannot take size of incomplete type */ 2946 warning(143); 2947 } 2948 /* FALLTHROUGH */ 2949 default: 2950 if (tp->t_isfield) { 2951 /* cannot take size of bit-field */ 2952 error(145); 2953 } 2954 if (tp->t_tspec == VOID) { 2955 /* cannot take size of void */ 2956 error(146); 2957 elsz = 1; 2958 } else { 2959 elsz = size(tp->t_tspec); 2960 if (elsz <= 0) 2961 lerror("bldszof() 1"); 2962 } 2963 break; 2964 } 2965 2966 #if SIZEOF_IS_ULONG 2967 st = ULONG; 2968 #else 2969 st = UINT; 2970 #endif 2971 2972 return (getinode(st, (int64_t)(elem * elsz / CHAR_BIT))); 2973 } 2974 2975 /* 2976 * Type casts. 2977 */ 2978 tnode_t * 2979 cast(tnode_t *tn, type_t *tp) 2980 { 2981 tspec_t nt, ot; 2982 2983 if (tn == NULL) 2984 return (NULL); 2985 2986 tn = cconv(tn); 2987 2988 nt = tp->t_tspec; 2989 ot = tn->tn_type->t_tspec; 2990 2991 if (nt == VOID) { 2992 /* 2993 * XXX ANSI C requires scalar types or void (Plauger&Brodie). 2994 * But this seams really questionable. 2995 */ 2996 } else if (nt == STRUCT || nt == UNION || nt == ARRAY || nt == FUNC) { 2997 /* invalid cast expression */ 2998 error(147); 2999 return (NULL); 3000 } else if (ot == STRUCT || ot == UNION) { 3001 /* invalid cast expression */ 3002 error(147); 3003 return (NULL); 3004 } else if (ot == VOID) { 3005 /* improper cast of void expression */ 3006 error(148); 3007 return (NULL); 3008 } else if (isityp(nt) && issclt(ot)) { 3009 /* ok */ 3010 } else if (isftyp(nt) && isatyp(ot)) { 3011 /* ok */ 3012 } else if (nt == PTR && isityp(ot)) { 3013 /* ok */ 3014 } else if (nt == PTR && ot == PTR) { 3015 if (!tp->t_subt->t_const && tn->tn_type->t_subt->t_const) { 3016 if (hflag) 3017 /* cast discards 'const' from ... */ 3018 warning(275); 3019 } 3020 } else { 3021 /* invalid cast expression */ 3022 error(147); 3023 return (NULL); 3024 } 3025 3026 tn = convert(CVT, 0, tp, tn); 3027 tn->tn_cast = 1; 3028 3029 return (tn); 3030 } 3031 3032 /* 3033 * Create the node for a function argument. 3034 * All necessary conversions and type checks are done in funccall(), because 3035 * in funcarg() we have no information about expected argument types. 3036 */ 3037 tnode_t * 3038 funcarg(tnode_t *args, tnode_t *arg) 3039 { 3040 tnode_t *ntn; 3041 3042 /* 3043 * If there was a serious error in the expression for the argument, 3044 * create a dummy argument so the positions of the remaining arguments 3045 * will not change. 3046 */ 3047 if (arg == NULL) 3048 arg = getinode(INT, (int64_t)0); 3049 3050 ntn = mktnode(PUSH, arg->tn_type, arg, args); 3051 3052 return (ntn); 3053 } 3054 3055 /* 3056 * Create the node for a function call. Also check types of 3057 * function arguments and insert conversions, if necessary. 3058 */ 3059 tnode_t * 3060 funccall(tnode_t *func, tnode_t *args) 3061 { 3062 tnode_t *ntn; 3063 op_t fcop; 3064 3065 if (func == NULL) 3066 return (NULL); 3067 3068 if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) { 3069 fcop = CALL; 3070 } else { 3071 fcop = ICALL; 3072 } 3073 3074 /* 3075 * after cconv() func will always be a pointer to a function 3076 * if it is a valid function designator. 3077 */ 3078 func = cconv(func); 3079 3080 if (func->tn_type->t_tspec != PTR || 3081 func->tn_type->t_subt->t_tspec != FUNC) { 3082 /* illegal function */ 3083 error(149); 3084 return (NULL); 3085 } 3086 3087 args = chkfarg(func->tn_type->t_subt, args); 3088 3089 ntn = mktnode(fcop, func->tn_type->t_subt->t_subt, func, args); 3090 3091 return (ntn); 3092 } 3093 3094 /* 3095 * Check types of all function arguments and insert conversions, 3096 * if necessary. 3097 */ 3098 static tnode_t * 3099 chkfarg(type_t *ftp, tnode_t *args) 3100 { 3101 tnode_t *arg; 3102 sym_t *asym; 3103 tspec_t at; 3104 int narg, npar, n, i; 3105 3106 /* get # of args in the prototype */ 3107 npar = 0; 3108 for (asym = ftp->t_args; asym != NULL; asym = asym->s_nxt) 3109 npar++; 3110 3111 /* get # of args in function call */ 3112 narg = 0; 3113 for (arg = args; arg != NULL; arg = arg->tn_right) 3114 narg++; 3115 3116 asym = ftp->t_args; 3117 if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) { 3118 /* argument mismatch: %d arg%s passed, %d expected */ 3119 error(150, narg, narg > 1 ? "s" : "", npar); 3120 asym = NULL; 3121 } 3122 3123 for (n = 1; n <= narg; n++) { 3124 3125 /* 3126 * The rightmost argument is at the top of the argument 3127 * subtree. 3128 */ 3129 for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) 3130 continue; 3131 3132 /* some things which are always not allowd */ 3133 if ((at = arg->tn_left->tn_type->t_tspec) == VOID) { 3134 /* void expressions may not be arguments, arg #%d */ 3135 error(151, n); 3136 return (NULL); 3137 } else if ((at == STRUCT || at == UNION) && 3138 incompl(arg->tn_left->tn_type)) { 3139 /* argument cannot have unknown size, arg #%d */ 3140 error(152, n); 3141 return (NULL); 3142 } else if (isityp(at) && arg->tn_left->tn_type->t_isenum && 3143 incompl(arg->tn_left->tn_type)) { 3144 /* argument cannot have unknown size, arg #%d */ 3145 warning(152, n); 3146 } 3147 3148 /* class conversions (arg in value context) */ 3149 arg->tn_left = cconv(arg->tn_left); 3150 3151 if (asym != NULL) { 3152 arg->tn_left = parg(n, asym->s_type, arg->tn_left); 3153 } else { 3154 arg->tn_left = promote(NOOP, 1, arg->tn_left); 3155 } 3156 arg->tn_type = arg->tn_left->tn_type; 3157 3158 if (asym != NULL) 3159 asym = asym->s_nxt; 3160 } 3161 3162 return (args); 3163 } 3164 3165 /* 3166 * Compare the type of an argument with the corresponding type of a 3167 * prototype parameter. If it is a valid combination, but both types 3168 * are not the same, insert a conversion to convert the argument into 3169 * the type of the parameter. 3170 */ 3171 static tnode_t * 3172 parg( int n, /* pos of arg */ 3173 type_t *tp, /* expected type (from prototype) */ 3174 tnode_t *tn) /* argument */ 3175 { 3176 tnode_t *ln; 3177 int warn; 3178 3179 ln = xcalloc(1, sizeof (tnode_t)); 3180 ln->tn_type = tduptyp(tp); 3181 ln->tn_type->t_const = 0; 3182 ln->tn_lvalue = 1; 3183 if (typeok(FARG, n, ln, tn)) { 3184 if (!eqtype(tp, tn->tn_type, 1, 0, (warn = 0, &warn)) || warn) 3185 tn = convert(FARG, n, tp, tn); 3186 } 3187 free(ln); 3188 return (tn); 3189 } 3190 3191 /* 3192 * Return the value of an integral constant expression. 3193 * If the expression is not constant or its type is not an integer 3194 * type, an error message is printed. 3195 */ 3196 val_t * 3197 constant(tnode_t *tn) 3198 { 3199 val_t *v; 3200 3201 if (tn != NULL) 3202 tn = cconv(tn); 3203 if (tn != NULL) 3204 tn = promote(NOOP, 0, tn); 3205 3206 v = xcalloc(1, sizeof (val_t)); 3207 3208 if (tn == NULL) { 3209 if (nerr == 0) 3210 lerror("constant() 1"); 3211 v->v_tspec = INT; 3212 v->v_quad = 1; 3213 return (v); 3214 } 3215 3216 v->v_tspec = tn->tn_type->t_tspec; 3217 3218 if (tn->tn_op == CON) { 3219 if (tn->tn_type->t_tspec != tn->tn_val->v_tspec) 3220 lerror("constant() 2"); 3221 if (isityp(tn->tn_val->v_tspec)) { 3222 v->v_ansiu = tn->tn_val->v_ansiu; 3223 v->v_quad = tn->tn_val->v_quad; 3224 return (v); 3225 } 3226 v->v_quad = tn->tn_val->v_ldbl; 3227 } else { 3228 v->v_quad = 1; 3229 } 3230 3231 /* integral constant expression expected */ 3232 error(55); 3233 3234 if (!isityp(v->v_tspec)) 3235 v->v_tspec = INT; 3236 3237 return (v); 3238 } 3239 3240 /* 3241 * Perform some tests on expressions which can't be done in build() and 3242 * functions called by build(). These tests must be done here because 3243 * we need some information about the context in which the operations 3244 * are performed. 3245 * After all tests are performed, expr() frees the memory which is used 3246 * for the expression. 3247 */ 3248 void 3249 expr(tnode_t *tn, int vctx, int tctx) 3250 { 3251 3252 if (tn == NULL && nerr == 0) 3253 lerror("expr() 1"); 3254 3255 if (tn == NULL) { 3256 tfreeblk(); 3257 return; 3258 } 3259 3260 /* expr() is also called in global initialisations */ 3261 if (dcs->d_ctx != EXTERN) 3262 chkreach(); 3263 3264 chkmisc(tn, vctx, tctx, !tctx, 0, 0, 0); 3265 if (tn->tn_op == ASSIGN) { 3266 if (hflag && tctx) 3267 /* assignment in conditional context */ 3268 warning(159); 3269 } else if (tn->tn_op == CON) { 3270 if (hflag && tctx && !ccflg) 3271 /* constant in conditional context */ 3272 warning(161); 3273 } 3274 if (!modtab[tn->tn_op].m_sideeff) { 3275 /* 3276 * for left operands of COMMA this warning is already 3277 * printed 3278 */ 3279 if (tn->tn_op != COMMA && !vctx && !tctx) 3280 nulleff(tn); 3281 } 3282 if (dflag) 3283 displexpr(tn, 0); 3284 3285 /* free the tree memory */ 3286 tfreeblk(); 3287 } 3288 3289 static void 3290 nulleff(tnode_t *tn) 3291 { 3292 3293 if (!hflag) 3294 return; 3295 3296 while (!modtab[tn->tn_op].m_sideeff) { 3297 if (tn->tn_op == CVT && tn->tn_type->t_tspec == VOID) { 3298 tn = tn->tn_left; 3299 } else if (tn->tn_op == LOGAND || tn->tn_op == LOGOR) { 3300 /* 3301 * && and || have a side effect if the right operand 3302 * has a side effect. 3303 */ 3304 tn = tn->tn_right; 3305 } else if (tn->tn_op == QUEST) { 3306 /* 3307 * ? has a side effect if at least one of its right 3308 * operands has a side effect 3309 */ 3310 tn = tn->tn_right; 3311 } else if (tn->tn_op == COLON || tn->tn_op == COMMA) { 3312 /* 3313 * : has a side effect if at least one of its operands 3314 * has a side effect 3315 */ 3316 if (modtab[tn->tn_left->tn_op].m_sideeff) { 3317 tn = tn->tn_left; 3318 } else if (modtab[tn->tn_right->tn_op].m_sideeff) { 3319 tn = tn->tn_right; 3320 } else { 3321 break; 3322 } 3323 } else { 3324 break; 3325 } 3326 } 3327 if (!modtab[tn->tn_op].m_sideeff) 3328 /* expression has null effect */ 3329 warning(129); 3330 } 3331 3332 /* 3333 * Dump an expression to stdout 3334 * only used for debugging 3335 */ 3336 static void 3337 displexpr(tnode_t *tn, int offs) 3338 { 3339 uint64_t uq; 3340 3341 if (tn == NULL) { 3342 (void)printf("%*s%s\n", offs, "", "NULL"); 3343 return; 3344 } 3345 (void)printf("%*sop %s ", offs, "", modtab[tn->tn_op].m_name); 3346 3347 if (tn->tn_op == NAME) { 3348 (void)printf("%s: %s ", 3349 tn->tn_sym->s_name, scltoa(tn->tn_sym->s_scl)); 3350 } else if (tn->tn_op == CON && isftyp(tn->tn_type->t_tspec)) { 3351 (void)printf("%#g ", (double)tn->tn_val->v_ldbl); 3352 } else if (tn->tn_op == CON && isityp(tn->tn_type->t_tspec)) { 3353 uq = tn->tn_val->v_quad; 3354 (void)printf("0x %08lx %08lx ", (long)(uq >> 32) & 0xffffffffl, 3355 (long)uq & 0xffffffffl); 3356 } else if (tn->tn_op == CON) { 3357 if (tn->tn_type->t_tspec != PTR) 3358 lerror("displexpr() 1"); 3359 (void)printf("0x%0*lx ", (int)(sizeof (void *) * CHAR_BIT / 4), 3360 (u_long)tn->tn_val->v_quad); 3361 } else if (tn->tn_op == STRING) { 3362 if (tn->tn_strg->st_tspec == CHAR) { 3363 (void)printf("\"%s\"", tn->tn_strg->st_cp); 3364 } else { 3365 char *s; 3366 size_t n; 3367 n = MB_CUR_MAX * (tn->tn_strg->st_len + 1); 3368 s = xmalloc(n); 3369 (void)wcstombs(s, tn->tn_strg->st_wcp, n); 3370 (void)printf("L\"%s\"", s); 3371 free(s); 3372 } 3373 (void)printf(" "); 3374 } else if (tn->tn_op == FSEL) { 3375 (void)printf("o=%d, l=%d ", tn->tn_type->t_foffs, 3376 tn->tn_type->t_flen); 3377 } 3378 (void)printf("%s\n", ttos(tn->tn_type)); 3379 if (tn->tn_op == NAME || tn->tn_op == CON || tn->tn_op == STRING) 3380 return; 3381 displexpr(tn->tn_left, offs + 2); 3382 if (modtab[tn->tn_op].m_binary || 3383 (tn->tn_op == PUSH && tn->tn_right != NULL)) { 3384 displexpr(tn->tn_right, offs + 2); 3385 } 3386 } 3387 3388 /* 3389 * Called by expr() to recursively perform some tests. 3390 */ 3391 /* ARGSUSED */ 3392 void 3393 chkmisc(tnode_t *tn, int vctx, int tctx, int eqwarn, int fcall, int rvdisc, 3394 int szof) 3395 { 3396 tnode_t *ln, *rn; 3397 mod_t *mp; 3398 int nrvdisc, cvctx, ctctx; 3399 op_t op; 3400 scl_t sc; 3401 dinfo_t *di; 3402 3403 if (tn == NULL) 3404 return; 3405 3406 ln = tn->tn_left; 3407 rn = tn->tn_right; 3408 mp = &modtab[op = tn->tn_op]; 3409 3410 switch (op) { 3411 case AMPER: 3412 if (ln->tn_op == NAME && (reached || rchflg)) { 3413 if (!szof) 3414 setsflg(ln->tn_sym); 3415 setuflg(ln->tn_sym, fcall, szof); 3416 } 3417 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) 3418 /* check the range of array indices */ 3419 chkaidx(ln->tn_left, 1); 3420 break; 3421 case LOAD: 3422 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) 3423 /* check the range of array indices */ 3424 chkaidx(ln->tn_left, 0); 3425 /* FALLTHROUGH */ 3426 case PUSH: 3427 case INCBEF: 3428 case DECBEF: 3429 case INCAFT: 3430 case DECAFT: 3431 case ADDASS: 3432 case SUBASS: 3433 case MULASS: 3434 case DIVASS: 3435 case MODASS: 3436 case ANDASS: 3437 case ORASS: 3438 case XORASS: 3439 case SHLASS: 3440 case SHRASS: 3441 if (ln->tn_op == NAME && (reached || rchflg)) { 3442 sc = ln->tn_sym->s_scl; 3443 /* 3444 * Look if there was a asm statement in one of the 3445 * compound statements we are in. If not, we don't 3446 * print a warning. 3447 */ 3448 for (di = dcs; di != NULL; di = di->d_nxt) { 3449 if (di->d_asm) 3450 break; 3451 } 3452 if (sc != EXTERN && sc != STATIC && 3453 !ln->tn_sym->s_set && !szof && di == NULL) { 3454 /* %s may be used before set */ 3455 warning(158, ln->tn_sym->s_name); 3456 setsflg(ln->tn_sym); 3457 } 3458 setuflg(ln->tn_sym, 0, 0); 3459 } 3460 break; 3461 case ASSIGN: 3462 if (ln->tn_op == NAME && !szof && (reached || rchflg)) { 3463 setsflg(ln->tn_sym); 3464 if (ln->tn_sym->s_scl == EXTERN) 3465 outusg(ln->tn_sym); 3466 } 3467 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) 3468 /* check the range of array indices */ 3469 chkaidx(ln->tn_left, 0); 3470 break; 3471 case CALL: 3472 if (ln->tn_op != AMPER || ln->tn_left->tn_op != NAME) 3473 lerror("chkmisc() 1"); 3474 if (!szof) 3475 outcall(tn, vctx || tctx, rvdisc); 3476 break; 3477 case EQ: 3478 /* equality operator "==" found where "=" was exp. */ 3479 if (hflag && eqwarn) 3480 warning(160); 3481 break; 3482 case CON: 3483 case NAME: 3484 case STRING: 3485 return; 3486 /* LINTED (enumeration values not handled in switch) */ 3487 case OR: 3488 case XOR: 3489 case NE: 3490 case GE: 3491 case GT: 3492 case LE: 3493 case LT: 3494 case SHR: 3495 case SHL: 3496 case MINUS: 3497 case PLUS: 3498 case MOD: 3499 case DIV: 3500 case MULT: 3501 case STAR: 3502 case UMINUS: 3503 case UPLUS: 3504 case DEC: 3505 case INC: 3506 case COMPL: 3507 case NOT: 3508 case POINT: 3509 case ARROW: 3510 case NOOP: 3511 case AND: 3512 case FARG: 3513 case CASE: 3514 case INIT: 3515 case RETURN: 3516 case ICALL: 3517 case CVT: 3518 case COMMA: 3519 case FSEL: 3520 case COLON: 3521 case QUEST: 3522 case LOGOR: 3523 case LOGAND: 3524 break; 3525 } 3526 3527 cvctx = mp->m_vctx; 3528 ctctx = mp->m_tctx; 3529 /* 3530 * values of operands of ':' are not used if the type of at least 3531 * one of the operands (for gcc compatibility) is void 3532 * XXX test/value context of QUEST should probably be used as 3533 * context for both operands of COLON 3534 */ 3535 if (op == COLON && tn->tn_type->t_tspec == VOID) 3536 cvctx = ctctx = 0; 3537 nrvdisc = op == CVT && tn->tn_type->t_tspec == VOID; 3538 chkmisc(ln, cvctx, ctctx, mp->m_eqwarn, op == CALL, nrvdisc, szof); 3539 3540 switch (op) { 3541 case PUSH: 3542 if (rn != NULL) 3543 chkmisc(rn, 0, 0, mp->m_eqwarn, 0, 0, szof); 3544 break; 3545 case LOGAND: 3546 case LOGOR: 3547 chkmisc(rn, 0, 1, mp->m_eqwarn, 0, 0, szof); 3548 break; 3549 case COLON: 3550 chkmisc(rn, cvctx, ctctx, mp->m_eqwarn, 0, 0, szof); 3551 break; 3552 case COMMA: 3553 chkmisc(rn, vctx, tctx, mp->m_eqwarn, 0, 0, szof); 3554 break; 3555 default: 3556 if (mp->m_binary) 3557 chkmisc(rn, 1, 0, mp->m_eqwarn, 0, 0, szof); 3558 break; 3559 } 3560 3561 } 3562 3563 /* 3564 * Checks the range of array indices, if possible. 3565 * amper is set if only the address of the element is used. This 3566 * means that the index is allowd to refere to the first element 3567 * after the array. 3568 */ 3569 static void 3570 chkaidx(tnode_t *tn, int amper) 3571 { 3572 int dim; 3573 tnode_t *ln, *rn; 3574 int elsz; 3575 int64_t con; 3576 3577 ln = tn->tn_left; 3578 rn = tn->tn_right; 3579 3580 /* We can only check constant indices. */ 3581 if (rn->tn_op != CON) 3582 return; 3583 3584 /* Return if the left node does not stem from an array. */ 3585 if (ln->tn_op != AMPER) 3586 return; 3587 if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME) 3588 return; 3589 if (ln->tn_left->tn_type->t_tspec != ARRAY) 3590 return; 3591 3592 /* 3593 * For incomplete array types, we can print a warning only if 3594 * the index is negative. 3595 */ 3596 if (incompl(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0) 3597 return; 3598 3599 /* Get the size of one array element */ 3600 if ((elsz = length(ln->tn_type->t_subt, NULL)) == 0) 3601 return; 3602 elsz /= CHAR_BIT; 3603 3604 /* Change the unit of the index from bytes to element size. */ 3605 if (isutyp(rn->tn_type->t_tspec)) { 3606 con = (uint64_t)rn->tn_val->v_quad / elsz; 3607 } else { 3608 con = rn->tn_val->v_quad / elsz; 3609 } 3610 3611 dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0); 3612 3613 if (!isutyp(rn->tn_type->t_tspec) && con < 0) { 3614 /* array subscript cannot be negative: %ld */ 3615 warning(167, (long)con); 3616 } else if (dim > 0 && (uint64_t)con >= dim) { 3617 /* array subscript cannot be > %d: %ld */ 3618 warning(168, dim - 1, (long)con); 3619 } 3620 } 3621 3622 /* 3623 * Check for ordered comparisons of unsigned values with 0. 3624 */ 3625 static void 3626 chkcomp(op_t op, tnode_t *ln, tnode_t *rn) 3627 { 3628 tspec_t lt, rt; 3629 mod_t *mp; 3630 3631 lt = ln->tn_type->t_tspec; 3632 rt = rn->tn_type->t_tspec; 3633 mp = &modtab[op]; 3634 3635 if (ln->tn_op != CON && rn->tn_op != CON) 3636 return; 3637 3638 if (!isityp(lt) || !isityp(rt)) 3639 return; 3640 3641 if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON && 3642 (rn->tn_val->v_quad < 0 || 3643 rn->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) { 3644 /* nonportable character comparison, op %s */ 3645 warning(230, mp->m_name); 3646 return; 3647 } 3648 if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON && 3649 (ln->tn_val->v_quad < 0 || 3650 ln->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) { 3651 /* nonportable character comparison, op %s */ 3652 warning(230, mp->m_name); 3653 return; 3654 } 3655 if (isutyp(lt) && !isutyp(rt) && 3656 rn->tn_op == CON && rn->tn_val->v_quad <= 0) { 3657 if (rn->tn_val->v_quad < 0) { 3658 /* comparison of %s with %s, op %s */ 3659 warning(162, tyname(ln->tn_type), "negative constant", 3660 mp->m_name); 3661 } else if (op == LT || op == GE || (hflag && op == LE)) { 3662 /* comparison of %s with %s, op %s */ 3663 warning(162, tyname(ln->tn_type), "0", mp->m_name); 3664 } 3665 return; 3666 } 3667 if (isutyp(rt) && !isutyp(lt) && 3668 ln->tn_op == CON && ln->tn_val->v_quad <= 0) { 3669 if (ln->tn_val->v_quad < 0) { 3670 /* comparison of %s with %s, op %s */ 3671 warning(162, "negative constant", tyname(rn->tn_type), 3672 mp->m_name); 3673 } else if (op == GT || op == LE || (hflag && op == GE)) { 3674 /* comparison of %s with %s, op %s */ 3675 warning(162, "0", tyname(rn->tn_type), mp->m_name); 3676 } 3677 return; 3678 } 3679 } 3680 3681 /* 3682 * Takes an expression an returns 0 if this expression can be used 3683 * for static initialisation, otherwise -1. 3684 * 3685 * Constant initialisation expressions must be costant or an address 3686 * of a static object with an optional offset. In the first case, 3687 * the result is returned in *offsp. In the second case, the static 3688 * object is returned in *symp and the offset in *offsp. 3689 * 3690 * The expression can consist of PLUS, MINUS, AMPER, NAME, STRING and 3691 * CON. Type conversions are allowed if they do not change binary 3692 * representation (including width). 3693 */ 3694 int 3695 conaddr(tnode_t *tn, sym_t **symp, ptrdiff_t *offsp) 3696 { 3697 sym_t *sym; 3698 ptrdiff_t offs1, offs2; 3699 tspec_t t, ot; 3700 3701 switch (tn->tn_op) { 3702 case MINUS: 3703 if (tn->tn_right->tn_op != CON) 3704 return (-1); 3705 /* FALLTHROUGH */ 3706 case PLUS: 3707 offs1 = offs2 = 0; 3708 if (tn->tn_left->tn_op == CON) { 3709 offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad; 3710 if (conaddr(tn->tn_right, &sym, &offs2) == -1) 3711 return (-1); 3712 } else if (tn->tn_right->tn_op == CON) { 3713 offs2 = (ptrdiff_t)tn->tn_right->tn_val->v_quad; 3714 if (tn->tn_op == MINUS) 3715 offs2 = -offs2; 3716 if (conaddr(tn->tn_left, &sym, &offs1) == -1) 3717 return (-1); 3718 } else { 3719 return (-1); 3720 } 3721 *symp = sym; 3722 *offsp = offs1 + offs2; 3723 break; 3724 case AMPER: 3725 if (tn->tn_left->tn_op == NAME) { 3726 *symp = tn->tn_left->tn_sym; 3727 *offsp = 0; 3728 } else if (tn->tn_left->tn_op == STRING) { 3729 /* 3730 * If this would be the front end of a compiler we 3731 * would return a label instead of 0. 3732 */ 3733 *offsp = 0; 3734 } 3735 break; 3736 case CVT: 3737 t = tn->tn_type->t_tspec; 3738 ot = tn->tn_left->tn_type->t_tspec; 3739 if ((!isityp(t) && t != PTR) || (!isityp(ot) && ot != PTR)) { 3740 return (-1); 3741 } else if (psize(t) != psize(ot)) { 3742 return (-1); 3743 } 3744 if (conaddr(tn->tn_left, symp, offsp) == -1) 3745 return (-1); 3746 break; 3747 default: 3748 return (-1); 3749 } 3750 return (0); 3751 } 3752 3753 /* 3754 * Concatenate two string constants. 3755 */ 3756 strg_t * 3757 catstrg(strg_t *strg1, strg_t *strg2) 3758 { 3759 size_t len1, len2, len; 3760 3761 if (strg1->st_tspec != strg2->st_tspec) { 3762 /* cannot concatenate wide and regular string literals */ 3763 error(292); 3764 return (strg1); 3765 } 3766 3767 len = (len1 = strg1->st_len) + (len2 = strg2->st_len); 3768 3769 if (strg1->st_tspec == CHAR) { 3770 strg1->st_cp = xrealloc(strg1->st_cp, len + 1); 3771 (void)memcpy(strg1->st_cp + len1, strg2->st_cp, len2 + 1); 3772 free(strg2->st_cp); 3773 } else { 3774 strg1->st_wcp = xrealloc(strg1->st_wcp, 3775 (len + 1) * sizeof (wchar_t)); 3776 (void)memcpy(strg1->st_wcp + len1, strg2->st_wcp, 3777 (len2 + 1) * sizeof (wchar_t)); 3778 free(strg2->st_wcp); 3779 } 3780 free(strg2); 3781 3782 return (strg1); 3783 } 3784 3785 /* 3786 * Print a warning if the given node has operands which should be 3787 * parenthesized. 3788 * 3789 * XXX Does not work if an operand is a constant expression. Constant 3790 * expressions are already folded. 3791 */ 3792 static void 3793 precconf(tnode_t *tn) 3794 { 3795 tnode_t *ln, *rn; 3796 op_t lop, rop = NOOP; 3797 int lparn, rparn = 0; 3798 mod_t *mp; 3799 int warn; 3800 3801 if (!hflag) 3802 return; 3803 3804 mp = &modtab[tn->tn_op]; 3805 3806 lparn = 0; 3807 for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left) 3808 lparn |= ln->tn_parn; 3809 lparn |= ln->tn_parn; 3810 lop = ln->tn_op; 3811 3812 if (mp->m_binary) { 3813 rparn = 0; 3814 for (rn = tn->tn_right; tn->tn_op == CVT; rn = rn->tn_left) 3815 rparn |= rn->tn_parn; 3816 rparn |= rn->tn_parn; 3817 rop = rn->tn_op; 3818 } 3819 3820 warn = 0; 3821 3822 switch (tn->tn_op) { 3823 case SHL: 3824 case SHR: 3825 if (!lparn && (lop == PLUS || lop == MINUS)) { 3826 warn = 1; 3827 } else if (!rparn && (rop == PLUS || rop == MINUS)) { 3828 warn = 1; 3829 } 3830 break; 3831 case LOGOR: 3832 if (!lparn && lop == LOGAND) { 3833 warn = 1; 3834 } else if (!rparn && rop == LOGAND) { 3835 warn = 1; 3836 } 3837 break; 3838 case AND: 3839 case XOR: 3840 case OR: 3841 if (!lparn && lop != tn->tn_op) { 3842 if (lop == PLUS || lop == MINUS) { 3843 warn = 1; 3844 } else if (lop == AND || lop == XOR) { 3845 warn = 1; 3846 } 3847 } 3848 if (!warn && !rparn && rop != tn->tn_op) { 3849 if (rop == PLUS || rop == MINUS) { 3850 warn = 1; 3851 } else if (rop == AND || rop == XOR) { 3852 warn = 1; 3853 } 3854 } 3855 break; 3856 /* LINTED (enumeration values not handled in switch) */ 3857 case DECAFT: 3858 case XORASS: 3859 case SHLASS: 3860 case NOOP: 3861 case ARROW: 3862 case ORASS: 3863 case POINT: 3864 case NAME: 3865 case NOT: 3866 case COMPL: 3867 case CON: 3868 case INC: 3869 case STRING: 3870 case DEC: 3871 case INCBEF: 3872 case DECBEF: 3873 case INCAFT: 3874 case FSEL: 3875 case CALL: 3876 case COMMA: 3877 case CVT: 3878 case ICALL: 3879 case LOAD: 3880 case PUSH: 3881 case RETURN: 3882 case INIT: 3883 case CASE: 3884 case FARG: 3885 case SUBASS: 3886 case ADDASS: 3887 case MODASS: 3888 case DIVASS: 3889 case MULASS: 3890 case ASSIGN: 3891 case COLON: 3892 case QUEST: 3893 case LOGAND: 3894 case NE: 3895 case EQ: 3896 case GE: 3897 case GT: 3898 case LE: 3899 case LT: 3900 case MINUS: 3901 case PLUS: 3902 case MOD: 3903 case DIV: 3904 case MULT: 3905 case AMPER: 3906 case STAR: 3907 case UMINUS: 3908 case SHRASS: 3909 case UPLUS: 3910 case ANDASS: 3911 break; 3912 } 3913 3914 if (warn) { 3915 /* precedence confusion possible: parenthesize! */ 3916 warning(169); 3917 } 3918 3919 } 3920