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