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