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