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