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