1 /* $NetBSD: tree.c,v 1.51 2008/07/31 15:21:34 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1994, 1995 Jochen Pohl 5 * All Rights Reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Jochen Pohl for 18 * The NetBSD Project. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #if HAVE_NBTOOL_CONFIG_H 35 #include "nbtool_config.h" 36 #endif 37 38 #include <sys/cdefs.h> 39 #if defined(__RCSID) && !defined(lint) 40 __RCSID("$NetBSD: tree.c,v 1.51 2008/07/31 15:21:34 christos Exp $"); 41 #endif 42 43 #include <stdlib.h> 44 #include <string.h> 45 #include <float.h> 46 #include <limits.h> 47 #include <math.h> 48 #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 } 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 == LDOUBLE || rt == LDOUBLE) { 1633 t = LDOUBLE; 1634 } else if (lt == DOUBLE || rt == DOUBLE) { 1635 t = DOUBLE; 1636 } else if (lt == FLOAT || rt == FLOAT) { 1637 t = FLOAT; 1638 } else { 1639 /* 1640 * If type A has more bits than type B it should 1641 * be able to hold all possible values of type B. 1642 */ 1643 if (size(lt) > size(rt)) { 1644 t = lt; 1645 } else if (size(lt) < size(rt)) { 1646 t = rt; 1647 } else { 1648 for (i = 3; tl[i] != INT; i++) { 1649 if (tl[i] == lt || tl[i] == rt) 1650 break; 1651 } 1652 if ((isutyp(lt) || isutyp(rt)) && 1653 !isutyp(tl[i])) { 1654 i--; 1655 } 1656 t = tl[i]; 1657 } 1658 } 1659 } else { 1660 /* Keep unsigned in traditional C */ 1661 u = isutyp(lt) || isutyp(rt); 1662 for (i = 0; tl[i] != INT; i++) { 1663 if (lt == tl[i] || rt == tl[i]) 1664 break; 1665 } 1666 t = tl[i]; 1667 if (u && isityp(t) && !isutyp(t)) 1668 t = utyp(t); 1669 } 1670 1671 if (t != lt) { 1672 ntp = tduptyp((*lnp)->tn_type); 1673 ntp->t_tspec = t; 1674 *lnp = convert(op, 0, ntp, *lnp); 1675 } 1676 if (t != rt) { 1677 ntp = tduptyp((*rnp)->tn_type); 1678 ntp->t_tspec = t; 1679 *rnp = convert(op, 0, ntp, *rnp); 1680 } 1681 } 1682 1683 /* 1684 * Insert a conversion operator, which converts the type of the node 1685 * to another given type. 1686 * If op is FARG, arg is the number of the argument (used for warnings). 1687 */ 1688 tnode_t * 1689 convert(op_t op, int arg, type_t *tp, tnode_t *tn) 1690 { 1691 tnode_t *ntn; 1692 tspec_t nt, ot, ost = NOTSPEC; 1693 1694 if (tn->tn_lvalue) 1695 LERROR("convert()"); 1696 1697 nt = tp->t_tspec; 1698 if ((ot = tn->tn_type->t_tspec) == PTR) 1699 ost = tn->tn_type->t_subt->t_tspec; 1700 1701 if (!tflag && !sflag && op == FARG) 1702 ptconv(arg, nt, ot, tp, tn); 1703 if (isityp(nt) && isityp(ot)) { 1704 iiconv(op, arg, nt, ot, tp, tn); 1705 } else if (nt == PTR && ((ot == PTR && ost == VOID) || isityp(ot)) && 1706 tn->tn_op == CON && tn->tn_val->v_quad == 0) { 1707 /* 0, 0L and (void *)0 may be assigned to any pointer. */ 1708 } else if (isityp(nt) && ot == PTR) { 1709 piconv(op, nt, tp, tn); 1710 } else if (nt == PTR && ot == PTR) { 1711 ppconv(op, tn, tp); 1712 } 1713 1714 ntn = getnode(); 1715 ntn->tn_op = CVT; 1716 ntn->tn_type = tp; 1717 ntn->tn_cast = op == CVT; 1718 if (tn->tn_op != CON || nt == VOID) { 1719 ntn->tn_left = tn; 1720 } else { 1721 ntn->tn_op = CON; 1722 ntn->tn_val = tgetblk(sizeof (val_t)); 1723 cvtcon(op, arg, ntn->tn_type, ntn->tn_val, tn->tn_val); 1724 } 1725 1726 return (ntn); 1727 } 1728 1729 /* 1730 * Print a warning if a prototype causes a type conversion that is 1731 * different from what would happen to the same argument in the 1732 * absence of a prototype. 1733 * 1734 * Errors/Warnings about illegal type combinations are already printed 1735 * in asgntypok(). 1736 */ 1737 static void 1738 ptconv(int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) 1739 { 1740 tnode_t *ptn; 1741 char buf[64]; 1742 1743 if (!isatyp(nt) || !isatyp(ot)) 1744 return; 1745 1746 /* 1747 * If the type of the formal parameter is char/short, a warning 1748 * would be useless, because functions declared the old style 1749 * can't expect char/short arguments. 1750 */ 1751 if (nt == CHAR || nt == UCHAR || nt == SHORT || nt == USHORT) 1752 return; 1753 1754 /* get default promotion */ 1755 ptn = promote(NOOP, 1, tn); 1756 ot = ptn->tn_type->t_tspec; 1757 1758 /* return if types are the same with and without prototype */ 1759 if (nt == ot || (nt == ENUM && ot == INT)) 1760 return; 1761 1762 if (isftyp(nt) != isftyp(ot) || psize(nt) != psize(ot)) { 1763 /* representation and/or width change */ 1764 if (!isityp(ot) || psize(ot) > psize(INT)) { 1765 /* conversion to '%s' due to prototype, arg #%d */ 1766 warning(259, tyname(buf, sizeof(buf), tp), arg); 1767 } 1768 } else if (hflag) { 1769 /* 1770 * they differ in sign or base type (char, short, int, 1771 * long, long long, float, double, long double) 1772 * 1773 * if they differ only in sign and the argument is a constant 1774 * and the msb of the argument is not set, print no warning 1775 */ 1776 if (ptn->tn_op == CON && isityp(nt) && styp(nt) == styp(ot) && 1777 msb(ptn->tn_val->v_quad, ot, -1) == 0) { 1778 /* ok */ 1779 } else { 1780 /* conversion to '%s' due to prototype, arg #%d */ 1781 warning(259, tyname(buf, sizeof(buf), tp), arg); 1782 } 1783 } 1784 } 1785 1786 /* 1787 * Print warnings for conversions of integer types which my cause 1788 * problems. 1789 */ 1790 /* ARGSUSED */ 1791 static void 1792 iiconv(op_t op, int arg, tspec_t nt, tspec_t ot, type_t *tp, tnode_t *tn) 1793 { 1794 char lbuf[64], rbuf[64], opbuf[16]; 1795 if (tn->tn_op == CON) 1796 return; 1797 1798 if (op == CVT) 1799 return; 1800 1801 if (Pflag && psize(nt) > psize(ot) && isutyp(nt) != isutyp(ot)) { 1802 /* conversion to %s may sign-extend incorrectly (, arg #%d) */ 1803 if (aflag && pflag) { 1804 if (op == FARG) { 1805 warning(297, tyname(lbuf, sizeof(lbuf), tp), 1806 arg); 1807 } else { 1808 warning(131, tyname(lbuf, sizeof(lbuf), tp)); 1809 } 1810 } 1811 } 1812 1813 if (Pflag && psize(nt) > psize(ot)) { 1814 switch (tn->tn_op) { 1815 case PLUS: 1816 case MINUS: 1817 case MULT: 1818 case SHL: 1819 warning(324, 1820 tyname(rbuf, sizeof(rbuf), gettyp(ot)), 1821 tyname(lbuf, sizeof(lbuf), tp), 1822 prtnode(opbuf, sizeof(opbuf), tn)); 1823 break; 1824 default: 1825 break; 1826 } 1827 } 1828 1829 if (psize(nt) < psize(ot) && 1830 (ot == LONG || ot == ULONG || ot == QUAD || ot == UQUAD || 1831 aflag > 1)) { 1832 /* conversion from '%s' may lose accuracy */ 1833 if (aflag) { 1834 if (op == FARG) { 1835 warning(298, 1836 tyname(rbuf, sizeof(rbuf), tn->tn_type), 1837 tyname(lbuf, sizeof(lbuf), tp), 1838 arg); 1839 } else { 1840 warning(132, 1841 tyname(rbuf, sizeof(rbuf), tn->tn_type), 1842 tyname(lbuf, sizeof(lbuf), tp)); 1843 } 1844 } 1845 } 1846 } 1847 1848 /* 1849 * Print warnings for dubious conversions of pointer to integer. 1850 */ 1851 static void 1852 piconv(op_t op, tspec_t nt, type_t *tp, tnode_t *tn) 1853 { 1854 char buf[64]; 1855 1856 if (tn->tn_op == CON) 1857 return; 1858 1859 if (op != CVT) { 1860 /* We got already an error. */ 1861 return; 1862 } 1863 1864 if (psize(nt) < psize(PTR)) { 1865 if (pflag && size(nt) >= size(PTR)) { 1866 /* conv. of pointer to %s may lose bits */ 1867 warning(134, tyname(buf, sizeof(buf), tp)); 1868 } else { 1869 /* conv. of pointer to %s loses bits */ 1870 warning(133, tyname(buf, sizeof(buf), tp)); 1871 } 1872 } 1873 } 1874 1875 /* 1876 * Print warnings for questionable pointer conversions. 1877 */ 1878 static void 1879 ppconv(op_t op, tnode_t *tn, type_t *tp) 1880 { 1881 tspec_t nt, ot; 1882 const char *nts, *ots; 1883 1884 /* 1885 * We got already an error (pointers of different types 1886 * without a cast) or we will not get a warning. 1887 */ 1888 if (op != CVT) 1889 return; 1890 1891 nt = tp->t_subt->t_tspec; 1892 ot = tn->tn_type->t_subt->t_tspec; 1893 1894 if (nt == VOID || ot == VOID) { 1895 if (sflag && (nt == FUNC || ot == FUNC)) { 1896 /* (void *)0 already handled in convert() */ 1897 *(nt == FUNC ? &nts : &ots) = "function pointer"; 1898 *(nt == VOID ? &nts : &ots) = "'void *'"; 1899 /* ANSI C forbids conversion of %s to %s */ 1900 warning(303, ots, nts); 1901 } 1902 return; 1903 } else if (nt == FUNC && ot == FUNC) { 1904 return; 1905 } else if (nt == FUNC || ot == FUNC) { 1906 /* questionable conversion of function pointer */ 1907 warning(229); 1908 return; 1909 } 1910 1911 if (getbound(tp->t_subt) > getbound(tn->tn_type->t_subt)) { 1912 if (hflag) 1913 /* possible pointer alignment problem */ 1914 warning(135); 1915 } 1916 if (((nt == STRUCT || nt == UNION) && 1917 tp->t_subt->t_str != tn->tn_type->t_subt->t_str) || 1918 psize(nt) != psize(ot)) { 1919 if (cflag) { 1920 /* pointer casts may be troublesome */ 1921 warning(247); 1922 } 1923 } 1924 } 1925 1926 /* 1927 * Converts a typed constant in a constant of another type. 1928 * 1929 * op operator which requires conversion 1930 * arg if op is FARG, # of argument 1931 * tp type in which to convert the constant 1932 * nv new constant 1933 * v old constant 1934 */ 1935 void 1936 cvtcon(op_t op, int arg, type_t *tp, val_t *nv, val_t *v) 1937 { 1938 char lbuf[64], rbuf[64]; 1939 tspec_t ot, nt; 1940 ldbl_t max = 0.0, min = 0.0; 1941 int sz, rchk; 1942 int64_t xmask, xmsk1; 1943 int osz, nsz; 1944 1945 ot = v->v_tspec; 1946 nt = nv->v_tspec = tp->t_tspec; 1947 rchk = 0; 1948 1949 if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE) { 1950 switch (nt) { 1951 case BOOL: 1952 max = 1; min = 0; break; 1953 case CHAR: 1954 max = CHAR_MAX; min = CHAR_MIN; break; 1955 case UCHAR: 1956 max = UCHAR_MAX; min = 0; break; 1957 case SCHAR: 1958 max = SCHAR_MAX; min = SCHAR_MIN; break; 1959 case SHORT: 1960 max = SHRT_MAX; min = SHRT_MIN; break; 1961 case USHORT: 1962 max = USHRT_MAX; min = 0; break; 1963 case ENUM: 1964 case INT: 1965 max = INT_MAX; min = INT_MIN; break; 1966 case UINT: 1967 max = (u_int)UINT_MAX; min = 0; break; 1968 case LONG: 1969 max = LONG_MAX; min = LONG_MIN; break; 1970 case ULONG: 1971 max = (u_long)ULONG_MAX; min = 0; break; 1972 case QUAD: 1973 max = QUAD_MAX; min = QUAD_MIN; break; 1974 case UQUAD: 1975 max = (uint64_t)UQUAD_MAX; min = 0; break; 1976 case FLOAT: 1977 case FCOMPLEX: 1978 max = FLT_MAX; min = -FLT_MAX; break; 1979 case DOUBLE: 1980 case DCOMPLEX: 1981 max = DBL_MAX; min = -DBL_MAX; break; 1982 case PTR: 1983 /* Got already an error because of float --> ptr */ 1984 case LDOUBLE: 1985 max = LDBL_MAX; min = -LDBL_MAX; break; 1986 default: 1987 LERROR("cvtcon()"); 1988 } 1989 if (v->v_ldbl > max || v->v_ldbl < min) { 1990 if (nt == LDOUBLE) 1991 LERROR("cvtcon()"); 1992 if (op == FARG) { 1993 /* conv. of %s to %s is out of rng., arg #%d */ 1994 warning(295, tyname(lbuf, sizeof(lbuf), 1995 gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), 1996 arg); 1997 } else { 1998 /* conversion of %s to %s is out of range */ 1999 warning(119, tyname(lbuf, sizeof(lbuf), 2000 gettyp(ot)), 2001 tyname(rbuf, sizeof(rbuf), tp)); 2002 } 2003 v->v_ldbl = v->v_ldbl > 0 ? max : min; 2004 } 2005 if (nt == FLOAT) { 2006 nv->v_ldbl = (float)v->v_ldbl; 2007 } else if (nt == DOUBLE) { 2008 nv->v_ldbl = (double)v->v_ldbl; 2009 } else if (nt == LDOUBLE) { 2010 nv->v_ldbl = v->v_ldbl; 2011 } else { 2012 nv->v_quad = (nt == PTR || isutyp(nt)) ? 2013 (uint64_t)v->v_ldbl : (int64_t)v->v_ldbl; 2014 } 2015 } else { 2016 if (nt == FLOAT) { 2017 nv->v_ldbl = (ot == PTR || isutyp(ot)) ? 2018 (float)(uint64_t)v->v_quad : (float)v->v_quad; 2019 } else if (nt == DOUBLE) { 2020 nv->v_ldbl = (ot == PTR || isutyp(ot)) ? 2021 (double)(uint64_t)v->v_quad : (double)v->v_quad; 2022 } else if (nt == LDOUBLE) { 2023 nv->v_ldbl = (ot == PTR || isutyp(ot)) ? 2024 (ldbl_t)(uint64_t)v->v_quad : (ldbl_t)v->v_quad; 2025 } else { 2026 rchk = 1; /* Check for lost precision. */ 2027 nv->v_quad = v->v_quad; 2028 } 2029 } 2030 2031 if (v->v_ansiu && isftyp(nt)) { 2032 /* ANSI C treats constant as unsigned */ 2033 warning(157); 2034 v->v_ansiu = 0; 2035 } else if (v->v_ansiu && (isityp(nt) && !isutyp(nt) && 2036 psize(nt) > psize(ot))) { 2037 /* ANSI C treats constant as unsigned */ 2038 warning(157); 2039 v->v_ansiu = 0; 2040 } 2041 2042 if (nt != FLOAT && nt != DOUBLE && nt != LDOUBLE) { 2043 sz = tp->t_isfield ? tp->t_flen : size(nt); 2044 nv->v_quad = xsign(nv->v_quad, nt, sz); 2045 } 2046 2047 if (rchk && op != CVT) { 2048 osz = size(ot); 2049 nsz = tp->t_isfield ? tp->t_flen : size(nt); 2050 xmask = qlmasks[nsz] ^ qlmasks[osz]; 2051 xmsk1 = qlmasks[nsz] ^ qlmasks[osz - 1]; 2052 /* 2053 * For bitwise operations we are not interested in the 2054 * value, but in the bits itself. 2055 */ 2056 if (op == ORASS || op == OR || op == XOR) { 2057 /* 2058 * Print a warning if bits which were set are 2059 * lost due to the conversion. 2060 * This can happen with operator ORASS only. 2061 */ 2062 if (nsz < osz && (v->v_quad & xmask) != 0) { 2063 /* constant truncated by conv., op %s */ 2064 warning(306, modtab[op].m_name); 2065 } 2066 } else if (op == ANDASS || op == AND) { 2067 /* 2068 * Print a warning if additional bits are not all 1 2069 * and the most significant bit of the old value is 1, 2070 * or if at least one (but not all) removed bit was 0. 2071 */ 2072 if (nsz > osz && 2073 (nv->v_quad & qbmasks[osz - 1]) != 0 && 2074 (nv->v_quad & xmask) != xmask) { 2075 /* 2076 * extra bits set to 0 in conversion 2077 * of '%s' to '%s', op %s 2078 */ 2079 warning(309, tyname(lbuf, sizeof(lbuf), 2080 gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), 2081 modtab[op].m_name); 2082 } else if (nsz < osz && 2083 (v->v_quad & xmask) != xmask && 2084 (v->v_quad & xmask) != 0) { 2085 /* const. truncated by conv., op %s */ 2086 warning(306, modtab[op].m_name); 2087 } 2088 } else if ((nt != PTR && isutyp(nt)) && 2089 (ot != PTR && !isutyp(ot)) && v->v_quad < 0) { 2090 if (op == ASSIGN) { 2091 /* assignment of negative constant to ... */ 2092 warning(164); 2093 } else if (op == INIT) { 2094 /* initialisation of unsigned with neg. ... */ 2095 warning(221); 2096 } else if (op == FARG) { 2097 /* conversion of neg. const. to ..., arg #%d */ 2098 warning(296, arg); 2099 } else if (modtab[op].m_comp) { 2100 /* we get this warning already in chkcomp() */ 2101 } else { 2102 /* conversion of negative constant to ... */ 2103 warning(222); 2104 } 2105 } else if (nv->v_quad != v->v_quad && nsz <= osz && 2106 (v->v_quad & xmask) != 0 && 2107 (isutyp(ot) || (v->v_quad & xmsk1) != xmsk1)) { 2108 /* 2109 * Loss of significant bit(s). All truncated bits 2110 * of unsigned types or all truncated bits plus the 2111 * msb of the target for signed types are considered 2112 * to be significant bits. Loss of significant bits 2113 * means that at least on of the bits was set in an 2114 * unsigned type or that at least one, but not all of 2115 * the bits was set in an signed type. 2116 * Loss of significant bits means that it is not 2117 * possible, also not with necessary casts, to convert 2118 * back to the original type. A example for a 2119 * necessary cast is: 2120 * char c; int i; c = 128; 2121 * i = c; ** yields -128 ** 2122 * i = (unsigned char)c; ** yields 128 ** 2123 */ 2124 if (op == ASSIGN && tp->t_isfield) { 2125 /* precision lost in bit-field assignment */ 2126 warning(166); 2127 } else if (op == ASSIGN) { 2128 /* constant truncated by assignment */ 2129 warning(165); 2130 } else if (op == INIT && tp->t_isfield) { 2131 /* bit-field initializer does not fit */ 2132 warning(180); 2133 } else if (op == INIT) { 2134 /* initializer does not fit */ 2135 warning(178); 2136 } else if (op == CASE) { 2137 /* case label affected by conversion */ 2138 warning(196); 2139 } else if (op == FARG) { 2140 /* conv. of %s to %s is out of rng., arg #%d */ 2141 warning(295, tyname(lbuf, sizeof(lbuf), 2142 gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), 2143 arg); 2144 } else { 2145 /* conversion of %s to %s is out of range */ 2146 warning(119, tyname(lbuf, sizeof(lbuf), 2147 gettyp(ot)), 2148 tyname(rbuf, sizeof(rbuf), tp)); 2149 } 2150 } else if (nv->v_quad != v->v_quad) { 2151 if (op == ASSIGN && tp->t_isfield) { 2152 /* precision lost in bit-field assignment */ 2153 warning(166); 2154 } else if (op == INIT && tp->t_isfield) { 2155 /* bit-field initializer out of range */ 2156 warning(11); 2157 } else if (op == CASE) { 2158 /* case label affected by conversion */ 2159 warning(196); 2160 } else if (op == FARG) { 2161 /* conv. of %s to %s is out of rng., arg #%d */ 2162 warning(295, tyname(lbuf, sizeof(lbuf), 2163 gettyp(ot)), tyname(rbuf, sizeof(rbuf), tp), 2164 arg); 2165 } else { 2166 /* conversion of %s to %s is out of range */ 2167 warning(119, tyname(lbuf, sizeof(lbuf), 2168 gettyp(ot)), 2169 tyname(rbuf, sizeof(rbuf), tp)); 2170 } 2171 } 2172 } 2173 } 2174 2175 /* 2176 * Called if incompatible types were detected. 2177 * Prints a appropriate warning. 2178 */ 2179 static void 2180 incompat(op_t op, tspec_t lt, tspec_t rt) 2181 { 2182 mod_t *mp; 2183 int e = 0; 2184 2185 mp = &modtab[op]; 2186 2187 if (lt == VOID || (mp->m_binary && rt == VOID)) { 2188 /* void type illegal in expression */ 2189 e = 109; 2190 } else if (op == ASSIGN) { 2191 if ((lt == STRUCT || lt == UNION) && 2192 (rt == STRUCT || rt == UNION)) { 2193 /* assignment of different structures */ 2194 e = 240; 2195 } else { 2196 /* assignment type mismatch */ 2197 e = 171; 2198 } 2199 } else if (mp->m_binary) { 2200 /* operands of %s have incompatible types */ 2201 e = 107; 2202 } else { 2203 /* operand of %s has incompatible type */ 2204 e = 108; 2205 } 2206 switch (e) { 2207 case 0: 2208 return; 2209 case 109: 2210 error(e); 2211 return; 2212 case 108: 2213 case 107: 2214 error(e, mp->m_name, basictyname(lt), basictyname(rt)); 2215 return; 2216 default: 2217 error(e, basictyname(lt), basictyname(rt)); 2218 return; 2219 } 2220 } 2221 2222 /* 2223 * Called if incompatible pointer types are detected. 2224 * Print an appropriate warning. 2225 */ 2226 static void 2227 illptrc(mod_t *mp, type_t *ltp, type_t *rtp) 2228 { 2229 tspec_t lt, rt; 2230 2231 if (ltp->t_tspec != PTR || rtp->t_tspec != PTR) 2232 LERROR("illptrc()"); 2233 2234 lt = ltp->t_subt->t_tspec; 2235 rt = rtp->t_subt->t_tspec; 2236 2237 if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION)) { 2238 if (mp == NULL) { 2239 /* illegal structure pointer combination */ 2240 warning(244); 2241 } else { 2242 /* illegal structure pointer combination, op %s */ 2243 warning(245, mp->m_name); 2244 } 2245 } else { 2246 if (mp == NULL) { 2247 /* illegal pointer combination */ 2248 warning(184); 2249 } else { 2250 /* illegal pointer combination, op %s */ 2251 warning(124, mp->m_name); 2252 } 2253 } 2254 } 2255 2256 /* 2257 * Make sure type (*tpp)->t_subt has at least the qualifiers 2258 * of tp1->t_subt and tp2->t_subt. 2259 */ 2260 static void 2261 mrgqual(type_t **tpp, type_t *tp1, type_t *tp2) 2262 { 2263 2264 if ((*tpp)->t_tspec != PTR || 2265 tp1->t_tspec != PTR || tp2->t_tspec != PTR) { 2266 LERROR("mrgqual()"); 2267 } 2268 2269 if ((*tpp)->t_subt->t_const == 2270 (tp1->t_subt->t_const | tp2->t_subt->t_const) && 2271 (*tpp)->t_subt->t_volatile == 2272 (tp1->t_subt->t_volatile | tp2->t_subt->t_volatile)) { 2273 return; 2274 } 2275 2276 *tpp = tduptyp(*tpp); 2277 (*tpp)->t_subt = tduptyp((*tpp)->t_subt); 2278 (*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 } 2283 2284 /* 2285 * Returns 1 if the given structure or union has a constant member 2286 * (maybe recursively). 2287 */ 2288 static int 2289 conmemb(type_t *tp) 2290 { 2291 sym_t *m; 2292 tspec_t t; 2293 2294 if ((t = tp->t_tspec) != STRUCT && t != UNION) 2295 LERROR("conmemb()"); 2296 for (m = tp->t_str->memb; m != NULL; m = m->s_nxt) { 2297 tp = m->s_type; 2298 if (tp->t_const) 2299 return (1); 2300 if ((t = tp->t_tspec) == STRUCT || t == UNION) { 2301 if (conmemb(m->s_type)) 2302 return (1); 2303 } 2304 } 2305 return (0); 2306 } 2307 2308 /* 2309 * Create a new node for one of the operators POINT and ARROW. 2310 */ 2311 static tnode_t * 2312 bldstr(op_t op, tnode_t *ln, tnode_t *rn) 2313 { 2314 tnode_t *ntn, *ctn; 2315 int nolval; 2316 2317 if (rn->tn_op != NAME) 2318 LERROR("bldstr()"); 2319 if (rn->tn_sym->s_value.v_tspec != INT) 2320 LERROR("bldstr()"); 2321 if (rn->tn_sym->s_scl != MOS && rn->tn_sym->s_scl != MOU) 2322 LERROR("bldstr()"); 2323 2324 /* 2325 * Remember if the left operand is an lvalue (structure members 2326 * are lvalues if and only if the structure itself is an lvalue). 2327 */ 2328 nolval = op == POINT && !ln->tn_lvalue; 2329 2330 if (op == POINT) { 2331 ln = bldamper(ln, 1); 2332 } else if (ln->tn_type->t_tspec != PTR) { 2333 if (!tflag || !isityp(ln->tn_type->t_tspec)) 2334 LERROR("bldstr()"); 2335 ln = convert(NOOP, 0, tincref(gettyp(VOID), PTR), ln); 2336 } 2337 2338 #if PTRDIFF_IS_LONG 2339 ctn = getinode(LONG, rn->tn_sym->s_value.v_quad / CHAR_BIT); 2340 #else 2341 ctn = getinode(INT, rn->tn_sym->s_value.v_quad / CHAR_BIT); 2342 #endif 2343 2344 ntn = mktnode(PLUS, tincref(rn->tn_type, PTR), ln, ctn); 2345 if (ln->tn_op == CON) 2346 ntn = fold(ntn); 2347 2348 if (rn->tn_type->t_isfield) { 2349 ntn = mktnode(FSEL, ntn->tn_type->t_subt, ntn, NULL); 2350 } else { 2351 ntn = mktnode(STAR, ntn->tn_type->t_subt, ntn, NULL); 2352 } 2353 2354 if (nolval) 2355 ntn->tn_lvalue = 0; 2356 2357 return (ntn); 2358 } 2359 2360 /* 2361 * Create a node for INCAFT, INCBEF, DECAFT and DECBEF. 2362 */ 2363 static tnode_t * 2364 bldincdec(op_t op, tnode_t *ln) 2365 { 2366 tnode_t *cn, *ntn; 2367 2368 if (ln == NULL) 2369 LERROR("bldincdec()"); 2370 2371 if (ln->tn_type->t_tspec == PTR) { 2372 cn = plength(ln->tn_type); 2373 } else { 2374 cn = getinode(INT, (int64_t)1); 2375 } 2376 ntn = mktnode(op, ln->tn_type, ln, cn); 2377 2378 return (ntn); 2379 } 2380 2381 /* 2382 * Create a node for REAL, IMAG 2383 */ 2384 static tnode_t * 2385 bldri(op_t op, tnode_t *ln) 2386 { 2387 tnode_t *cn, *ntn; 2388 char buf[64]; 2389 2390 if (ln == NULL) 2391 LERROR("bldincdec()"); 2392 2393 switch (ln->tn_type->t_tspec) { 2394 case DCOMPLEX: 2395 cn = getinode(DOUBLE, (int64_t)1); 2396 break; 2397 case FCOMPLEX: 2398 cn = getinode(FLOAT, (int64_t)1); 2399 break; 2400 default: 2401 error(276, op == REAL ? "real" : "imag", 2402 tyname(buf, sizeof(buf), ln->tn_type)); 2403 return NULL; 2404 } 2405 ntn = mktnode(op, cn->tn_type, ln, cn); 2406 2407 return (ntn); 2408 } 2409 /* 2410 * Create a tree node for the & operator 2411 */ 2412 static tnode_t * 2413 bldamper(tnode_t *tn, int noign) 2414 { 2415 tnode_t *ntn; 2416 tspec_t t; 2417 2418 if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) { 2419 /* & before array or function: ignored */ 2420 if (tflag) 2421 warning(127); 2422 return (tn); 2423 } 2424 2425 /* eliminate &* */ 2426 if (tn->tn_op == STAR && 2427 tn->tn_left->tn_type->t_tspec == PTR && 2428 tn->tn_left->tn_type->t_subt == tn->tn_type) { 2429 return (tn->tn_left); 2430 } 2431 2432 ntn = mktnode(AMPER, tincref(tn->tn_type, PTR), tn, NULL); 2433 2434 return (ntn); 2435 } 2436 2437 /* 2438 * Create a node for operators PLUS and MINUS. 2439 */ 2440 static tnode_t * 2441 bldplmi(op_t op, tnode_t *ln, tnode_t *rn) 2442 { 2443 tnode_t *ntn, *ctn; 2444 type_t *tp; 2445 2446 /* If pointer and integer, then pointer to the lhs. */ 2447 if (rn->tn_type->t_tspec == PTR && isityp(ln->tn_type->t_tspec)) { 2448 ntn = ln; 2449 ln = rn; 2450 rn = ntn; 2451 } 2452 2453 if (ln->tn_type->t_tspec == PTR && rn->tn_type->t_tspec != PTR) { 2454 2455 if (!isityp(rn->tn_type->t_tspec)) 2456 LERROR("bldplmi()"); 2457 2458 ctn = plength(ln->tn_type); 2459 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) 2460 rn = convert(NOOP, 0, ctn->tn_type, rn); 2461 rn = mktnode(MULT, rn->tn_type, rn, ctn); 2462 if (rn->tn_left->tn_op == CON) 2463 rn = fold(rn); 2464 ntn = mktnode(op, ln->tn_type, ln, rn); 2465 2466 } else if (rn->tn_type->t_tspec == PTR) { 2467 2468 if (ln->tn_type->t_tspec != PTR || op != MINUS) 2469 LERROR("bldplmi()"); 2470 #if PTRDIFF_IS_LONG 2471 tp = gettyp(LONG); 2472 #else 2473 tp = gettyp(INT); 2474 #endif 2475 ntn = mktnode(op, tp, ln, rn); 2476 if (ln->tn_op == CON && rn->tn_op == CON) 2477 ntn = fold(ntn); 2478 ctn = plength(ln->tn_type); 2479 balance(NOOP, &ntn, &ctn); 2480 ntn = mktnode(DIV, tp, ntn, ctn); 2481 2482 } else { 2483 2484 ntn = mktnode(op, ln->tn_type, ln, rn); 2485 2486 } 2487 return (ntn); 2488 } 2489 2490 /* 2491 * Create a node for operators SHL and SHR. 2492 */ 2493 static tnode_t * 2494 bldshft(op_t op, tnode_t *ln, tnode_t *rn) 2495 { 2496 tspec_t t; 2497 tnode_t *ntn; 2498 2499 if ((t = rn->tn_type->t_tspec) != INT && t != UINT) 2500 rn = convert(CVT, 0, gettyp(INT), rn); 2501 ntn = mktnode(op, ln->tn_type, ln, rn); 2502 return (ntn); 2503 } 2504 2505 /* 2506 * Create a node for COLON. 2507 */ 2508 static tnode_t * 2509 bldcol(tnode_t *ln, tnode_t *rn) 2510 { 2511 tspec_t lt, rt, pdt; 2512 type_t *rtp; 2513 tnode_t *ntn; 2514 2515 lt = ln->tn_type->t_tspec; 2516 rt = rn->tn_type->t_tspec; 2517 #if PTRDIFF_IS_LONG 2518 pdt = LONG; 2519 #else 2520 pdt = INT; 2521 #endif 2522 2523 /* 2524 * Arithmetic types are balanced, all other type combinations 2525 * still need to be handled. 2526 */ 2527 if (isatyp(lt) && isatyp(rt)) { 2528 rtp = ln->tn_type; 2529 } else if (lt == VOID || rt == VOID) { 2530 rtp = gettyp(VOID); 2531 } else if (lt == STRUCT || lt == UNION) { 2532 /* Both types must be identical. */ 2533 if (rt != STRUCT && rt != UNION) 2534 LERROR("bldcol()"); 2535 if (ln->tn_type->t_str != rn->tn_type->t_str) 2536 LERROR("bldcol()"); 2537 if (incompl(ln->tn_type)) { 2538 /* unknown operand size, op %s */ 2539 error(138, modtab[COLON].m_name); 2540 return (NULL); 2541 } 2542 rtp = ln->tn_type; 2543 } else if (lt == PTR && isityp(rt)) { 2544 if (rt != pdt) { 2545 rn = convert(NOOP, 0, gettyp(pdt), rn); 2546 rt = pdt; 2547 } 2548 rtp = ln->tn_type; 2549 } else if (rt == PTR && isityp(lt)) { 2550 if (lt != pdt) { 2551 ln = convert(NOOP, 0, gettyp(pdt), ln); 2552 lt = pdt; 2553 } 2554 rtp = rn->tn_type; 2555 } else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID) { 2556 if (rt != PTR) 2557 LERROR("bldcol()"); 2558 rtp = ln->tn_type; 2559 mrgqual(&rtp, ln->tn_type, rn->tn_type); 2560 } else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID) { 2561 if (lt != PTR) 2562 LERROR("bldcol()"); 2563 rtp = rn->tn_type; 2564 mrgqual(&rtp, ln->tn_type, rn->tn_type); 2565 } else { 2566 if (lt != PTR || rt != PTR) 2567 LERROR("bldcol()"); 2568 /* 2569 * XXX For now we simply take the left type. This is 2570 * probably wrong, if one type contains a functionprototype 2571 * and the other one, at the same place, only an old style 2572 * declaration. 2573 */ 2574 rtp = ln->tn_type; 2575 mrgqual(&rtp, ln->tn_type, rn->tn_type); 2576 } 2577 2578 ntn = mktnode(COLON, rtp, ln, rn); 2579 2580 return (ntn); 2581 } 2582 2583 /* 2584 * Create a node for an assignment operator (both = and op= ). 2585 */ 2586 static tnode_t * 2587 bldasgn(op_t op, tnode_t *ln, tnode_t *rn) 2588 { 2589 tspec_t lt, rt; 2590 tnode_t *ntn, *ctn; 2591 2592 if (ln == NULL || rn == NULL) 2593 LERROR("bldasgn()"); 2594 2595 lt = ln->tn_type->t_tspec; 2596 rt = rn->tn_type->t_tspec; 2597 2598 if ((op == ADDASS || op == SUBASS) && lt == PTR) { 2599 if (!isityp(rt)) 2600 LERROR("bldasgn()"); 2601 ctn = plength(ln->tn_type); 2602 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec) 2603 rn = convert(NOOP, 0, ctn->tn_type, rn); 2604 rn = mktnode(MULT, rn->tn_type, rn, ctn); 2605 if (rn->tn_left->tn_op == CON) 2606 rn = fold(rn); 2607 } 2608 2609 if ((op == ASSIGN || op == RETURN) && (lt == STRUCT || rt == STRUCT)) { 2610 if (rt != lt || ln->tn_type->t_str != rn->tn_type->t_str) 2611 LERROR("bldasgn()"); 2612 if (incompl(ln->tn_type)) { 2613 if (op == RETURN) { 2614 /* cannot return incomplete type */ 2615 error(212); 2616 } else { 2617 /* unknown operand size, op %s */ 2618 error(138, modtab[op].m_name); 2619 } 2620 return (NULL); 2621 } 2622 } 2623 2624 if (op == SHLASS) { 2625 if (psize(lt) < psize(rt)) { 2626 if (hflag) 2627 /* semantics of %s change in ANSI C; use ... */ 2628 warning(118, "<<="); 2629 } 2630 } else if (op != SHRASS) { 2631 if (op == ASSIGN || lt != PTR) { 2632 if (lt != rt || 2633 (ln->tn_type->t_isfield && rn->tn_op == CON)) { 2634 rn = convert(op, 0, ln->tn_type, rn); 2635 rt = lt; 2636 } 2637 } 2638 } 2639 2640 ntn = mktnode(op, ln->tn_type, ln, rn); 2641 2642 return (ntn); 2643 } 2644 2645 /* 2646 * Get length of type tp->t_subt. 2647 */ 2648 static tnode_t * 2649 plength(type_t *tp) 2650 { 2651 int elem, elsz; 2652 tspec_t st; 2653 2654 if (tp->t_tspec != PTR) 2655 LERROR("plength()"); 2656 tp = tp->t_subt; 2657 2658 elem = 1; 2659 elsz = 0; 2660 2661 while (tp->t_tspec == ARRAY) { 2662 elem *= tp->t_dim; 2663 tp = tp->t_subt; 2664 } 2665 2666 switch (tp->t_tspec) { 2667 case FUNC: 2668 /* pointer to function is not allowed here */ 2669 error(110); 2670 break; 2671 case VOID: 2672 /* cannot do pointer arithmetic on operand of ... */ 2673 (void)gnuism(136); 2674 break; 2675 case STRUCT: 2676 case UNION: 2677 if ((elsz = tp->t_str->size) == 0) 2678 /* cannot do pointer arithmetic on operand of ... */ 2679 error(136); 2680 break; 2681 case ENUM: 2682 if (incompl(tp)) { 2683 /* cannot do pointer arithmetic on operand of ... */ 2684 warning(136); 2685 } 2686 /* FALLTHROUGH */ 2687 default: 2688 if ((elsz = size(tp->t_tspec)) == 0) { 2689 /* cannot do pointer arithmetic on operand of ... */ 2690 error(136); 2691 } else if (elsz == -1) { 2692 LERROR("plength()"); 2693 } 2694 break; 2695 } 2696 2697 if (elem == 0 && elsz != 0) { 2698 /* cannot do pointer arithmetic on operand of ... */ 2699 error(136); 2700 } 2701 2702 if (elsz == 0) 2703 elsz = CHAR_BIT; 2704 2705 #if PTRDIFF_IS_LONG 2706 st = LONG; 2707 #else 2708 st = INT; 2709 #endif 2710 2711 return (getinode(st, (int64_t)(elem * elsz / CHAR_BIT))); 2712 } 2713 2714 /* 2715 * XXX 2716 * Note: There appear to be a number of bugs in detecting overflow in 2717 * this function. An audit and a set of proper regression tests are needed. 2718 * --Perry Metzger, Nov. 16, 2001 2719 */ 2720 /* 2721 * Do only as much as necessary to compute constant expressions. 2722 * Called only if the operator allows folding and (both) operands 2723 * are constants. 2724 */ 2725 static tnode_t * 2726 fold(tnode_t *tn) 2727 { 2728 val_t *v; 2729 tspec_t t; 2730 int utyp, ovfl; 2731 int64_t sl, sr = 0, q = 0, mask; 2732 uint64_t ul, ur = 0; 2733 tnode_t *cn; 2734 2735 v = xcalloc(1, sizeof (val_t)); 2736 v->v_tspec = t = tn->tn_type->t_tspec; 2737 2738 utyp = t == PTR || isutyp(t); 2739 ul = sl = tn->tn_left->tn_val->v_quad; 2740 if (modtab[tn->tn_op].m_binary) 2741 ur = sr = tn->tn_right->tn_val->v_quad; 2742 2743 mask = qlmasks[size(t)]; 2744 ovfl = 0; 2745 2746 switch (tn->tn_op) { 2747 case UPLUS: 2748 q = sl; 2749 break; 2750 case UMINUS: 2751 q = -sl; 2752 if (msb(q, t, -1) == msb(sl, t, -1)) 2753 ovfl = 1; 2754 break; 2755 case COMPL: 2756 q = ~sl; 2757 break; 2758 case MULT: 2759 if (utyp) { 2760 q = ul * ur; 2761 if (q != (q & mask)) 2762 ovfl = 1; 2763 else if ((ul != 0) && ((q / ul) != ur)) 2764 ovfl = 1; 2765 } else { 2766 q = sl * sr; 2767 if (msb(q, t, -1) != (msb(sl, t, -1) ^ msb(sr, t, -1))) 2768 ovfl = 1; 2769 } 2770 break; 2771 case DIV: 2772 if (sr == 0) { 2773 /* division by 0 */ 2774 error(139); 2775 q = utyp ? UQUAD_MAX : QUAD_MAX; 2776 } else { 2777 q = utyp ? ul / ur : sl / sr; 2778 } 2779 break; 2780 case MOD: 2781 if (sr == 0) { 2782 /* modulus by 0 */ 2783 error(140); 2784 q = 0; 2785 } else { 2786 q = utyp ? ul % ur : sl % sr; 2787 } 2788 break; 2789 case PLUS: 2790 q = utyp ? ul + ur : sl + sr; 2791 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) != 0) { 2792 if (msb(q, t, -1) == 0) 2793 ovfl = 1; 2794 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) == 0) { 2795 if (msb(q, t, -1) != 0) 2796 ovfl = 1; 2797 } 2798 break; 2799 case MINUS: 2800 q = utyp ? ul - ur : sl - sr; 2801 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) == 0) { 2802 if (msb(q, t, -1) == 0) 2803 ovfl = 1; 2804 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) != 0) { 2805 if (msb(q, t, -1) != 0) 2806 ovfl = 1; 2807 } 2808 break; 2809 case SHL: 2810 q = utyp ? ul << sr : sl << sr; 2811 break; 2812 case SHR: 2813 /* 2814 * The sign must be explicitly extended because 2815 * shifts of signed values are implementation dependent. 2816 */ 2817 q = ul >> sr; 2818 q = xsign(q, t, size(t) - (int)sr); 2819 break; 2820 case LT: 2821 q = utyp ? ul < ur : sl < sr; 2822 break; 2823 case LE: 2824 q = utyp ? ul <= ur : sl <= sr; 2825 break; 2826 case GE: 2827 q = utyp ? ul >= ur : sl >= sr; 2828 break; 2829 case GT: 2830 q = utyp ? ul > ur : sl > sr; 2831 break; 2832 case EQ: 2833 q = utyp ? ul == ur : sl == sr; 2834 break; 2835 case NE: 2836 q = utyp ? ul != ur : sl != sr; 2837 break; 2838 case AND: 2839 q = utyp ? ul & ur : sl & sr; 2840 break; 2841 case XOR: 2842 q = utyp ? ul ^ ur : sl ^ sr; 2843 break; 2844 case OR: 2845 q = utyp ? ul | ur : sl | sr; 2846 break; 2847 default: 2848 LERROR("fold()"); 2849 } 2850 2851 /* XXX does not work for quads. */ 2852 if (ovfl || ((q | mask) != ~(uint64_t)0 && (q & ~mask) != 0)) { 2853 if (hflag) 2854 /* integer overflow detected, op %s */ 2855 warning(141, modtab[tn->tn_op].m_name); 2856 } 2857 2858 v->v_quad = xsign(q, t, -1); 2859 2860 cn = getcnode(tn->tn_type, v); 2861 2862 return (cn); 2863 } 2864 2865 /* 2866 * Same for operators whose operands are compared with 0 (test context). 2867 */ 2868 static tnode_t * 2869 foldtst(tnode_t *tn) 2870 { 2871 int l, r = 0; 2872 val_t *v; 2873 2874 v = xcalloc(1, sizeof (val_t)); 2875 v->v_tspec = tn->tn_type->t_tspec; 2876 if (tn->tn_type->t_tspec != INT) 2877 LERROR("foldtst()"); 2878 2879 if (isftyp(tn->tn_left->tn_type->t_tspec)) { 2880 l = tn->tn_left->tn_val->v_ldbl != 0.0; 2881 } else { 2882 l = tn->tn_left->tn_val->v_quad != 0; 2883 } 2884 2885 if (modtab[tn->tn_op].m_binary) { 2886 if (isftyp(tn->tn_right->tn_type->t_tspec)) { 2887 r = tn->tn_right->tn_val->v_ldbl != 0.0; 2888 } else { 2889 r = tn->tn_right->tn_val->v_quad != 0; 2890 } 2891 } 2892 2893 switch (tn->tn_op) { 2894 case NOT: 2895 if (hflag) 2896 /* constant argument to NOT */ 2897 warning(239); 2898 v->v_quad = !l; 2899 break; 2900 case LOGAND: 2901 v->v_quad = l && r; 2902 break; 2903 case LOGOR: 2904 v->v_quad = l || r; 2905 break; 2906 default: 2907 LERROR("foldtst()"); 2908 } 2909 2910 return (getcnode(tn->tn_type, v)); 2911 } 2912 2913 /* 2914 * Same for operands with floating point type. 2915 */ 2916 static tnode_t * 2917 foldflt(tnode_t *tn) 2918 { 2919 val_t *v; 2920 tspec_t t; 2921 ldbl_t l, r = 0; 2922 2923 fpe = 0; 2924 v = xcalloc(1, sizeof (val_t)); 2925 v->v_tspec = t = tn->tn_type->t_tspec; 2926 2927 if (!isftyp(t)) 2928 LERROR("foldflt()"); 2929 2930 if (t != tn->tn_left->tn_type->t_tspec) 2931 LERROR("foldflt()"); 2932 if (modtab[tn->tn_op].m_binary && t != tn->tn_right->tn_type->t_tspec) 2933 LERROR("foldflt()"); 2934 2935 l = tn->tn_left->tn_val->v_ldbl; 2936 if (modtab[tn->tn_op].m_binary) 2937 r = tn->tn_right->tn_val->v_ldbl; 2938 2939 switch (tn->tn_op) { 2940 case UPLUS: 2941 v->v_ldbl = l; 2942 break; 2943 case UMINUS: 2944 v->v_ldbl = -l; 2945 break; 2946 case MULT: 2947 v->v_ldbl = l * r; 2948 break; 2949 case DIV: 2950 if (r == 0.0) { 2951 /* division by 0 */ 2952 error(139); 2953 if (t == FLOAT) { 2954 v->v_ldbl = l < 0 ? -FLT_MAX : FLT_MAX; 2955 } else if (t == DOUBLE) { 2956 v->v_ldbl = l < 0 ? -DBL_MAX : DBL_MAX; 2957 } else { 2958 v->v_ldbl = l < 0 ? -LDBL_MAX : LDBL_MAX; 2959 } 2960 } else { 2961 v->v_ldbl = l / r; 2962 } 2963 break; 2964 case PLUS: 2965 v->v_ldbl = l + r; 2966 break; 2967 case MINUS: 2968 v->v_ldbl = l - r; 2969 break; 2970 case LT: 2971 v->v_quad = l < r; 2972 break; 2973 case LE: 2974 v->v_quad = l <= r; 2975 break; 2976 case GE: 2977 v->v_quad = l >= r; 2978 break; 2979 case GT: 2980 v->v_quad = l > r; 2981 break; 2982 case EQ: 2983 v->v_quad = l == r; 2984 break; 2985 case NE: 2986 v->v_quad = l != r; 2987 break; 2988 default: 2989 LERROR("foldflt()"); 2990 } 2991 2992 if (!fpe && isnan((double)v->v_ldbl)) 2993 LERROR("foldflt()"); 2994 if (fpe || !finite((double)v->v_ldbl) || 2995 (t == FLOAT && 2996 (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) || 2997 (t == DOUBLE && 2998 (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) { 2999 /* floating point overflow detected, op %s */ 3000 warning(142, modtab[tn->tn_op].m_name); 3001 if (t == FLOAT) { 3002 v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX; 3003 } else if (t == DOUBLE) { 3004 v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX; 3005 } else { 3006 v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX; 3007 } 3008 fpe = 0; 3009 } 3010 3011 return (getcnode(tn->tn_type, v)); 3012 } 3013 3014 /* 3015 * Create a constant node for sizeof. 3016 */ 3017 tnode_t * 3018 bldszof(type_t *tp) 3019 { 3020 int elem, elsz; 3021 tspec_t st; 3022 3023 elem = 1; 3024 while (tp->t_tspec == ARRAY) { 3025 elem *= tp->t_dim; 3026 tp = tp->t_subt; 3027 } 3028 if (elem == 0) { 3029 /* cannot take size of incomplete type */ 3030 error(143); 3031 elem = 1; 3032 } 3033 switch (tp->t_tspec) { 3034 case FUNC: 3035 /* cannot take size of function */ 3036 error(144); 3037 elsz = 1; 3038 break; 3039 case STRUCT: 3040 case UNION: 3041 if (incompl(tp)) { 3042 /* cannot take size of incomplete type */ 3043 error(143); 3044 elsz = 1; 3045 } else { 3046 elsz = tp->t_str->size; 3047 } 3048 break; 3049 case ENUM: 3050 if (incompl(tp)) { 3051 /* cannot take size of incomplete type */ 3052 warning(143); 3053 } 3054 /* FALLTHROUGH */ 3055 default: 3056 if (tp->t_isfield) { 3057 /* cannot take size of bit-field */ 3058 error(145); 3059 } 3060 if (tp->t_tspec == VOID) { 3061 /* cannot take size of void */ 3062 error(146); 3063 elsz = 1; 3064 } else { 3065 elsz = size(tp->t_tspec); 3066 if (elsz <= 0) 3067 LERROR("bldszof()"); 3068 } 3069 break; 3070 } 3071 3072 #if SIZEOF_IS_ULONG 3073 st = ULONG; 3074 #else 3075 st = UINT; 3076 #endif 3077 3078 return (getinode(st, (int64_t)(elem * elsz / CHAR_BIT))); 3079 } 3080 3081 /* 3082 * Type casts. 3083 */ 3084 tnode_t * 3085 cast(tnode_t *tn, type_t *tp) 3086 { 3087 tspec_t nt, ot; 3088 3089 if (tn == NULL) 3090 return (NULL); 3091 3092 tn = cconv(tn); 3093 3094 nt = tp->t_tspec; 3095 ot = tn->tn_type->t_tspec; 3096 3097 if (nt == VOID) { 3098 /* 3099 * XXX ANSI C requires scalar types or void (Plauger&Brodie). 3100 * But this seams really questionable. 3101 */ 3102 } else if (nt == STRUCT || nt == UNION || nt == ARRAY || nt == FUNC) { 3103 /* invalid cast expression */ 3104 error(147); 3105 return (NULL); 3106 } else if (ot == STRUCT || ot == UNION) { 3107 /* invalid cast expression */ 3108 error(147); 3109 return (NULL); 3110 } else if (ot == VOID) { 3111 /* improper cast of void expression */ 3112 error(148); 3113 return (NULL); 3114 } else if (isityp(nt) && issclt(ot)) { 3115 /* ok */ 3116 } else if (isftyp(nt) && isatyp(ot)) { 3117 /* ok */ 3118 } else if (nt == PTR && isityp(ot)) { 3119 /* ok */ 3120 } else if (nt == PTR && ot == PTR) { 3121 if (!tp->t_subt->t_const && tn->tn_type->t_subt->t_const) { 3122 if (hflag) 3123 /* cast discards 'const' from ... */ 3124 warning(275); 3125 } 3126 } else { 3127 /* invalid cast expression */ 3128 error(147); 3129 return (NULL); 3130 } 3131 3132 tn = convert(CVT, 0, tp, tn); 3133 tn->tn_cast = 1; 3134 3135 return (tn); 3136 } 3137 3138 /* 3139 * Create the node for a function argument. 3140 * All necessary conversions and type checks are done in funccall(), because 3141 * in funcarg() we have no information about expected argument types. 3142 */ 3143 tnode_t * 3144 funcarg(tnode_t *args, tnode_t *arg) 3145 { 3146 tnode_t *ntn; 3147 3148 /* 3149 * If there was a serious error in the expression for the argument, 3150 * create a dummy argument so the positions of the remaining arguments 3151 * will not change. 3152 */ 3153 if (arg == NULL) 3154 arg = getinode(INT, (int64_t)0); 3155 3156 ntn = mktnode(PUSH, arg->tn_type, arg, args); 3157 3158 return (ntn); 3159 } 3160 3161 /* 3162 * Create the node for a function call. Also check types of 3163 * function arguments and insert conversions, if necessary. 3164 */ 3165 tnode_t * 3166 funccall(tnode_t *func, tnode_t *args) 3167 { 3168 tnode_t *ntn; 3169 op_t fcop; 3170 3171 if (func == NULL) 3172 return (NULL); 3173 3174 if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) { 3175 fcop = CALL; 3176 } else { 3177 fcop = ICALL; 3178 } 3179 3180 /* 3181 * after cconv() func will always be a pointer to a function 3182 * if it is a valid function designator. 3183 */ 3184 func = cconv(func); 3185 3186 if (func->tn_type->t_tspec != PTR || 3187 func->tn_type->t_subt->t_tspec != FUNC) { 3188 /* illegal function */ 3189 error(149); 3190 return (NULL); 3191 } 3192 3193 args = chkfarg(func->tn_type->t_subt, args); 3194 3195 ntn = mktnode(fcop, func->tn_type->t_subt->t_subt, func, args); 3196 3197 return (ntn); 3198 } 3199 3200 /* 3201 * Check types of all function arguments and insert conversions, 3202 * if necessary. 3203 */ 3204 static tnode_t * 3205 chkfarg(type_t *ftp, tnode_t *args) 3206 { 3207 tnode_t *arg; 3208 sym_t *asym; 3209 tspec_t at; 3210 int narg, npar, n, i; 3211 3212 /* get # of args in the prototype */ 3213 npar = 0; 3214 for (asym = ftp->t_args; asym != NULL; asym = asym->s_nxt) 3215 npar++; 3216 3217 /* get # of args in function call */ 3218 narg = 0; 3219 for (arg = args; arg != NULL; arg = arg->tn_right) 3220 narg++; 3221 3222 asym = ftp->t_args; 3223 if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) { 3224 /* argument mismatch: %d arg%s passed, %d expected */ 3225 error(150, narg, narg > 1 ? "s" : "", npar); 3226 asym = NULL; 3227 } 3228 3229 for (n = 1; n <= narg; n++) { 3230 3231 /* 3232 * The rightmost argument is at the top of the argument 3233 * subtree. 3234 */ 3235 for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) 3236 continue; 3237 3238 /* some things which are always not allowd */ 3239 if ((at = arg->tn_left->tn_type->t_tspec) == VOID) { 3240 /* void expressions may not be arguments, arg #%d */ 3241 error(151, n); 3242 return (NULL); 3243 } else if ((at == STRUCT || at == UNION) && 3244 incompl(arg->tn_left->tn_type)) { 3245 /* argument cannot have unknown size, arg #%d */ 3246 error(152, n); 3247 return (NULL); 3248 } else if (isityp(at) && arg->tn_left->tn_type->t_isenum && 3249 incompl(arg->tn_left->tn_type)) { 3250 /* argument cannot have unknown size, arg #%d */ 3251 warning(152, n); 3252 } 3253 3254 /* class conversions (arg in value context) */ 3255 arg->tn_left = cconv(arg->tn_left); 3256 3257 if (asym != NULL) { 3258 arg->tn_left = parg(n, asym->s_type, arg->tn_left); 3259 } else { 3260 arg->tn_left = promote(NOOP, 1, arg->tn_left); 3261 } 3262 arg->tn_type = arg->tn_left->tn_type; 3263 3264 if (asym != NULL) 3265 asym = asym->s_nxt; 3266 } 3267 3268 return (args); 3269 } 3270 3271 /* 3272 * Compare the type of an argument with the corresponding type of a 3273 * prototype parameter. If it is a valid combination, but both types 3274 * are not the same, insert a conversion to convert the argument into 3275 * the type of the parameter. 3276 */ 3277 static tnode_t * 3278 parg( int n, /* pos of arg */ 3279 type_t *tp, /* expected type (from prototype) */ 3280 tnode_t *tn) /* argument */ 3281 { 3282 tnode_t *ln; 3283 int warn; 3284 3285 ln = xcalloc(1, sizeof (tnode_t)); 3286 ln->tn_type = tduptyp(tp); 3287 ln->tn_type->t_const = 0; 3288 ln->tn_lvalue = 1; 3289 if (typeok(FARG, n, ln, tn)) { 3290 if (!eqtype(tp, tn->tn_type, 1, 0, (warn = 0, &warn)) || warn) 3291 tn = convert(FARG, n, tp, tn); 3292 } 3293 free(ln); 3294 return (tn); 3295 } 3296 3297 /* 3298 * Return the value of an integral constant expression. 3299 * If the expression is not constant or its type is not an integer 3300 * type, an error message is printed. 3301 */ 3302 val_t * 3303 constant(tnode_t *tn, int required) 3304 { 3305 val_t *v; 3306 3307 if (tn != NULL) 3308 tn = cconv(tn); 3309 if (tn != NULL) 3310 tn = promote(NOOP, 0, tn); 3311 3312 v = xcalloc(1, sizeof (val_t)); 3313 3314 if (tn == NULL) { 3315 if (nerr == 0) 3316 LERROR("constant()"); 3317 v->v_tspec = INT; 3318 v->v_quad = 1; 3319 return (v); 3320 } 3321 3322 v->v_tspec = tn->tn_type->t_tspec; 3323 3324 if (tn->tn_op == CON) { 3325 if (tn->tn_type->t_tspec != tn->tn_val->v_tspec) 3326 LERROR("constant()"); 3327 if (isityp(tn->tn_val->v_tspec)) { 3328 v->v_ansiu = tn->tn_val->v_ansiu; 3329 v->v_quad = tn->tn_val->v_quad; 3330 return (v); 3331 } 3332 v->v_quad = tn->tn_val->v_ldbl; 3333 } else { 3334 v->v_quad = 1; 3335 } 3336 3337 /* integral constant expression expected */ 3338 if (required) 3339 error(55); 3340 else 3341 c99ism(318); 3342 3343 if (!isityp(v->v_tspec)) 3344 v->v_tspec = INT; 3345 3346 return (v); 3347 } 3348 3349 /* 3350 * Perform some tests on expressions which can't be done in build() and 3351 * functions called by build(). These tests must be done here because 3352 * we need some information about the context in which the operations 3353 * are performed. 3354 * After all tests are performed, expr() frees the memory which is used 3355 * for the expression. 3356 */ 3357 void 3358 expr(tnode_t *tn, int vctx, int tctx, int freeblk) 3359 { 3360 3361 if (tn == NULL && nerr == 0) 3362 LERROR("expr()"); 3363 3364 if (tn == NULL) { 3365 tfreeblk(); 3366 return; 3367 } 3368 3369 /* expr() is also called in global initialisations */ 3370 if (dcs->d_ctx != EXTERN) 3371 chkreach(); 3372 3373 chkmisc(tn, vctx, tctx, !tctx, 0, 0, 0); 3374 if (tn->tn_op == ASSIGN) { 3375 if (hflag && tctx) 3376 /* assignment in conditional context */ 3377 warning(159); 3378 } else if (tn->tn_op == CON) { 3379 if (hflag && tctx && !ccflg) 3380 /* constant in conditional context */ 3381 warning(161); 3382 } 3383 if (!modtab[tn->tn_op].m_sideeff) { 3384 /* 3385 * for left operands of COMMA this warning is already 3386 * printed 3387 */ 3388 if (tn->tn_op != COMMA && !vctx && !tctx) 3389 nulleff(tn); 3390 } 3391 if (dflag) 3392 displexpr(tn, 0); 3393 3394 /* free the tree memory */ 3395 if (freeblk) 3396 tfreeblk(); 3397 } 3398 3399 static void 3400 nulleff(tnode_t *tn) 3401 { 3402 3403 if (!hflag) 3404 return; 3405 3406 while (!modtab[tn->tn_op].m_sideeff) { 3407 if (tn->tn_op == CVT && tn->tn_type->t_tspec == VOID) { 3408 tn = tn->tn_left; 3409 } else if (tn->tn_op == LOGAND || tn->tn_op == LOGOR) { 3410 /* 3411 * && and || have a side effect if the right operand 3412 * has a side effect. 3413 */ 3414 tn = tn->tn_right; 3415 } else if (tn->tn_op == QUEST) { 3416 /* 3417 * ? has a side effect if at least one of its right 3418 * operands has a side effect 3419 */ 3420 tn = tn->tn_right; 3421 } else if (tn->tn_op == COLON || tn->tn_op == COMMA) { 3422 /* 3423 * : has a side effect if at least one of its operands 3424 * has a side effect 3425 */ 3426 if (modtab[tn->tn_left->tn_op].m_sideeff) { 3427 tn = tn->tn_left; 3428 } else if (modtab[tn->tn_right->tn_op].m_sideeff) { 3429 tn = tn->tn_right; 3430 } else { 3431 break; 3432 } 3433 } else { 3434 break; 3435 } 3436 } 3437 if (!modtab[tn->tn_op].m_sideeff) 3438 /* expression has null effect */ 3439 warning(129); 3440 } 3441 3442 /* 3443 * Dump an expression to stdout 3444 * only used for debugging 3445 */ 3446 static void 3447 displexpr(tnode_t *tn, int offs) 3448 { 3449 uint64_t uq; 3450 3451 if (tn == NULL) { 3452 (void)printf("%*s%s\n", offs, "", "NULL"); 3453 return; 3454 } 3455 (void)printf("%*sop %s ", offs, "", modtab[tn->tn_op].m_name); 3456 3457 if (tn->tn_op == NAME) { 3458 (void)printf("%s: %s ", 3459 tn->tn_sym->s_name, scltoa(tn->tn_sym->s_scl)); 3460 } else if (tn->tn_op == CON && isftyp(tn->tn_type->t_tspec)) { 3461 (void)printf("%#g ", (double)tn->tn_val->v_ldbl); 3462 } else if (tn->tn_op == CON && isityp(tn->tn_type->t_tspec)) { 3463 uq = tn->tn_val->v_quad; 3464 (void)printf("0x %08lx %08lx ", (long)(uq >> 32) & 0xffffffffl, 3465 (long)uq & 0xffffffffl); 3466 } else if (tn->tn_op == CON) { 3467 if (tn->tn_type->t_tspec != PTR) 3468 LERROR("displexpr()"); 3469 (void)printf("0x%0*lx ", (int)(sizeof (void *) * CHAR_BIT / 4), 3470 (u_long)tn->tn_val->v_quad); 3471 } else if (tn->tn_op == STRING) { 3472 if (tn->tn_strg->st_tspec == CHAR) { 3473 (void)printf("\"%s\"", tn->tn_strg->st_cp); 3474 } else { 3475 char *s; 3476 size_t n; 3477 n = MB_CUR_MAX * (tn->tn_strg->st_len + 1); 3478 s = xmalloc(n); 3479 (void)wcstombs(s, tn->tn_strg->st_wcp, n); 3480 (void)printf("L\"%s\"", s); 3481 free(s); 3482 } 3483 (void)printf(" "); 3484 } else if (tn->tn_op == FSEL) { 3485 (void)printf("o=%d, l=%d ", tn->tn_type->t_foffs, 3486 tn->tn_type->t_flen); 3487 } 3488 (void)printf("%s\n", ttos(tn->tn_type)); 3489 if (tn->tn_op == NAME || tn->tn_op == CON || tn->tn_op == STRING) 3490 return; 3491 displexpr(tn->tn_left, offs + 2); 3492 if (modtab[tn->tn_op].m_binary || 3493 (tn->tn_op == PUSH && tn->tn_right != NULL)) { 3494 displexpr(tn->tn_right, offs + 2); 3495 } 3496 } 3497 3498 /* 3499 * Called by expr() to recursively perform some tests. 3500 */ 3501 /* ARGSUSED */ 3502 void 3503 chkmisc(tnode_t *tn, int vctx, int tctx, int eqwarn, int fcall, int rvdisc, 3504 int szof) 3505 { 3506 tnode_t *ln, *rn; 3507 mod_t *mp; 3508 int nrvdisc, cvctx, ctctx; 3509 op_t op; 3510 scl_t sc; 3511 dinfo_t *di; 3512 3513 if (tn == NULL) 3514 return; 3515 3516 ln = tn->tn_left; 3517 rn = tn->tn_right; 3518 mp = &modtab[op = tn->tn_op]; 3519 3520 switch (op) { 3521 case AMPER: 3522 if (ln->tn_op == NAME && (reached || rchflg)) { 3523 if (!szof) 3524 setsflg(ln->tn_sym); 3525 setuflg(ln->tn_sym, fcall, szof); 3526 } 3527 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) 3528 /* check the range of array indices */ 3529 chkaidx(ln->tn_left, 1); 3530 break; 3531 case LOAD: 3532 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) 3533 /* check the range of array indices */ 3534 chkaidx(ln->tn_left, 0); 3535 /* FALLTHROUGH */ 3536 case PUSH: 3537 case INCBEF: 3538 case DECBEF: 3539 case INCAFT: 3540 case DECAFT: 3541 case ADDASS: 3542 case SUBASS: 3543 case MULASS: 3544 case DIVASS: 3545 case MODASS: 3546 case ANDASS: 3547 case ORASS: 3548 case XORASS: 3549 case SHLASS: 3550 case SHRASS: 3551 case REAL: 3552 case IMAG: 3553 if (ln->tn_op == NAME && (reached || rchflg)) { 3554 sc = ln->tn_sym->s_scl; 3555 /* 3556 * Look if there was a asm statement in one of the 3557 * compound statements we are in. If not, we don't 3558 * print a warning. 3559 */ 3560 for (di = dcs; di != NULL; di = di->d_nxt) { 3561 if (di->d_asm) 3562 break; 3563 } 3564 if (sc != EXTERN && sc != STATIC && 3565 !ln->tn_sym->s_set && !szof && di == NULL) { 3566 /* %s may be used before set */ 3567 warning(158, ln->tn_sym->s_name); 3568 setsflg(ln->tn_sym); 3569 } 3570 setuflg(ln->tn_sym, 0, 0); 3571 } 3572 break; 3573 case ASSIGN: 3574 if (ln->tn_op == NAME && !szof && (reached || rchflg)) { 3575 setsflg(ln->tn_sym); 3576 if (ln->tn_sym->s_scl == EXTERN) 3577 outusg(ln->tn_sym); 3578 } 3579 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS) 3580 /* check the range of array indices */ 3581 chkaidx(ln->tn_left, 0); 3582 break; 3583 case CALL: 3584 if (ln->tn_op != AMPER || ln->tn_left->tn_op != NAME) 3585 LERROR("chkmisc()"); 3586 if (!szof) 3587 outcall(tn, vctx || tctx, rvdisc); 3588 break; 3589 case EQ: 3590 /* equality operator "==" found where "=" was exp. */ 3591 if (hflag && eqwarn) 3592 warning(160); 3593 break; 3594 case CON: 3595 case NAME: 3596 case STRING: 3597 return; 3598 /* LINTED (enumeration values not handled in switch) */ 3599 case OR: 3600 case XOR: 3601 case NE: 3602 case GE: 3603 case GT: 3604 case LE: 3605 case LT: 3606 case SHR: 3607 case SHL: 3608 case MINUS: 3609 case PLUS: 3610 case MOD: 3611 case DIV: 3612 case MULT: 3613 case STAR: 3614 case UMINUS: 3615 case UPLUS: 3616 case DEC: 3617 case INC: 3618 case COMPL: 3619 case NOT: 3620 case POINT: 3621 case ARROW: 3622 case NOOP: 3623 case AND: 3624 case FARG: 3625 case CASE: 3626 case INIT: 3627 case RETURN: 3628 case ICALL: 3629 case CVT: 3630 case COMMA: 3631 case FSEL: 3632 case COLON: 3633 case QUEST: 3634 case LOGOR: 3635 case LOGAND: 3636 break; 3637 } 3638 3639 cvctx = mp->m_vctx; 3640 ctctx = mp->m_tctx; 3641 /* 3642 * values of operands of ':' are not used if the type of at least 3643 * one of the operands (for gcc compatibility) is void 3644 * XXX test/value context of QUEST should probably be used as 3645 * context for both operands of COLON 3646 */ 3647 if (op == COLON && tn->tn_type->t_tspec == VOID) 3648 cvctx = ctctx = 0; 3649 nrvdisc = op == CVT && tn->tn_type->t_tspec == VOID; 3650 chkmisc(ln, cvctx, ctctx, mp->m_eqwarn, op == CALL, nrvdisc, szof); 3651 3652 switch (op) { 3653 case PUSH: 3654 if (rn != NULL) 3655 chkmisc(rn, 0, 0, mp->m_eqwarn, 0, 0, szof); 3656 break; 3657 case LOGAND: 3658 case LOGOR: 3659 chkmisc(rn, 0, 1, mp->m_eqwarn, 0, 0, szof); 3660 break; 3661 case COLON: 3662 chkmisc(rn, cvctx, ctctx, mp->m_eqwarn, 0, 0, szof); 3663 break; 3664 case COMMA: 3665 chkmisc(rn, vctx, tctx, mp->m_eqwarn, 0, 0, szof); 3666 break; 3667 default: 3668 if (mp->m_binary) 3669 chkmisc(rn, 1, 0, mp->m_eqwarn, 0, 0, szof); 3670 break; 3671 } 3672 3673 } 3674 3675 /* 3676 * Checks the range of array indices, if possible. 3677 * amper is set if only the address of the element is used. This 3678 * means that the index is allowd to refere to the first element 3679 * after the array. 3680 */ 3681 static void 3682 chkaidx(tnode_t *tn, int amper) 3683 { 3684 int dim; 3685 tnode_t *ln, *rn; 3686 int elsz; 3687 int64_t con; 3688 3689 ln = tn->tn_left; 3690 rn = tn->tn_right; 3691 3692 /* We can only check constant indices. */ 3693 if (rn->tn_op != CON) 3694 return; 3695 3696 /* Return if the left node does not stem from an array. */ 3697 if (ln->tn_op != AMPER) 3698 return; 3699 if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME) 3700 return; 3701 if (ln->tn_left->tn_type->t_tspec != ARRAY) 3702 return; 3703 3704 /* 3705 * For incomplete array types, we can print a warning only if 3706 * the index is negative. 3707 */ 3708 if (incompl(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0) 3709 return; 3710 3711 /* Get the size of one array element */ 3712 if ((elsz = length(ln->tn_type->t_subt, NULL)) == 0) 3713 return; 3714 elsz /= CHAR_BIT; 3715 3716 /* Change the unit of the index from bytes to element size. */ 3717 if (isutyp(rn->tn_type->t_tspec)) { 3718 con = (uint64_t)rn->tn_val->v_quad / elsz; 3719 } else { 3720 con = rn->tn_val->v_quad / elsz; 3721 } 3722 3723 dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0); 3724 3725 if (!isutyp(rn->tn_type->t_tspec) && con < 0) { 3726 /* array subscript cannot be negative: %ld */ 3727 warning(167, (long)con); 3728 } else if (dim > 0 && (uint64_t)con >= dim) { 3729 /* array subscript cannot be > %d: %ld */ 3730 warning(168, dim - 1, (long)con); 3731 } 3732 } 3733 3734 /* 3735 * Check for ordered comparisons of unsigned values with 0. 3736 */ 3737 static void 3738 chkcomp(op_t op, tnode_t *ln, tnode_t *rn) 3739 { 3740 char buf[64]; 3741 tspec_t lt, rt; 3742 mod_t *mp; 3743 3744 lt = ln->tn_type->t_tspec; 3745 rt = rn->tn_type->t_tspec; 3746 mp = &modtab[op]; 3747 3748 if (ln->tn_op != CON && rn->tn_op != CON) 3749 return; 3750 3751 if (!isityp(lt) || !isityp(rt)) 3752 return; 3753 3754 if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON && 3755 (rn->tn_val->v_quad < 0 || 3756 rn->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) { 3757 /* nonportable character comparison, op %s */ 3758 warning(230, mp->m_name); 3759 return; 3760 } 3761 if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON && 3762 (ln->tn_val->v_quad < 0 || 3763 ln->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) { 3764 /* nonportable character comparison, op %s */ 3765 warning(230, mp->m_name); 3766 return; 3767 } 3768 if (isutyp(lt) && !isutyp(rt) && 3769 rn->tn_op == CON && rn->tn_val->v_quad <= 0) { 3770 if (rn->tn_val->v_quad < 0) { 3771 /* comparison of %s with %s, op %s */ 3772 warning(162, tyname(buf, sizeof(buf), ln->tn_type), 3773 "negative constant", mp->m_name); 3774 } else if (op == LT || op == GE || (hflag && op == LE)) { 3775 /* comparison of %s with %s, op %s */ 3776 warning(162, tyname(buf, sizeof(buf), ln->tn_type), 3777 "0", mp->m_name); 3778 } 3779 return; 3780 } 3781 if (isutyp(rt) && !isutyp(lt) && 3782 ln->tn_op == CON && ln->tn_val->v_quad <= 0) { 3783 if (ln->tn_val->v_quad < 0) { 3784 /* comparison of %s with %s, op %s */ 3785 warning(162, "negative constant", 3786 tyname(buf, sizeof(buf), rn->tn_type), mp->m_name); 3787 } else if (op == GT || op == LE || (hflag && op == GE)) { 3788 /* comparison of %s with %s, op %s */ 3789 warning(162, "0", tyname(buf, sizeof(buf), rn->tn_type), 3790 mp->m_name); 3791 } 3792 return; 3793 } 3794 } 3795 3796 /* 3797 * Takes an expression an returns 0 if this expression can be used 3798 * for static initialisation, otherwise -1. 3799 * 3800 * Constant initialisation expressions must be constant or an address 3801 * of a static object with an optional offset. In the first case, 3802 * the result is returned in *offsp. In the second case, the static 3803 * object is returned in *symp and the offset in *offsp. 3804 * 3805 * The expression can consist of PLUS, MINUS, AMPER, NAME, STRING and 3806 * CON. Type conversions are allowed if they do not change binary 3807 * representation (including width). 3808 */ 3809 int 3810 conaddr(tnode_t *tn, sym_t **symp, ptrdiff_t *offsp) 3811 { 3812 sym_t *sym; 3813 ptrdiff_t offs1, offs2; 3814 tspec_t t, ot; 3815 3816 switch (tn->tn_op) { 3817 case MINUS: 3818 if (tn->tn_right->tn_op == CVT) 3819 return conaddr(tn->tn_right, symp, offsp); 3820 else if (tn->tn_right->tn_op != CON) 3821 return (-1); 3822 /* FALLTHROUGH */ 3823 case PLUS: 3824 offs1 = offs2 = 0; 3825 if (tn->tn_left->tn_op == CON) { 3826 offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad; 3827 if (conaddr(tn->tn_right, &sym, &offs2) == -1) 3828 return (-1); 3829 } else if (tn->tn_right->tn_op == CON) { 3830 offs2 = (ptrdiff_t)tn->tn_right->tn_val->v_quad; 3831 if (tn->tn_op == MINUS) 3832 offs2 = -offs2; 3833 if (conaddr(tn->tn_left, &sym, &offs1) == -1) 3834 return (-1); 3835 } else { 3836 return (-1); 3837 } 3838 *symp = sym; 3839 *offsp = offs1 + offs2; 3840 break; 3841 case AMPER: 3842 if (tn->tn_left->tn_op == NAME) { 3843 *symp = tn->tn_left->tn_sym; 3844 *offsp = 0; 3845 } else if (tn->tn_left->tn_op == STRING) { 3846 /* 3847 * If this would be the front end of a compiler we 3848 * would return a label instead of 0. 3849 */ 3850 *offsp = 0; 3851 } 3852 break; 3853 case CVT: 3854 t = tn->tn_type->t_tspec; 3855 ot = tn->tn_left->tn_type->t_tspec; 3856 if ((!isityp(t) && t != PTR) || (!isityp(ot) && ot != PTR)) 3857 return (-1); 3858 #ifdef notdef 3859 /* 3860 * consider: 3861 * struct foo { 3862 * unsigned char a; 3863 * } f = { 3864 * (u_char)(u_long)(&(((struct foo *)0)->a)) 3865 * }; 3866 * since psize(u_long) != psize(u_char) this fails. 3867 */ 3868 else if (psize(t) != psize(ot)) 3869 return (-1); 3870 #endif 3871 if (conaddr(tn->tn_left, symp, offsp) == -1) 3872 return (-1); 3873 break; 3874 default: 3875 return (-1); 3876 } 3877 return (0); 3878 } 3879 3880 /* 3881 * Concatenate two string constants. 3882 */ 3883 strg_t * 3884 catstrg(strg_t *strg1, strg_t *strg2) 3885 { 3886 size_t len1, len2, len; 3887 3888 if (strg1->st_tspec != strg2->st_tspec) { 3889 /* cannot concatenate wide and regular string literals */ 3890 error(292); 3891 return (strg1); 3892 } 3893 3894 len = (len1 = strg1->st_len) + (len2 = strg2->st_len); 3895 3896 if (strg1->st_tspec == CHAR) { 3897 strg1->st_cp = xrealloc(strg1->st_cp, len + 1); 3898 (void)memcpy(strg1->st_cp + len1, strg2->st_cp, len2 + 1); 3899 free(strg2->st_cp); 3900 } else { 3901 strg1->st_wcp = xrealloc(strg1->st_wcp, 3902 (len + 1) * sizeof (wchar_t)); 3903 (void)memcpy(strg1->st_wcp + len1, strg2->st_wcp, 3904 (len2 + 1) * sizeof (wchar_t)); 3905 free(strg2->st_wcp); 3906 } 3907 free(strg2); 3908 3909 return (strg1); 3910 } 3911 3912 /* 3913 * Print a warning if the given node has operands which should be 3914 * parenthesized. 3915 * 3916 * XXX Does not work if an operand is a constant expression. Constant 3917 * expressions are already folded. 3918 */ 3919 static void 3920 precconf(tnode_t *tn) 3921 { 3922 tnode_t *ln, *rn; 3923 op_t lop, rop = NOOP; 3924 int lparn, rparn = 0; 3925 mod_t *mp; 3926 int warn; 3927 3928 if (!hflag) 3929 return; 3930 3931 mp = &modtab[tn->tn_op]; 3932 3933 lparn = 0; 3934 for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left) 3935 lparn |= ln->tn_parn; 3936 lparn |= ln->tn_parn; 3937 lop = ln->tn_op; 3938 3939 if (mp->m_binary) { 3940 rparn = 0; 3941 for (rn = tn->tn_right; tn->tn_op == CVT; rn = rn->tn_left) 3942 rparn |= rn->tn_parn; 3943 rparn |= rn->tn_parn; 3944 rop = rn->tn_op; 3945 } 3946 3947 warn = 0; 3948 3949 switch (tn->tn_op) { 3950 case SHL: 3951 case SHR: 3952 if (!lparn && (lop == PLUS || lop == MINUS)) { 3953 warn = 1; 3954 } else if (!rparn && (rop == PLUS || rop == MINUS)) { 3955 warn = 1; 3956 } 3957 break; 3958 case LOGOR: 3959 if (!lparn && lop == LOGAND) { 3960 warn = 1; 3961 } else if (!rparn && rop == LOGAND) { 3962 warn = 1; 3963 } 3964 break; 3965 case AND: 3966 case XOR: 3967 case OR: 3968 if (!lparn && lop != tn->tn_op) { 3969 if (lop == PLUS || lop == MINUS) { 3970 warn = 1; 3971 } else if (lop == AND || lop == XOR) { 3972 warn = 1; 3973 } 3974 } 3975 if (!warn && !rparn && rop != tn->tn_op) { 3976 if (rop == PLUS || rop == MINUS) { 3977 warn = 1; 3978 } else if (rop == AND || rop == XOR) { 3979 warn = 1; 3980 } 3981 } 3982 break; 3983 /* LINTED (enumeration values not handled in switch) */ 3984 case DECAFT: 3985 case XORASS: 3986 case SHLASS: 3987 case NOOP: 3988 case ARROW: 3989 case ORASS: 3990 case POINT: 3991 case NAME: 3992 case NOT: 3993 case COMPL: 3994 case CON: 3995 case INC: 3996 case STRING: 3997 case DEC: 3998 case INCBEF: 3999 case DECBEF: 4000 case INCAFT: 4001 case FSEL: 4002 case CALL: 4003 case COMMA: 4004 case CVT: 4005 case ICALL: 4006 case LOAD: 4007 case PUSH: 4008 case RETURN: 4009 case INIT: 4010 case CASE: 4011 case FARG: 4012 case SUBASS: 4013 case ADDASS: 4014 case MODASS: 4015 case DIVASS: 4016 case MULASS: 4017 case ASSIGN: 4018 case COLON: 4019 case QUEST: 4020 case LOGAND: 4021 case NE: 4022 case EQ: 4023 case GE: 4024 case GT: 4025 case LE: 4026 case LT: 4027 case MINUS: 4028 case PLUS: 4029 case MOD: 4030 case DIV: 4031 case MULT: 4032 case AMPER: 4033 case STAR: 4034 case UMINUS: 4035 case SHRASS: 4036 case UPLUS: 4037 case ANDASS: 4038 case REAL: 4039 case IMAG: 4040 break; 4041 } 4042 4043 if (warn) { 4044 /* precedence confusion possible: parenthesize! */ 4045 warning(169); 4046 } 4047 4048 } 4049