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