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