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