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