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