Add some missing $DragonFly$ keywords.
[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.3 2003/11/03 19:14:36 eirikn 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 __P((tspec_t, quad_t));
50 static  void    ptrcmpok __P((op_t, tnode_t *, tnode_t *));
51 static  int     asgntypok __P((op_t, int, tnode_t *, tnode_t *));
52 static  void    chkbeop __P((op_t, tnode_t *, tnode_t *));
53 static  void    chkeop2 __P((op_t, int, tnode_t *, tnode_t *));
54 static  void    chkeop1 __P((op_t, int, tnode_t *, tnode_t *));
55 static  tnode_t *mktnode __P((op_t, type_t *, tnode_t *, tnode_t *));
56 static  void    balance __P((op_t, tnode_t **, tnode_t **));
57 static  void    incompat __P((op_t, tspec_t, tspec_t));
58 static  void    illptrc __P((mod_t *, type_t *, type_t *));
59 static  void    mrgqual __P((type_t **, type_t *, type_t *));
60 static  int     conmemb __P((type_t *));
61 static  void    ptconv __P((int, tspec_t, tspec_t, type_t *, tnode_t *));
62 static  void    iiconv __P((op_t, int, tspec_t, tspec_t, type_t *, tnode_t *));
63 static  void    piconv __P((op_t, tspec_t, type_t *, tnode_t *));
64 static  void    ppconv __P((op_t, tnode_t *, type_t *));
65 static  tnode_t *bldstr __P((op_t, tnode_t *, tnode_t *));
66 static  tnode_t *bldincdec __P((op_t, tnode_t *));
67 static  tnode_t *bldamper __P((tnode_t *, int));
68 static  tnode_t *bldplmi __P((op_t, tnode_t *, tnode_t *));
69 static  tnode_t *bldshft __P((op_t, tnode_t *, tnode_t *));
70 static  tnode_t *bldcol __P((tnode_t *, tnode_t *));
71 static  tnode_t *bldasgn __P((op_t, tnode_t *, tnode_t *));
72 static  tnode_t *plength __P((type_t *));
73 static  tnode_t *fold __P((tnode_t *));
74 static  tnode_t *foldtst __P((tnode_t *));
75 static  tnode_t *foldflt __P((tnode_t *));
76 static  tnode_t *chkfarg __P((type_t *, tnode_t *));
77 static  tnode_t *parg __P((int, type_t *, tnode_t *));
78 static  void    nulleff __P((tnode_t *));
79 static  void    displexpr __P((tnode_t *, int));
80 static  void    chkaidx __P((tnode_t *, int));
81 static  void    chkcomp __P((op_t, tnode_t *, tnode_t *));
82 static  void    precconf __P((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         }
1137
1138         if (mp->m_badeop &&
1139             (ltp->t_isenum || (mp->m_binary && rtp->t_isenum))) {
1140                 chkbeop(op, ln, rn);
1141         } else if (mp->m_enumop && (ltp->t_isenum && rtp->t_isenum)) {
1142                 chkeop2(op, arg, ln, rn);
1143         } else if (mp->m_enumop && (ltp->t_isenum || rtp->t_isenum)) {
1144                 chkeop1(op, arg, ln, rn);
1145         }
1146
1147         return (1);
1148 }
1149
1150 static void
1151 ptrcmpok(op, ln, rn)
1152         op_t    op;
1153         tnode_t *ln, *rn;
1154 {
1155         type_t  *ltp, *rtp;
1156         tspec_t lt, rt;
1157         const   char *lts, *rts;
1158
1159         lt = (ltp = ln->tn_type)->t_subt->t_tspec;
1160         rt = (rtp = rn->tn_type)->t_subt->t_tspec;
1161
1162         if (lt == VOID || rt == VOID) {
1163                 if (sflag && (lt == FUNC || rt == FUNC)) {
1164                         /* (void *)0 already handled in typeok() */
1165                         *(lt == FUNC ? &lts : &rts) = "function pointer";
1166                         *(lt == VOID ? &lts : &rts) = "'void *'";
1167                         /* ANSI C forbids comparision of %s with %s */
1168                         warning(274, lts, rts);
1169                 }
1170                 return;
1171         }
1172
1173         if (!eqtype(ltp->t_subt, rtp->t_subt, 1, 0, NULL)) {
1174                 illptrc(&modtab[op], ltp, rtp);
1175                 return;
1176         }
1177
1178         if (lt == FUNC && rt == FUNC) {
1179                 if (sflag && op != EQ && op != NE)
1180                         /* ANSI C forbids ordered comp. of func ptr */
1181                         warning(125);
1182         }
1183 }
1184
1185 /*
1186  * Checks type compatibility for ASSIGN, INIT, FARG and RETURN
1187  * and prints warnings/errors if necessary.
1188  * If the types are (almost) compatible, 1 is returned, otherwise 0.
1189  */
1190 static int
1191 asgntypok(op, arg, ln, rn)
1192         op_t    op;
1193         int     arg;
1194         tnode_t *ln, *rn;
1195 {
1196         tspec_t lt, rt, lst, rst;
1197         type_t  *ltp, *rtp, *lstp, *rstp;
1198         mod_t   *mp;
1199         const   char *lts, *rts;
1200
1201         if ((lt = (ltp = ln->tn_type)->t_tspec) == PTR)
1202                 lst = (lstp = ltp->t_subt)->t_tspec;
1203         if ((rt = (rtp = rn->tn_type)->t_tspec) == PTR)
1204                 rst = (rstp = rtp->t_subt)->t_tspec;
1205         mp = &modtab[op];
1206
1207         if (isatyp(lt) && isatyp(rt))
1208                 return (1);
1209
1210         if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION))
1211                 /* both are struct or union */
1212                 return (ltp->t_str == rtp->t_str);
1213
1214         /* 0, 0L and (void *)0 may be assigned to any pointer */
1215         if (lt == PTR && ((rt == PTR && rst == VOID) || isityp(rt))) {
1216                 if (rn->tn_op == CON && rn->tn_val->v_quad == 0)
1217                         return (1);
1218         }
1219
1220         if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID)) {
1221                 /* two pointers, at least one pointer to void */
1222                 if (sflag && (lst == FUNC || rst == FUNC)) {
1223                         /* comb. of ptr to func and ptr to void */
1224                         *(lst == FUNC ? &lts : &rts) = "function pointer";
1225                         *(lst == VOID ? &lts : &rts) = "'void *'";
1226                         switch (op) {
1227                         case INIT:
1228                         case RETURN:
1229                                 /* ANSI C forbids conversion of %s to %s */
1230                                 warning(303, rts, lts);
1231                                 break;
1232                         case FARG:
1233                                 /* ANSI C forbids conv. of %s to %s, arg #%d */
1234                                 warning(304, rts, lts, arg);
1235                                 break;
1236                         default:
1237                                 /* ANSI C forbids conv. of %s to %s, op %s */
1238                                 warning(305, rts, lts, mp->m_name);
1239                                 break;
1240                         }
1241                 }
1242         }
1243
1244         if (lt == PTR && rt == PTR && (lst == VOID || rst == VOID ||
1245                                        eqtype(lstp, rstp, 1, 0, NULL))) {
1246                 /* compatible pointer types (qualifiers ignored) */
1247                 if (!tflag &&
1248                     ((!lstp->t_const && rstp->t_const) ||
1249                      (!lstp->t_volatile && rstp->t_volatile))) {
1250                         /* left side has not all qualifiers of right */
1251                         switch (op) {
1252                         case INIT:
1253                         case RETURN:
1254                                 /* incompatible pointer types */
1255                                 warning(182);
1256                                 break;
1257                         case FARG:
1258                                 /* argument has incompat. ptr. type, arg #%d */
1259                                 warning(153, arg);
1260                                 break;
1261                         default:
1262                                 /* operands have incompat. ptr. types, op %s */
1263                                 warning(128, mp->m_name);
1264                                 break;
1265                         }
1266                 }
1267                 return (1);
1268         }
1269
1270         if ((lt == PTR && isityp(rt)) || (isityp(lt) && rt == PTR)) {
1271                 switch (op) {
1272                 case INIT:
1273                 case RETURN:
1274                         /* illegal combination of pointer and integer */
1275                         warning(183);
1276                         break;
1277                 case FARG:
1278                         /* illegal comb. of ptr. and int., arg #%d */
1279                         warning(154, arg);
1280                         break;
1281                 default:
1282                         /* illegal comb. of ptr. and int., op %s */
1283                         warning(123, mp->m_name);
1284                         break;
1285                 }
1286                 return (1);
1287         }
1288
1289         if (lt == PTR && rt == PTR) {
1290                 switch (op) {
1291                 case INIT:
1292                 case RETURN:
1293                         illptrc(NULL, ltp, rtp);
1294                         break;
1295                 case FARG:
1296                         /* argument has incompatible pointer type, arg #%d */
1297                         warning(153, arg);
1298                         break;
1299                 default:
1300                         illptrc(mp, ltp, rtp);
1301                         break;
1302                 }
1303                 return (1);
1304         }
1305
1306         switch (op) {
1307         case INIT:
1308                 /* initialisation type mismatch */
1309                 error(185);
1310                 break;
1311         case RETURN:
1312                 /* return value type mismatch */
1313                 error(211);
1314                 break;
1315         case FARG:
1316                 /* argument is incompatible with prototype, arg #%d */
1317                 warning(155, arg);
1318                 break;
1319         default:
1320                 incompat(op, lt, rt);
1321                 break;
1322         }
1323
1324         return (0);
1325 }
1326
1327 /*
1328  * Prints a warning if an operator, which should be senseless for an
1329  * enum type, is applied to an enum type.
1330  */
1331 static void
1332 chkbeop(op, ln, rn)
1333         op_t    op;
1334         tnode_t *ln, *rn;
1335 {
1336         mod_t   *mp;
1337
1338         if (!eflag)
1339                 return;
1340
1341         mp = &modtab[op];
1342
1343         if (!(ln->tn_type->t_isenum ||
1344               (mp->m_binary && rn->tn_type->t_isenum))) {
1345                 return;
1346         }
1347
1348         /*
1349          * Enum as offset to a pointer is an exception (otherwise enums
1350          * could not be used as array indizes).
1351          */
1352         if (op == PLUS &&
1353             ((ln->tn_type->t_isenum && rn->tn_type->t_tspec == PTR) ||
1354              (rn->tn_type->t_isenum && ln->tn_type->t_tspec == PTR))) {
1355                 return;
1356         }
1357
1358         /* dubious operation on enum, op %s */
1359         warning(241, mp->m_name);
1360
1361 }
1362
1363 /*
1364  * Prints a warning if an operator is applied to two different enum types.
1365  */
1366 static void
1367 chkeop2(op, arg, ln, rn)
1368         op_t    op;
1369         int     arg;
1370         tnode_t *ln, *rn;
1371 {
1372         mod_t   *mp;
1373
1374         mp = &modtab[op];
1375
1376         if (ln->tn_type->t_enum != rn->tn_type->t_enum) {
1377                 switch (op) {
1378                 case INIT:
1379                         /* enum type mismatch in initialisation */
1380                         warning(210);
1381                         break;
1382                 case FARG:
1383                         /* enum type mismatch, arg #%d */
1384                         warning(156, arg);
1385                         break;
1386                 case RETURN:
1387                         /* return value type mismatch */
1388                         warning(211);
1389                         break;
1390                 default:
1391                         /* enum type mismatch, op %s */
1392                         warning(130, mp->m_name);
1393                         break;
1394                 }
1395 #if 0
1396         } else if (mp->m_comp && op != EQ && op != NE) {
1397                 if (eflag)
1398                         /* dubious comparisions of enums */
1399                         warning(243, mp->m_name);
1400 #endif
1401         }
1402 }
1403
1404 /*
1405  * Prints a warning if an operator has both enum end other integer
1406  * types.
1407  */
1408 static void
1409 chkeop1(op, arg, ln, rn)
1410         op_t    op;
1411         int     arg;
1412         tnode_t *ln, *rn;
1413 {
1414         if (!eflag)
1415                 return;
1416
1417         switch (op) {
1418         case INIT:
1419                 /*
1420                  * Initializations with 0 should be allowed. Otherwise,
1421                  * we should complain about all uninitialized enums,
1422                  * consequently.
1423                  */
1424                 if (!rn->tn_type->t_isenum && rn->tn_op == CON &&
1425                     isityp(rn->tn_type->t_tspec) && rn->tn_val->v_quad == 0) {
1426                         return;
1427                 }
1428                 /* initialisation of '%s' with '%s' */
1429                 warning(277, tyname(ln->tn_type), tyname(rn->tn_type));
1430                 break;
1431         case FARG:
1432                 /* combination of '%s' and '%s', arg #%d */
1433                 warning(278, tyname(ln->tn_type), tyname(rn->tn_type), arg);
1434                 break;
1435         case RETURN:
1436                 /* combination of '%s' and '%s' in return */
1437                 warning(279, tyname(ln->tn_type), tyname(rn->tn_type));
1438                 break;
1439         default:
1440                 /* combination of '%s' and %s, op %s */
1441                 warning(242, tyname(ln->tn_type), tyname(rn->tn_type),
1442                         modtab[op].m_name);
1443                 break;
1444         }
1445 }
1446
1447 /*
1448  * Build and initialize a new node.
1449  */
1450 static tnode_t *
1451 mktnode(op, type, ln, rn)
1452         op_t    op;
1453         type_t  *type;
1454         tnode_t *ln, *rn;
1455 {
1456         tnode_t *ntn;
1457         tspec_t t;
1458
1459         ntn = getnode();
1460
1461         ntn->tn_op = op;
1462         ntn->tn_type = type;
1463         ntn->tn_left = ln;
1464         ntn->tn_right = rn;
1465
1466         if (op == STAR || op == FSEL) {
1467                 if (ln->tn_type->t_tspec == PTR) {
1468                         t = ln->tn_type->t_subt->t_tspec;
1469                         if (t != FUNC && t != VOID)
1470                                 ntn->tn_lvalue = 1;
1471                 } else {
1472                         lerror("mktnode() 2");
1473                 }
1474         }
1475
1476         return (ntn);
1477 }
1478
1479 /*
1480  * Performs usual conversion of operands to (unsigned) int.
1481  *
1482  * If tflag is set or the operand is a function argument with no
1483  * type information (no prototype or variable # of args), convert
1484  * float to double.
1485  */
1486 tnode_t *
1487 promote(op, farg, tn)
1488         op_t    op;
1489         int     farg;
1490         tnode_t *tn;
1491 {
1492         tspec_t t;
1493         type_t  *ntp;
1494         int     len;
1495
1496         t = tn->tn_type->t_tspec;
1497
1498         if (!isatyp(t))
1499                 return (tn);
1500
1501         if (!tflag) {
1502                 /*
1503                  * ANSI C requires that the result is always of type INT
1504                  * if INT can represent all possible values of the previous
1505                  * type.
1506                  */
1507                 if (tn->tn_type->t_isfield) {
1508                         len = tn->tn_type->t_flen;
1509                         if (size(INT) > len) {
1510                                 t = INT;
1511                         } else {
1512                                 if (size(INT) != len)
1513                                         lerror("promote() 1");
1514                                 if (isutyp(t)) {
1515                                         t = UINT;
1516                                 } else {
1517                                         t = INT;
1518                                 }
1519                         }
1520                 } else if (t == CHAR || t == UCHAR || t == SCHAR) {
1521                         t = (size(CHAR) < size(INT) || t != UCHAR) ?
1522                                 INT : UINT;
1523                 } else if (t == SHORT || t == USHORT) {
1524                         t = (size(SHORT) < size(INT) || t == SHORT) ?
1525                                 INT : UINT;
1526                 } else if (t == ENUM) {
1527                         t = INT;
1528                 } else if (farg && t == FLOAT) {
1529                         t = DOUBLE;
1530                 }
1531         } else {
1532                 /*
1533                  * In traditional C, keep unsigned and promote FLOAT
1534                  * to DOUBLE.
1535                  */
1536                 if (t == UCHAR || t == USHORT) {
1537                         t = UINT;
1538                 } else if (t == CHAR || t == SCHAR || t == SHORT) {
1539                         t = INT;
1540                 } else if (t == FLOAT) {
1541                         t = DOUBLE;
1542                 } else if (t == ENUM) {
1543                         t = INT;
1544                 }
1545         }
1546
1547         if (t != tn->tn_type->t_tspec) {
1548                 ntp = tduptyp(tn->tn_type);
1549                 ntp->t_tspec = t;
1550                 /*
1551                  * Keep t_isenum so we are later able to check compatibility
1552                  * of enum types.
1553                  */
1554                 tn = convert(op, 0, ntp, tn);
1555         }
1556
1557         return (tn);
1558 }
1559
1560 /*
1561  * Insert conversions which are necessary to give both operands the same
1562  * type. This is done in different ways for traditional C and ANIS C.
1563  */
1564 static void
1565 balance(op, lnp, rnp)
1566         op_t    op;
1567         tnode_t **lnp, **rnp;
1568 {
1569         tspec_t lt, rt, t;
1570         int     i, u;
1571         type_t  *ntp;
1572         static  tspec_t tl[] = {
1573                 LDOUBLE, DOUBLE, FLOAT, UQUAD, QUAD, ULONG, LONG, UINT, INT,
1574         };
1575
1576         lt = (*lnp)->tn_type->t_tspec;
1577         rt = (*rnp)->tn_type->t_tspec;
1578
1579         if (!isatyp(lt) || !isatyp(rt))
1580                 return;
1581
1582         if (!tflag) {
1583                 if (lt == rt) {
1584                         t = lt;
1585                 } else if (lt == LDOUBLE || rt == LDOUBLE) {
1586                         t = LDOUBLE;
1587                 } else if (lt == DOUBLE || rt == DOUBLE) {
1588                         t = DOUBLE;
1589                 } else if (lt == FLOAT || rt == FLOAT) {
1590                         t = FLOAT;
1591                 } else {
1592                         /*
1593                          * If type A has more bits than type B it should
1594                          * be able to hold all possible values of type B.
1595                          */
1596                         if (size(lt) > size(rt)) {
1597                                 t = lt;
1598                         } else if (size(lt) < size(rt)) {
1599                                 t = rt;
1600                         } else {
1601                                 for (i = 3; tl[i] != INT; i++) {
1602                                         if (tl[i] == lt || tl[i] == rt)
1603                                                 break;
1604                                 }
1605                                 if ((isutyp(lt) || isutyp(rt)) &&
1606                                     !isutyp(tl[i])) {
1607                                         i--;
1608                                 }
1609                                 t = tl[i];
1610                         }
1611                 }
1612         } else {
1613                 /* Keep unsigned in traditional C */
1614                 u = isutyp(lt) || isutyp(rt);
1615                 for (i = 0; tl[i] != INT; i++) {
1616                         if (lt == tl[i] || rt == tl[i])
1617                                 break;
1618                 }
1619                 t = tl[i];
1620                 if (u && isityp(t) && !isutyp(t))
1621                         t = utyp(t);
1622         }
1623
1624         if (t != lt) {
1625                 ntp = tduptyp((*lnp)->tn_type);
1626                 ntp->t_tspec = t;
1627                 *lnp = convert(op, 0, ntp, *lnp);
1628         }
1629         if (t != rt) {
1630                 ntp = tduptyp((*rnp)->tn_type);
1631                 ntp->t_tspec = t;
1632                 *rnp = convert(op, 0, ntp, *rnp);
1633         }
1634 }
1635
1636 /*
1637  * Insert a conversion operator, which converts the type of the node
1638  * to another given type.
1639  * If op is FARG, arg is the number of the argument (used for warnings).
1640  */
1641 tnode_t *
1642 convert(op, arg, tp, tn)
1643         op_t    op;
1644         int     arg;
1645         type_t  *tp;
1646         tnode_t *tn;
1647 {
1648         tnode_t *ntn;
1649         tspec_t nt, ot, ost;
1650
1651         if (tn->tn_lvalue)
1652                 lerror("convert() 1");
1653
1654         nt = tp->t_tspec;
1655         if ((ot = tn->tn_type->t_tspec) == PTR)
1656                 ost = tn->tn_type->t_subt->t_tspec;
1657
1658         if (!tflag && !sflag && op == FARG)
1659                 ptconv(arg, nt, ot, tp, tn);
1660         if (isityp(nt) && isityp(ot)) {
1661                 iiconv(op, arg, nt, ot, tp, tn);
1662         } else if (nt == PTR && ((ot == PTR && ost == VOID) || isityp(ot)) &&
1663                    tn->tn_op == CON && tn->tn_val->v_quad == 0) {
1664                 /* 0, 0L and (void *)0 may be assigned to any pointer. */
1665         } else if (isityp(nt) && ot == PTR) {
1666                 piconv(op, nt, tp, tn);
1667         } else if (nt == PTR && ot == PTR) {
1668                 ppconv(op, tn, tp);
1669         }
1670
1671         ntn = getnode();
1672         ntn->tn_op = CVT;
1673         ntn->tn_type = tp;
1674         ntn->tn_cast = op == CVT;
1675         if (tn->tn_op != CON || nt == VOID) {
1676                 ntn->tn_left = tn;
1677         } else {
1678                 ntn->tn_op = CON;
1679                 ntn->tn_val = tgetblk(sizeof (val_t));
1680                 cvtcon(op, arg, ntn->tn_type, ntn->tn_val, tn->tn_val);
1681         }
1682
1683         return (ntn);
1684 }
1685
1686 /*
1687  * Print a warning if a prototype causes a type conversion that is
1688  * different from what would happen to the same argument in the
1689  * absence of a prototype.
1690  *
1691  * Errors/Warnings about illegal type combinations are already printed
1692  * in asgntypok().
1693  */
1694 static void
1695 ptconv(arg, nt, ot, tp, tn)
1696         int     arg;
1697         tspec_t nt, ot;
1698         type_t  *tp;
1699         tnode_t *tn;
1700 {
1701         tnode_t *ptn;
1702
1703         if (!isatyp(nt) || !isatyp(ot))
1704                 return;
1705
1706         /*
1707          * If the type of the formal parameter is char/short, a warning
1708          * would be useless, because functions declared the old style
1709          * can't expect char/short arguments.
1710          */
1711         if (nt == CHAR || nt == UCHAR || nt == SHORT || nt == USHORT)
1712                 return;
1713
1714         /* get default promotion */
1715         ptn = promote(NOOP, 1, tn);
1716         ot = ptn->tn_type->t_tspec;
1717
1718         /* return if types are the same with and without prototype */
1719         if (nt == ot || (nt == ENUM && ot == INT))
1720                 return;
1721
1722         if (isftyp(nt) != isftyp(ot) || psize(nt) != psize(ot)) {
1723                 /* representation and/or width change */
1724                 if (styp(nt) != SHORT || !isityp(ot) || psize(ot) > psize(INT))
1725                         /* conversion to '%s' due to prototype, arg #%d */
1726                         warning(259, tyname(tp), arg);
1727         } else if (hflag) {
1728                 /*
1729                  * they differ in sign or base type (char, short, int,
1730                  * long, long long, float, double, long double)
1731                  *
1732                  * if they differ only in sign and the argument is a constant
1733                  * and the msb of the argument is not set, print no warning
1734                  */
1735                 if (ptn->tn_op == CON && isityp(nt) && styp(nt) == styp(ot) &&
1736                     msb(ptn->tn_val->v_quad, ot, -1) == 0) {
1737                         /* ok */
1738                 } else {
1739                         /* conversion to '%s' due to prototype, arg #%d */
1740                         warning(259, tyname(tp), arg);
1741                 }
1742         }
1743 }
1744
1745 /*
1746  * Print warnings for conversions of integer types which my cause
1747  * problems.
1748  */
1749 /* ARGSUSED */
1750 static void
1751 iiconv(op, arg, nt, ot, tp, tn)
1752         op_t    op;
1753         int     arg;
1754         tspec_t nt, ot;
1755         type_t  *tp;
1756         tnode_t *tn;
1757 {
1758         if (tn->tn_op == CON)
1759                 return;
1760
1761         if (op == CVT)
1762                 return;
1763
1764 #if 0
1765         if (psize(nt) > psize(ot) && isutyp(nt) != isutyp(ot)) {
1766                 /* conversion to %s may sign-extend incorrectly (, arg #%d) */
1767                 if (aflag && pflag) {
1768                         if (op == FARG) {
1769                                 warning(297, tyname(tp), arg);
1770                         } else {
1771                                 warning(131, tyname(tp));
1772                         }
1773                 }
1774         }
1775 #endif
1776
1777         if (psize(nt) < psize(ot) &&
1778             (ot == LONG || ot == ULONG || ot == QUAD || ot == UQUAD ||
1779              aflag > 1)) {
1780                 /* conversion from '%s' may lose accuracy */
1781                 if (aflag) {
1782                         if (op == FARG) {
1783                                 warning(298, tyname(tn->tn_type), arg);
1784                         } else {
1785                                 warning(132, tyname(tn->tn_type));
1786                         }
1787                 } 
1788         }
1789 }
1790
1791 /*
1792  * Print warnings for dubious conversions of pointer to integer.
1793  */
1794 static void
1795 piconv(op, nt, tp, tn)
1796         op_t    op;
1797         tspec_t nt;
1798         type_t  *tp;
1799         tnode_t *tn;
1800 {
1801         if (tn->tn_op == CON)
1802                 return;
1803
1804         if (op != CVT) {
1805                 /* We got already an error. */
1806                 return;
1807         }
1808
1809         if (psize(nt) < psize(PTR)) {
1810                 if (pflag && size(nt) >= size(PTR)) {
1811                         /* conv. of pointer to %s may lose bits */
1812                         warning(134, tyname(tp));
1813                 } else {
1814                         /* conv. of pointer to %s loses bits */
1815                         warning(133, tyname(tp));
1816                 }
1817         }
1818 }
1819
1820 /*
1821  * Print warnings for questionable pointer conversions.
1822  */
1823 static void
1824 ppconv(op, tn, tp)
1825         op_t    op;
1826         tnode_t *tn;
1827         type_t  *tp;
1828 {
1829         tspec_t nt, ot;
1830         const   char *nts, *ots;
1831
1832         /*
1833          * We got already an error (pointers of different types
1834          * without a cast) or we will not get a warning.
1835          */
1836         if (op != CVT)
1837                 return;
1838
1839         nt = tp->t_subt->t_tspec;
1840         ot = tn->tn_type->t_subt->t_tspec;
1841
1842         if (nt == VOID || ot == VOID) {
1843                 if (sflag && (nt == FUNC || ot == FUNC)) {
1844                         /* (void *)0 already handled in convert() */
1845                         *(nt == FUNC ? &nts : &ots) = "function pointer";
1846                         *(nt == VOID ? &nts : &ots) = "'void *'";
1847                         /* ANSI C forbids conversion of %s to %s */
1848                         warning(303, ots, nts);
1849                 }
1850                 return;
1851         } else if (nt == FUNC && ot == FUNC) {
1852                 return;
1853         } else if (nt == FUNC || ot == FUNC) {
1854                 /* questionable conversion of function pointer */
1855                 warning(229);
1856                 return;
1857         }
1858         
1859         if (getbound(tp->t_subt) > getbound(tn->tn_type->t_subt)) {
1860                 if (hflag)
1861                         /* possible pointer alignment problem */
1862                         warning(135);
1863         }
1864         if (((nt == STRUCT || nt == UNION) &&
1865              tp->t_subt->t_str != tn->tn_type->t_subt->t_str) ||
1866             psize(nt) != psize(ot)) {
1867                 if (cflag) {
1868                         /* pointer casts may be troublesome */
1869                         warning(247);
1870                 }
1871         }
1872 }
1873
1874 /*
1875  * Converts a typed constant in a constant of another type.
1876  *
1877  * op           operator which requires conversion
1878  * arg          if op is FARG, # of argument
1879  * tp           type in which to convert the constant
1880  * nv           new constant
1881  * v            old constant
1882  */
1883 void
1884 cvtcon(op, arg, tp, nv, v)
1885         op_t    op;
1886         int     arg;
1887         type_t  *tp;
1888         val_t   *nv, *v;
1889 {
1890         tspec_t ot, nt;
1891         ldbl_t  max, min;
1892         int     sz, rchk;
1893         quad_t  xmask, xmsk1;
1894         int     osz, nsz;
1895
1896         ot = v->v_tspec;
1897         nt = nv->v_tspec = tp->t_tspec;
1898         rchk = 0;
1899
1900         if (ot == FLOAT || ot == DOUBLE || ot == LDOUBLE) {
1901                 switch (nt) {
1902                 case CHAR:
1903                         max = CHAR_MAX;         min = CHAR_MIN;         break;
1904                 case UCHAR:
1905                         max = UCHAR_MAX;        min = 0;                break;
1906                 case SCHAR:
1907                         max = SCHAR_MAX;        min = SCHAR_MIN;        break;
1908                 case SHORT:
1909                         max = SHRT_MAX;         min = SHRT_MIN;         break;
1910                 case USHORT:
1911                         max = USHRT_MAX;        min = 0;                break;
1912                 case ENUM:
1913                 case INT:
1914                         max = INT_MAX;          min = INT_MIN;          break;
1915                 case UINT:
1916                         max = (u_int)UINT_MAX;  min = 0;                break;
1917                 case LONG:
1918                         max = LONG_MAX;         min = LONG_MIN;         break;
1919                 case ULONG:
1920                         max = (u_long)ULONG_MAX; min = 0;               break;
1921                 case QUAD:
1922                         max = QUAD_MAX;         min = QUAD_MIN;         break;
1923                 case UQUAD:
1924                         max = (u_quad_t)UQUAD_MAX; min = 0;             break;
1925                 case FLOAT:
1926                         max = FLT_MAX;          min = -FLT_MAX;         break;
1927                 case DOUBLE:
1928                         max = DBL_MAX;          min = -DBL_MAX;         break;
1929                 case PTR:
1930                         /* Got already an error because of float --> ptr */
1931                 case LDOUBLE:
1932                         max = LDBL_MAX;         min = -LDBL_MAX;        break;
1933                 default:
1934                         lerror("cvtcon() 1");
1935                 }
1936                 if (v->v_ldbl > max || v->v_ldbl < min) {
1937                         if (nt == LDOUBLE)
1938                                 lerror("cvtcon() 2");
1939                         if (op == FARG) {
1940                                 /* conv. of %s to %s is out of rng., arg #%d */
1941                                 warning(295, tyname(gettyp(ot)), tyname(tp),
1942                                         arg);
1943                         } else {
1944                                 /* conversion of %s to %s is out of range */
1945                                 warning(119, tyname(gettyp(ot)), tyname(tp));
1946                         }
1947                         v->v_ldbl = v->v_ldbl > 0 ? max : min;
1948                 }
1949                 if (nt == FLOAT) {
1950                         nv->v_ldbl = (float)v->v_ldbl;
1951                 } else if (nt == DOUBLE) {
1952                         nv->v_ldbl = (double)v->v_ldbl;
1953                 } else if (nt == LDOUBLE) {
1954                         nv->v_ldbl = v->v_ldbl;
1955                 } else {
1956                         nv->v_quad = (nt == PTR || isutyp(nt)) ?
1957                                 (u_quad_t)v->v_ldbl : (quad_t)v->v_ldbl;
1958                 }
1959         } else {
1960                 if (nt == FLOAT) {
1961                         nv->v_ldbl = (ot == PTR || isutyp(ot)) ?
1962                                (float)(u_quad_t)v->v_quad : (float)v->v_quad;
1963                 } else if (nt == DOUBLE) {
1964                         nv->v_ldbl = (ot == PTR || isutyp(ot)) ?
1965                                (double)(u_quad_t)v->v_quad : (double)v->v_quad;
1966                 } else if (nt == LDOUBLE) {
1967                         nv->v_ldbl = (ot == PTR || isutyp(ot)) ?
1968                                (ldbl_t)(u_quad_t)v->v_quad : (ldbl_t)v->v_quad;
1969                 } else {
1970                         rchk = 1;               /* Check for lost precision. */
1971                         nv->v_quad = v->v_quad;
1972                 }
1973         }
1974
1975         if (v->v_ansiu && isftyp(nt)) {
1976                 /* ANSI C treats constant as unsigned */
1977                 warning(157);
1978                 v->v_ansiu = 0;
1979         } else if (v->v_ansiu && (isityp(nt) && !isutyp(nt) &&
1980                                   psize(nt) > psize(ot))) {
1981                 /* ANSI C treats constant as unsigned */
1982                 warning(157);
1983                 v->v_ansiu = 0;
1984         }
1985
1986         if (nt != FLOAT && nt != DOUBLE && nt != LDOUBLE) {
1987                 sz = tp->t_isfield ? tp->t_flen : size(nt);
1988                 nv->v_quad = xsign(nv->v_quad, nt, sz);
1989         }
1990         
1991         if (rchk && op != CVT) {
1992                 osz = size(ot);
1993                 nsz = tp->t_isfield ? tp->t_flen : size(nt);
1994                 xmask = qlmasks[nsz] ^ qlmasks[osz];
1995                 xmsk1 = qlmasks[nsz] ^ qlmasks[osz - 1];
1996                 /*
1997                  * For bitwise operations we are not interested in the
1998                  * value, but in the bits itself.
1999                  */
2000                 if (op == ORASS || op == OR || op == XOR) {
2001                         /*
2002                          * Print a warning if bits which were set are
2003                          * lost due to the conversion.
2004                          * This can happen with operator ORASS only.
2005                          */
2006                         if (nsz < osz && (v->v_quad & xmask) != 0) {
2007                                 /* constant truncated by conv., op %s */
2008                                 warning(306, modtab[op].m_name);
2009                         }
2010                 } else if (op == ANDASS || op == AND) {
2011                         /*
2012                          * Print a warning if additional bits are not all 1
2013                          * and the most significant bit of the old value is 1,
2014                          * or if at least one (but not all) removed bit was 0.
2015                          */
2016                         if (nsz > osz &&
2017                             (nv->v_quad & qbmasks[osz - 1]) != 0 &&
2018                             (nv->v_quad & xmask) != xmask) {
2019                                 /*
2020                                  * extra bits set to 0 in conversion
2021                                  * of '%s' to '%s', op %s
2022                                  */
2023                                 warning(309, tyname(gettyp(ot)),
2024                                         tyname(tp), modtab[op].m_name);
2025                         } else if (nsz < osz &&
2026                                    (v->v_quad & xmask) != xmask &&
2027                                    (v->v_quad & xmask) != 0) {
2028                                 /* const. truncated by conv., op %s */
2029                                 warning(306, modtab[op].m_name);
2030                         }
2031                 } else if ((nt != PTR && isutyp(nt)) &&
2032                            (ot != PTR && !isutyp(ot)) && v->v_quad < 0) {
2033                         if (op == ASSIGN) {
2034                                 /* assignment of negative constant to ... */
2035                                 warning(164);
2036                         } else if (op == INIT) {
2037                                 /* initialisation of unsigned with neg. ... */
2038                                 warning(221);
2039                         } else if (op == FARG) {
2040                                 /* conversion of neg. const. to ..., arg #%d */
2041                                 warning(296, arg);
2042                         } else if (modtab[op].m_comp) {
2043                                 /* we get this warning already in chkcomp() */
2044                         } else {
2045                                 /* conversion of negative constant to ... */
2046                                 warning(222);
2047                         }
2048                 } else if (nv->v_quad != v->v_quad && nsz <= osz &&
2049                            (v->v_quad & xmask) != 0 &&
2050                            (isutyp(ot) || (v->v_quad & xmsk1) != xmsk1)) {
2051                         /*
2052                          * Loss of significant bit(s). All truncated bits
2053                          * of unsigned types or all truncated bits plus the
2054                          * msb of the target for signed types are considered
2055                          * to be significant bits. Loss of significant bits
2056                          * means that at least on of the bits was set in an
2057                          * unsigned type or that at least one, but not all of
2058                          * the bits was set in an signed type.
2059                          * Loss of significant bits means that it is not
2060                          * possible, also not with necessary casts, to convert
2061                          * back to the original type. A example for a
2062                          * necessary cast is:
2063                          *      char c; int     i; c = 128;
2064                          *      i = c;                  ** yields -128 **
2065                          *      i = (unsigned char)c;   ** yields 128 **
2066                          */
2067                         if (op == ASSIGN && tp->t_isfield) {
2068                                 /* precision lost in bit-field assignment */
2069                                 warning(166);
2070                         } else if (op == ASSIGN) {
2071                                 /* constant truncated by assignment */
2072                                 warning(165);
2073                         } else if (op == INIT && tp->t_isfield) {
2074                                 /* bit-field initializer does not fit */
2075                                 warning(180);
2076                         } else if (op == INIT) {
2077                                 /* initializer does not fit */
2078                                 warning(178);
2079                         } else if (op == CASE) {
2080                                 /* case label affected by conversion */
2081                                 warning(196);
2082                         } else if (op == FARG) {
2083                                 /* conv. of %s to %s is out of rng., arg #%d */
2084                                 warning(295, tyname(gettyp(ot)), tyname(tp),
2085                                         arg);
2086                         } else {
2087                                 /* conversion of %s to %s is out of range */
2088                                 warning(119, tyname(gettyp(ot)), tyname(tp));
2089                         }
2090                 } else if (nv->v_quad != v->v_quad) {
2091                         if (op == ASSIGN && tp->t_isfield) {
2092                                 /* precision lost in bit-field assignment */
2093                                 warning(166);
2094                         } else if (op == INIT && tp->t_isfield) {
2095                                 /* bit-field initializer out of range */
2096                                 warning(11);
2097                         } else if (op == CASE) {
2098                                 /* case label affected by conversion */
2099                                 warning(196);
2100                         } else if (op == FARG) {
2101                                 /* conv. of %s to %s is out of rng., arg #%d */
2102                                 warning(295, tyname(gettyp(ot)), tyname(tp),
2103                                         arg);
2104                         } else {
2105                                 /* conversion of %s to %s is out of range */
2106                                 warning(119, tyname(gettyp(ot)), tyname(tp));
2107                         }
2108                 }
2109         }
2110 }
2111
2112 /*
2113  * Called if incompatible types were detected.
2114  * Prints a appropriate warning.
2115  */
2116 static void
2117 incompat(op, lt, rt)
2118         op_t    op;
2119         tspec_t lt, rt;
2120 {
2121         mod_t   *mp;
2122
2123         mp = &modtab[op];
2124
2125         if (lt == VOID || (mp->m_binary && rt == VOID)) {
2126                 /* void type illegal in expression */
2127                 error(109);
2128         } else if (op == ASSIGN) {
2129                 if ((lt == STRUCT || lt == UNION) &&
2130                     (rt == STRUCT || rt == UNION)) {
2131                         /* assignment of different structures */
2132                         error(240);
2133                 } else {
2134                         /* assignment type mismatch */
2135                         error(171);
2136                 }
2137         } else if (mp->m_binary) {
2138                 /* operands of %s have incompatible types */
2139                 error(107, mp->m_name);
2140         } else {
2141                 /* operand of %s has incompatible type */
2142                 error(108, mp->m_name);
2143         }
2144 }
2145
2146 /*
2147  * Called if incompatible pointer types are detected.
2148  * Print an appropriate warning.
2149  */
2150 static void
2151 illptrc(mp, ltp, rtp)
2152         mod_t   *mp;
2153         type_t  *ltp, *rtp;
2154 {
2155         tspec_t lt, rt;
2156
2157         if (ltp->t_tspec != PTR || rtp->t_tspec != PTR)
2158                 lerror("illptrc() 1");
2159
2160         lt = ltp->t_subt->t_tspec;
2161         rt = rtp->t_subt->t_tspec;
2162
2163         if ((lt == STRUCT || lt == UNION) && (rt == STRUCT || rt == UNION)) {
2164                 if (mp == NULL) {
2165                         /* illegal structure pointer combination */
2166                         warning(244);
2167                 } else {
2168                         /* illegal structure pointer combination, op %s */
2169                         warning(245, mp->m_name);
2170                 }
2171         } else {
2172                 if (mp == NULL) {
2173                         /* illegal pointer combination */
2174                         warning(184);
2175                 } else {
2176                         /* illegal pointer combination, op %s */
2177                         warning(124, mp->m_name);
2178                 }
2179         }
2180 }
2181
2182 /*
2183  * Make sure type (*tpp)->t_subt has at least the qualifiers
2184  * of tp1->t_subt and tp2->t_subt.
2185  */
2186 static void
2187 mrgqual(tpp, tp1, tp2)
2188         type_t  **tpp, *tp1, *tp2;
2189 {
2190         if ((*tpp)->t_tspec != PTR ||
2191             tp1->t_tspec != PTR || tp2->t_tspec != PTR) {
2192                 lerror("mrgqual()");
2193         }
2194
2195         if ((*tpp)->t_subt->t_const ==
2196             (tp1->t_subt->t_const | tp2->t_subt->t_const) &&
2197             (*tpp)->t_subt->t_volatile ==
2198             (tp1->t_subt->t_volatile | tp2->t_subt->t_volatile)) {
2199                 return;
2200         }
2201
2202         *tpp = tduptyp(*tpp);
2203         (*tpp)->t_subt = tduptyp((*tpp)->t_subt);
2204         (*tpp)->t_subt->t_const =
2205                 tp1->t_subt->t_const | tp2->t_subt->t_const;
2206         (*tpp)->t_subt->t_volatile =
2207                 tp1->t_subt->t_volatile | tp2->t_subt->t_volatile;
2208 }
2209
2210 /*
2211  * Returns 1 if the given structure or union has a constant member
2212  * (maybe recursively).
2213  */
2214 static int
2215 conmemb(tp)
2216         type_t  *tp;
2217 {
2218         sym_t   *m;
2219         tspec_t t;
2220
2221         if ((t = tp->t_tspec) != STRUCT && t != UNION)
2222                 lerror("conmemb()");
2223         for (m = tp->t_str->memb; m != NULL; m = m->s_nxt) {
2224                 tp = m->s_type;
2225                 if (tp->t_const)
2226                         return (1);
2227                 if ((t = tp->t_tspec) == STRUCT || t == UNION) {
2228                         if (conmemb(m->s_type))
2229                                 return (1);
2230                 }
2231         }
2232         return (0);
2233 }
2234
2235 const char *
2236 tyname(tp)
2237         type_t  *tp;
2238 {
2239         tspec_t t;
2240         const   char *s;
2241
2242         if ((t = tp->t_tspec) == INT && tp->t_isenum)
2243                 t = ENUM;
2244
2245         switch (t) {
2246         case CHAR:      s = "char";                     break;
2247         case UCHAR:     s = "unsigned char";            break;
2248         case SCHAR:     s = "signed char";              break;
2249         case SHORT:     s = "short";                    break;
2250         case USHORT:    s = "unsigned short";           break;
2251         case INT:       s = "int";                      break;
2252         case UINT:      s = "unsigned int";             break;
2253         case LONG:      s = "long";                     break;
2254         case ULONG:     s = "unsigned long";            break;
2255         case QUAD:      s = "long long";                break;
2256         case UQUAD:     s = "unsigned long long";       break;
2257         case FLOAT:     s = "float";                    break;
2258         case DOUBLE:    s = "double";                   break;
2259         case LDOUBLE:   s = "long double";              break;
2260         case PTR:       s = "pointer";                  break;
2261         case ENUM:      s = "enum";                     break;
2262         case STRUCT:    s = "struct";                   break;
2263         case UNION:     s = "union";                    break;
2264         case FUNC:      s = "function";                 break;
2265         case ARRAY:     s = "array";                    break;
2266         default:
2267                 lerror("tyname()");
2268         }
2269         return (s);
2270 }
2271
2272 /*
2273  * Create a new node for one of the operators POINT and ARROW.
2274  */
2275 static tnode_t *
2276 bldstr(op, ln, rn)
2277         op_t    op;
2278         tnode_t *ln, *rn;
2279 {
2280         tnode_t *ntn, *ctn;
2281         int     nolval;
2282
2283         if (rn->tn_op != NAME)
2284                 lerror("bldstr() 1");
2285         if (rn->tn_sym->s_value.v_tspec != INT)
2286                 lerror("bldstr() 2");
2287         if (rn->tn_sym->s_scl != MOS && rn->tn_sym->s_scl != MOU)
2288                 lerror("bldstr() 3");
2289
2290         /*
2291          * Remember if the left operand is an lvalue (structure members
2292          * are lvalues if and only if the structure itself is an lvalue).
2293          */
2294         nolval = op == POINT && !ln->tn_lvalue;
2295
2296         if (op == POINT) {
2297                 ln = bldamper(ln, 1);
2298         } else if (ln->tn_type->t_tspec != PTR) {
2299                 if (!tflag || !isityp(ln->tn_type->t_tspec))
2300                         lerror("bldstr() 4");
2301                 ln = convert(NOOP, 0, tincref(gettyp(VOID), PTR), ln);
2302         }
2303
2304 #if PTRDIFF_IS_LONG
2305         ctn = getinode(LONG, rn->tn_sym->s_value.v_quad / CHAR_BIT);
2306 #else
2307         ctn = getinode(INT, rn->tn_sym->s_value.v_quad / CHAR_BIT);
2308 #endif
2309
2310         ntn = mktnode(PLUS, tincref(rn->tn_type, PTR), ln, ctn);
2311         if (ln->tn_op == CON)
2312                 ntn = fold(ntn);
2313
2314         if (rn->tn_type->t_isfield) {
2315                 ntn = mktnode(FSEL, ntn->tn_type->t_subt, ntn, NULL);
2316         } else {
2317                 ntn = mktnode(STAR, ntn->tn_type->t_subt, ntn, NULL);
2318         }
2319
2320         if (nolval)
2321                 ntn->tn_lvalue = 0;
2322
2323         return (ntn);
2324 }
2325
2326 /*
2327  * Create a node for INCAFT, INCBEF, DECAFT and DECBEF.
2328  */
2329 static tnode_t *
2330 bldincdec(op, ln)
2331         op_t    op;
2332         tnode_t *ln;
2333 {
2334         tnode_t *cn, *ntn;
2335
2336         if (ln == NULL)
2337                 lerror("bldincdec() 1");
2338
2339         if (ln->tn_type->t_tspec == PTR) {
2340                 cn = plength(ln->tn_type);
2341         } else {
2342                 cn = getinode(INT, (quad_t)1);
2343         }
2344         ntn = mktnode(op, ln->tn_type, ln, cn);
2345
2346         return (ntn);
2347 }
2348
2349 /*
2350  * Create a tree node for the & operator
2351  */
2352 static tnode_t *
2353 bldamper(tn, noign)
2354         tnode_t *tn;
2355         int     noign;
2356 {
2357         tnode_t *ntn;
2358         tspec_t t;
2359         
2360         if (!noign && ((t = tn->tn_type->t_tspec) == ARRAY || t == FUNC)) {
2361                 /* & before array or function: ignored */
2362                 if (tflag)
2363                         warning(127);
2364                 return (tn);
2365         }
2366
2367         /* eliminate &* */
2368         if (tn->tn_op == STAR &&
2369             tn->tn_left->tn_type->t_tspec == PTR &&
2370             tn->tn_left->tn_type->t_subt == tn->tn_type) {
2371                 return (tn->tn_left);
2372         }
2373             
2374         ntn = mktnode(AMPER, tincref(tn->tn_type, PTR), tn, NULL);
2375
2376         return (ntn);
2377 }
2378
2379 /*
2380  * Create a node for operators PLUS and MINUS.
2381  */
2382 static tnode_t *
2383 bldplmi(op, ln, rn)
2384         op_t    op;
2385         tnode_t *ln, *rn;
2386 {
2387         tnode_t *ntn, *ctn;
2388         type_t  *tp;
2389
2390         /* If pointer and integer, then pointer to the lhs. */
2391         if (rn->tn_type->t_tspec == PTR && isityp(ln->tn_type->t_tspec)) {
2392                 ntn = ln;
2393                 ln = rn;
2394                 rn = ntn;
2395         }
2396
2397         if (ln->tn_type->t_tspec == PTR && rn->tn_type->t_tspec != PTR) {
2398
2399                 if (!isityp(rn->tn_type->t_tspec))
2400                         lerror("bldplmi() 1");
2401
2402                 ctn = plength(ln->tn_type);
2403                 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
2404                         rn = convert(NOOP, 0, ctn->tn_type, rn);
2405                 rn = mktnode(MULT, rn->tn_type, rn, ctn);
2406                 if (rn->tn_left->tn_op == CON)
2407                         rn = fold(rn);
2408                 ntn = mktnode(op, ln->tn_type, ln, rn);
2409
2410         } else if (rn->tn_type->t_tspec == PTR) {
2411
2412                 if (ln->tn_type->t_tspec != PTR || op != MINUS)
2413                         lerror("bldplmi() 2");
2414 #if PTRDIFF_IS_LONG
2415                 tp = gettyp(LONG);
2416 #else
2417                 tp = gettyp(INT);
2418 #endif
2419                 ntn = mktnode(op, tp, ln, rn);
2420                 if (ln->tn_op == CON && rn->tn_op == CON)
2421                         ntn = fold(ntn);
2422                 ctn = plength(ln->tn_type);
2423                 balance(NOOP, &ntn, &ctn);
2424                 ntn = mktnode(DIV, tp, ntn, ctn);
2425
2426         } else {
2427
2428                 ntn = mktnode(op, ln->tn_type, ln, rn);
2429
2430         }
2431         return (ntn);
2432 }
2433
2434 /*
2435  * Create a node for operators SHL and SHR.
2436  */
2437 static tnode_t *
2438 bldshft(op, ln, rn)
2439         op_t    op;
2440         tnode_t *ln, *rn;
2441 {
2442         tspec_t t;
2443         tnode_t *ntn;
2444
2445         if ((t = rn->tn_type->t_tspec) != INT && t != UINT)
2446                 rn = convert(CVT, 0, gettyp(INT), rn);
2447         ntn = mktnode(op, ln->tn_type, ln, rn);
2448         return (ntn);
2449 }
2450
2451 /*
2452  * Create a node for COLON.
2453  */
2454 static tnode_t *
2455 bldcol(ln, rn)
2456         tnode_t *ln, *rn;
2457 {
2458         tspec_t lt, rt, pdt;
2459         type_t  *rtp;
2460         tnode_t *ntn;
2461
2462         lt = ln->tn_type->t_tspec;
2463         rt = rn->tn_type->t_tspec;
2464 #if PTRDIFF_IS_LONG
2465         pdt = LONG;
2466 #else
2467         pdt = INT;
2468 #endif
2469
2470         /*
2471          * Arithmetic types are balanced, all other type combinations
2472          * still need to be handled.
2473          */
2474         if (isatyp(lt) && isatyp(rt)) {
2475                 rtp = ln->tn_type;
2476         } else if (lt == VOID || rt == VOID) {
2477                 rtp = gettyp(VOID);
2478         } else if (lt == STRUCT || lt == UNION) {
2479                 /* Both types must be identical. */
2480                 if (rt != STRUCT && rt != UNION)
2481                         lerror("bldcol() 1");
2482                 if (ln->tn_type->t_str != rn->tn_type->t_str)
2483                         lerror("bldcol() 2");
2484                 if (incompl(ln->tn_type)) {
2485                         /* unknown operand size, op %s */
2486                         error(138, modtab[COLON].m_name);
2487                         return (NULL);
2488                 }
2489                 rtp = ln->tn_type;
2490         } else if (lt == PTR && isityp(rt)) {
2491                 if (rt != pdt) {
2492                         rn = convert(NOOP, 0, gettyp(pdt), rn);
2493                         rt = pdt;
2494                 }
2495                 rtp = ln->tn_type;
2496         } else if (rt == PTR && isityp(lt)) {
2497                 if (lt != pdt) {
2498                         ln = convert(NOOP, 0, gettyp(pdt), ln);
2499                         lt = pdt;
2500                 }
2501                 rtp = rn->tn_type;
2502         } else if (lt == PTR && ln->tn_type->t_subt->t_tspec == VOID) {
2503                 if (rt != PTR)
2504                         lerror("bldcol() 4");
2505                 rtp = ln->tn_type;
2506                 mrgqual(&rtp, ln->tn_type, rn->tn_type);
2507         } else if (rt == PTR && rn->tn_type->t_subt->t_tspec == VOID) {
2508                 if (lt != PTR)
2509                         lerror("bldcol() 5");
2510                 rtp = rn->tn_type;
2511                 mrgqual(&rtp, ln->tn_type, rn->tn_type);
2512         } else {
2513                 if (lt != PTR || rt != PTR)
2514                         lerror("bldcol() 6");
2515                 /*
2516                  * XXX For now we simply take the left type. This is
2517                  * probably wrong, if one type contains a functionprototype
2518                  * and the other one, at the same place, only an old style
2519                  * declaration.
2520                  */
2521                 rtp = ln->tn_type;
2522                 mrgqual(&rtp, ln->tn_type, rn->tn_type);
2523         }
2524
2525         ntn = mktnode(COLON, rtp, ln, rn);
2526
2527         return (ntn);
2528 }
2529
2530 /*
2531  * Create a node for an assignment operator (both = and op= ).
2532  */
2533 static tnode_t *
2534 bldasgn(op, ln, rn)
2535         op_t    op;
2536         tnode_t *ln, *rn;
2537 {
2538         tspec_t lt, rt;
2539         tnode_t *ntn, *ctn;
2540
2541         if (ln == NULL || rn == NULL)
2542                 lerror("bldasgn() 1");
2543
2544         lt = ln->tn_type->t_tspec;
2545         rt = rn->tn_type->t_tspec;
2546
2547         if ((op == ADDASS || op == SUBASS) && lt == PTR) {
2548                 if (!isityp(rt))
2549                         lerror("bldasgn() 2");
2550                 ctn = plength(ln->tn_type);
2551                 if (rn->tn_type->t_tspec != ctn->tn_type->t_tspec)
2552                         rn = convert(NOOP, 0, ctn->tn_type, rn);
2553                 rn = mktnode(MULT, rn->tn_type, rn, ctn);
2554                 if (rn->tn_left->tn_op == CON)
2555                         rn = fold(rn);
2556         }
2557
2558         if ((op == ASSIGN || op == RETURN) && (lt == STRUCT || rt == STRUCT)) {
2559                 if (rt != lt || ln->tn_type->t_str != rn->tn_type->t_str)
2560                         lerror("bldasgn() 3");
2561                 if (incompl(ln->tn_type)) {
2562                         if (op == RETURN) {
2563                                 /* cannot return incomplete type */
2564                                 error(212);
2565                         } else {
2566                                 /* unknown operand size, op %s */
2567                                 error(138, modtab[op].m_name);
2568                         }
2569                         return (NULL);
2570                 }
2571         }
2572
2573         if (op == SHLASS || op == SHRASS) {
2574                 if (rt != INT) {
2575                         rn = convert(NOOP, 0, gettyp(INT), rn);
2576                         rt = INT;
2577                 }
2578         } else {
2579                 if (op == ASSIGN || lt != PTR) {
2580                         if (lt != rt ||
2581                             (ln->tn_type->t_isfield && rn->tn_op == CON)) {
2582                                 rn = convert(op, 0, ln->tn_type, rn);
2583                                 rt = lt;
2584                         }
2585                 }
2586         }
2587
2588         ntn = mktnode(op, ln->tn_type, ln, rn);
2589
2590         return (ntn);
2591 }
2592
2593 /*
2594  * Get length of type tp->t_subt.
2595  */
2596 static tnode_t *
2597 plength(tp)
2598         type_t  *tp;
2599 {
2600         int     elem, elsz;
2601         tspec_t st;
2602
2603         if (tp->t_tspec != PTR)
2604                 lerror("plength() 1");
2605         tp = tp->t_subt;
2606
2607         elem = 1;
2608         elsz = 0;
2609
2610         while (tp->t_tspec == ARRAY) {
2611                 elem *= tp->t_dim;
2612                 tp = tp->t_subt;
2613         }
2614
2615         switch (tp->t_tspec) {
2616         case FUNC:
2617                 /* pointer to function is not allowed here */
2618                 error(110);
2619                 break;
2620         case VOID:
2621                 /* cannot do pointer arithmetic on operand of ... */
2622                 (void)gnuism(136);
2623                 break;
2624         case STRUCT:
2625         case UNION:
2626                 if ((elsz = tp->t_str->size) == 0)
2627                         /* cannot do pointer arithmetic on operand of ... */
2628                         error(136);
2629                 break;
2630         case ENUM:
2631                 if (incompl(tp)) {
2632                         /* cannot do pointer arithmetic on operand of ... */
2633                         warning(136);
2634                 }
2635                 /* FALLTHROUGH */
2636         default:
2637                 if ((elsz = size(tp->t_tspec)) == 0) {
2638                         /* cannot do pointer arithmetic on operand of ... */
2639                         error(136);
2640                 } else if (elsz == -1) {
2641                         lerror("plength() 2");
2642                 }
2643                 break;
2644         }
2645
2646         if (elem == 0 && elsz != 0) {
2647                 /* cannot do pointer arithmetic on operand of ... */
2648                 error(136);
2649         }
2650
2651         if (elsz == 0)
2652                 elsz = CHAR_BIT;
2653
2654 #if PTRDIFF_IS_LONG
2655         st = LONG;
2656 #else
2657         st = INT;
2658 #endif
2659
2660         return (getinode(st, (quad_t)(elem * elsz / CHAR_BIT)));
2661 }
2662
2663 #ifdef XXX_BROKEN_GCC
2664 static int
2665 quad_t_eq(x, y)
2666         quad_t x, y;
2667 {
2668         return (x == y);
2669 }
2670
2671 static int
2672 u_quad_t_eq(x, y)
2673         u_quad_t x, y;
2674 {
2675         return (x == y);
2676 }
2677 #endif
2678
2679 /*
2680  * Do only as much as necessary to compute constant expressions.
2681  * Called only if the operator allows folding and (both) operands
2682  * are constants.
2683  */
2684 static tnode_t *
2685 fold(tn)
2686         tnode_t *tn;
2687 {
2688         val_t   *v;
2689         tspec_t t;
2690         int     utyp, ovfl;
2691         quad_t  sl, sr, q, mask;
2692         u_quad_t ul, ur;
2693         tnode_t *cn;
2694
2695         v = xcalloc(1, sizeof (val_t));
2696         v->v_tspec = t = tn->tn_type->t_tspec;
2697
2698         utyp = t == PTR || isutyp(t);
2699         ul = sl = tn->tn_left->tn_val->v_quad;
2700         if (modtab[tn->tn_op].m_binary)
2701                 ur = sr = tn->tn_right->tn_val->v_quad;
2702
2703         ovfl = 0;
2704
2705         switch (tn->tn_op) {
2706         case UPLUS:
2707                 q = sl;
2708                 break;
2709         case UMINUS:
2710                 q = -sl;
2711                 if (msb(q, t, -1) == msb(sl, t, -1))
2712                         ovfl = 1;
2713                 break;
2714         case COMPL:
2715                 q = ~sl;
2716                 break;
2717         case MULT:
2718                 q = utyp ? ul * ur : sl * sr;
2719                 if (msb(q, t, -1) != (msb(sl, t, -1) ^ msb(sr, t, -1)))
2720                         ovfl = 1;
2721                 break;
2722         case DIV:
2723                 if (sr == 0) {
2724                         /* division by 0 */
2725                         error(139);
2726                         q = utyp ? UQUAD_MAX : QUAD_MAX;
2727                 } else {
2728                         q = utyp ? ul / ur : sl / sr;
2729                 }
2730                 break;
2731         case MOD:
2732                 if (sr == 0) {
2733                         /* modulus by 0 */
2734                         error(140);
2735                         q = 0;
2736                 } else {
2737                         q = utyp ? ul % ur : sl % sr;
2738                 }
2739                 break;
2740         case PLUS:
2741                 q = utyp ? ul + ur : sl + sr;
2742                 if (msb(sl, t, -1)  != 0 && msb(sr, t, -1) != 0) {
2743                         if (msb(q, t, -1) == 0)
2744                                 ovfl = 1;
2745                 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) == 0) {
2746                         if (msb(q, t, -1) != 0)
2747                                 ovfl = 1;
2748                 }
2749                 break;
2750         case MINUS:
2751                 q = utyp ? ul - ur : sl - sr;
2752                 if (msb(sl, t, -1) != 0 && msb(sr, t, -1) == 0) {
2753                         if (msb(q, t, -1) == 0)
2754                                 ovfl = 1;
2755                 } else if (msb(sl, t, -1) == 0 && msb(sr, t, -1) != 0) {
2756                         if (msb(q, t, -1) != 0)
2757                                 ovfl = 1;
2758                 }
2759                 break;
2760         case SHL:
2761                 q = utyp ? ul << sr : sl << sr;
2762                 break;
2763         case SHR:
2764                 /*
2765                  * The sign must be explizitly extended because
2766                  * shifts of signed values are implementation dependent.
2767                  */
2768                 q = ul >> sr;
2769                 q = xsign(q, t, size(t) - (int)sr);
2770                 break;
2771         case LT:
2772                 q = utyp ? ul < ur : sl < sr;
2773                 break;
2774         case LE:
2775                 q = utyp ? ul <= ur : sl <= sr;
2776                 break;
2777         case GE:
2778                 q = utyp ? ul >= ur : sl >= sr;
2779                 break;
2780         case GT:
2781                 q = utyp ? ul > ur : sl > sr;
2782                 break;
2783         case EQ:
2784 #ifdef XXX_BROKEN_GCC
2785                 q = utyp ? u_quad_t_eq(ul, ur) : quad_t_eq(sl, sr);
2786 #else
2787                 q = utyp ? ul == ur : sl == sr;
2788 #endif
2789                 break;
2790         case NE:
2791                 q = utyp ? ul != ur : sl != sr;
2792                 break;
2793         case AND:
2794                 q = utyp ? ul & ur : sl & sr;
2795                 break;
2796         case XOR:
2797                 q = utyp ? ul ^ ur : sl ^ sr;
2798                 break;
2799         case OR:
2800                 q = utyp ? ul | ur : sl | sr;
2801                 break;
2802         default:
2803                 lerror("fold() 5");
2804         }
2805
2806         mask = qlmasks[size(t)];
2807
2808         /* XXX does not work for quads. */
2809         if (ovfl || ((q | mask) != ~(u_quad_t)0 && (q & ~mask) != 0)) {
2810                 if (hflag)
2811                         /* integer overflow detected, op %s */
2812                         warning(141, modtab[tn->tn_op].m_name);
2813         }
2814
2815         v->v_quad = xsign(q, t, -1);
2816
2817         cn = getcnode(tn->tn_type, v);
2818
2819         return (cn);
2820 }
2821
2822 #ifdef XXX_BROKEN_GCC
2823 int
2824 ldbl_t_neq(x, y)
2825         ldbl_t x, y;
2826 {
2827         return (x != y);
2828 }
2829 #endif
2830
2831 /*
2832  * Same for operators whose operands are compared with 0 (test context).
2833  */
2834 static tnode_t *
2835 foldtst(tn)
2836         tnode_t *tn;
2837 {
2838         int     l, r;
2839         val_t   *v;
2840
2841         v = xcalloc(1, sizeof (val_t));
2842         v->v_tspec = tn->tn_type->t_tspec;
2843         if (tn->tn_type->t_tspec != INT)
2844                 lerror("foldtst() 1");
2845
2846         if (isftyp(tn->tn_left->tn_type->t_tspec)) {
2847 #ifdef XXX_BROKEN_GCC
2848                 l = ldbl_t_neq(tn->tn_left->tn_val->v_ldbl, 0.0);
2849 #else
2850                 l = tn->tn_left->tn_val->v_ldbl != 0.0;
2851 #endif
2852         } else {
2853                 l = tn->tn_left->tn_val->v_quad != 0;
2854         }
2855
2856         if (modtab[tn->tn_op].m_binary) {
2857                 if (isftyp(tn->tn_right->tn_type->t_tspec)) {
2858 #ifdef XXX_BROKEN_GCC
2859                         r = ldbl_t_neq(tn->tn_right->tn_val->v_ldbl, 0.0);
2860 #else
2861                         r = tn->tn_right->tn_val->v_ldbl != 0.0;
2862 #endif
2863                 } else {
2864                         r = tn->tn_right->tn_val->v_quad != 0;
2865                 }
2866         }
2867
2868         switch (tn->tn_op) {
2869         case NOT:
2870                 if (hflag)
2871                         /* constant argument to NOT */
2872                         warning(239);
2873                 v->v_quad = !l;
2874                 break;
2875         case LOGAND:
2876                 v->v_quad = l && r;
2877                 break;
2878         case LOGOR:
2879                 v->v_quad = l || r;
2880                 break;
2881         default:
2882                 lerror("foldtst() 1");
2883         }
2884
2885         return (getcnode(tn->tn_type, v));
2886 }
2887
2888 /*
2889  * Same for operands with floating point type.
2890  */
2891 static tnode_t *
2892 foldflt(tn)
2893         tnode_t *tn;
2894 {
2895         val_t   *v;
2896         tspec_t t;
2897         ldbl_t  l, r;
2898
2899         v = xcalloc(1, sizeof (val_t));
2900         v->v_tspec = t = tn->tn_type->t_tspec;
2901
2902         if (!isftyp(t))
2903                 lerror("foldflt() 1");
2904
2905         if (t != tn->tn_left->tn_type->t_tspec)
2906                 lerror("foldflt() 2");
2907         if (modtab[tn->tn_op].m_binary && t != tn->tn_right->tn_type->t_tspec)
2908                 lerror("foldflt() 3");
2909
2910         l = tn->tn_left->tn_val->v_ldbl;
2911         if (modtab[tn->tn_op].m_binary)
2912                 r = tn->tn_right->tn_val->v_ldbl;
2913
2914         switch (tn->tn_op) {
2915         case UPLUS:
2916                 v->v_ldbl = l;
2917                 break;
2918         case UMINUS:
2919                 v->v_ldbl = -l;
2920                 break;
2921         case MULT:
2922                 v->v_ldbl = l * r;
2923                 break;
2924         case DIV:
2925                 if (r == 0.0) {
2926                         /* division by 0 */
2927                         error(139);
2928                         if (t == FLOAT) {
2929                                 v->v_ldbl = l < 0 ? -FLT_MAX : FLT_MAX;
2930                         } else if (t == DOUBLE) {
2931                                 v->v_ldbl = l < 0 ? -DBL_MAX : DBL_MAX;
2932                         } else {
2933                                 v->v_ldbl = l < 0 ? -LDBL_MAX : LDBL_MAX;
2934                         }
2935                 } else {
2936                         v->v_ldbl = l / r;
2937                 }
2938                 break;
2939         case PLUS:
2940                 v->v_ldbl = l + r;
2941                 break;
2942         case MINUS:
2943                 v->v_ldbl = l - r;
2944                 break;
2945         case LT:
2946                 v->v_quad = l < r;
2947                 break;
2948         case LE:
2949                 v->v_quad = l <= r;
2950                 break;
2951         case GE:
2952                 v->v_quad = l >= r;
2953                 break;
2954         case GT:
2955                 v->v_quad = l > r;
2956                 break;
2957         case EQ:
2958                 v->v_quad = l == r;
2959                 break;
2960         case NE:
2961                 v->v_quad = l != r;
2962                 break;
2963         default:
2964                 lerror("foldflt() 4");
2965         }
2966
2967         if (isnan((double)v->v_ldbl))
2968                 lerror("foldflt() 5");
2969         if (isinf((double)v->v_ldbl) ||
2970             (t == FLOAT &&
2971              (v->v_ldbl > FLT_MAX || v->v_ldbl < -FLT_MAX)) ||
2972             (t == DOUBLE &&
2973              (v->v_ldbl > DBL_MAX || v->v_ldbl < -DBL_MAX))) {
2974                 /* floating point overflow detected, op %s */
2975                 warning(142, modtab[tn->tn_op].m_name);
2976                 if (t == FLOAT) {
2977                         v->v_ldbl = v->v_ldbl < 0 ? -FLT_MAX : FLT_MAX;
2978                 } else if (t == DOUBLE) {
2979                         v->v_ldbl = v->v_ldbl < 0 ? -DBL_MAX : DBL_MAX;
2980                 } else {
2981                         v->v_ldbl = v->v_ldbl < 0 ? -LDBL_MAX: LDBL_MAX;
2982                 }
2983         }
2984
2985         return (getcnode(tn->tn_type, v));
2986 }
2987
2988 /*
2989  * Create a constant node for sizeof.
2990  */
2991 tnode_t *
2992 bldszof(tp)
2993         type_t  *tp;
2994 {
2995         int     elem, elsz;
2996         tspec_t st;
2997
2998         elem = 1;
2999         while (tp->t_tspec == ARRAY) {
3000                 elem *= tp->t_dim;
3001                 tp = tp->t_subt;
3002         }
3003         if (elem == 0) {
3004                 /* cannot take size of incomplete type */
3005                 error(143);
3006                 elem = 1;
3007         }
3008         switch (tp->t_tspec) {
3009         case FUNC:
3010                 /* cannot take size of function */
3011                 error(144);
3012                 elsz = 1;
3013                 break;
3014         case STRUCT:
3015         case UNION:
3016                 if (incompl(tp)) {
3017                         /* cannot take size of incomplete type */
3018                         error(143);
3019                         elsz = 1;
3020                 } else {
3021                         elsz = tp->t_str->size;
3022                 }
3023                 break;
3024         case ENUM:
3025                 if (incompl(tp)) {
3026                         /* cannot take size of incomplete type */
3027                         warning(143);
3028                 }
3029                 /* FALLTHROUGH */
3030         default:
3031                 if (tp->t_isfield) {
3032                         /* cannot take size of bit-field */
3033                         error(145);
3034                 }
3035                 if (tp->t_tspec == VOID) {
3036                         /* cannot take size of void */
3037                         error(146);
3038                         elsz = 1;
3039                 } else {
3040                         elsz = size(tp->t_tspec);
3041                         if (elsz <= 0)
3042                                 lerror("bldszof() 1");
3043                 }
3044                 break;
3045         }
3046
3047 #if SIZEOF_IS_ULONG
3048         st = ULONG;
3049 #else
3050         st = UINT;
3051 #endif
3052
3053         return (getinode(st, (quad_t)(elem * elsz / CHAR_BIT)));
3054 }
3055
3056 /*
3057  * Type casts.
3058  */
3059 tnode_t *
3060 cast(tn, tp)
3061         tnode_t *tn;
3062         type_t  *tp;
3063 {
3064         tspec_t nt, ot;
3065
3066         if (tn == NULL)
3067                 return (NULL);
3068
3069         tn = cconv(tn);
3070
3071         nt = tp->t_tspec;
3072         ot = tn->tn_type->t_tspec;
3073
3074         if (nt == VOID) {
3075                 /*
3076                  * XXX ANSI C requires scalar types or void (Plauger&Brodie).
3077                  * But this seams really questionable.
3078                  */
3079         } else if (nt == STRUCT || nt == UNION || nt == ARRAY || nt == FUNC) {
3080                 /* invalid cast expression */
3081                 error(147);
3082                 return (NULL);
3083         } else if (ot == STRUCT || ot == UNION) {
3084                 /* invalid cast expression */
3085                 error(147);
3086                 return (NULL);
3087         } else if (ot == VOID) {
3088                 /* improper cast of void expression */
3089                 error(148);
3090                 return (NULL);
3091         } else if (isityp(nt) && issclt(ot)) {
3092                 /* ok */
3093         } else if (isftyp(nt) && isatyp(ot)) {
3094                 /* ok */
3095         } else if (nt == PTR && isityp(ot)) {
3096                 /* ok */
3097         } else if (nt == PTR && ot == PTR) {
3098                 if (!tp->t_subt->t_const && tn->tn_type->t_subt->t_const) {
3099                         if (hflag)
3100                                 /* cast discards 'const' from ... */
3101                                 warning(275);
3102                 }
3103         } else {
3104                 /* invalid cast expression */
3105                 error(147);
3106                 return (NULL);
3107         }
3108
3109         tn = convert(CVT, 0, tp, tn);
3110         tn->tn_cast = 1;
3111
3112         return (tn);
3113 }
3114
3115 /*
3116  * Create the node for a function argument.
3117  * All necessary conversions and type checks are done in funccall(), because
3118  * in funcarg() we have no information about expected argument types.
3119  */
3120 tnode_t *
3121 funcarg(args, arg)
3122         tnode_t *args, *arg;
3123 {
3124         tnode_t *ntn;
3125
3126         /*
3127          * If there was a serious error in the expression for the argument,
3128          * create a dummy argument so the positions of the remaining arguments
3129          * will not change.
3130          */
3131         if (arg == NULL)
3132                 arg = getinode(INT, (quad_t)0);
3133
3134         ntn = mktnode(PUSH, arg->tn_type, arg, args);
3135
3136         return (ntn);
3137 }
3138
3139 /*
3140  * Create the node for a function call. Also check types of
3141  * function arguments and insert conversions, if necessary.
3142  */
3143 tnode_t *
3144 funccall(func, args)
3145         tnode_t *func, *args;
3146 {
3147         tnode_t *ntn;
3148         op_t    fcop;
3149
3150         if (func == NULL)
3151                 return (NULL);
3152
3153         if (func->tn_op == NAME && func->tn_type->t_tspec == FUNC) {
3154                 fcop = CALL;
3155         } else {
3156                 fcop = ICALL;
3157         }
3158
3159         /*
3160          * after cconv() func will always be a pointer to a function
3161          * if it is a valid function designator.
3162          */
3163         func = cconv(func);
3164
3165         if (func->tn_type->t_tspec != PTR ||
3166             func->tn_type->t_subt->t_tspec != FUNC) {
3167                 /* illegal function */
3168                 error(149);
3169                 return (NULL);
3170         }
3171
3172         args = chkfarg(func->tn_type->t_subt, args);
3173
3174         ntn = mktnode(fcop, func->tn_type->t_subt->t_subt, func, args);
3175
3176         return (ntn);
3177 }
3178
3179 /*
3180  * Check types of all function arguments and insert conversions,
3181  * if necessary.
3182  */
3183 static tnode_t *
3184 chkfarg(ftp, args)
3185         type_t  *ftp;           /* type of called function */
3186         tnode_t *args;          /* arguments */
3187 {
3188         tnode_t *arg;
3189         sym_t   *asym;
3190         tspec_t at;
3191         int     narg, npar, n, i;
3192
3193         /* get # of args in the prototype */
3194         npar = 0;
3195         for (asym = ftp->t_args; asym != NULL; asym = asym->s_nxt)
3196                 npar++;
3197
3198         /* get # of args in function call */
3199         narg = 0;
3200         for (arg = args; arg != NULL; arg = arg->tn_right)
3201                 narg++;
3202
3203         asym = ftp->t_args;
3204         if (ftp->t_proto && npar != narg && !(ftp->t_vararg && npar < narg)) {
3205                 /* argument mismatch: %d arg%s passed, %d expected */
3206                 error(150, narg, narg > 1 ? "s" : "", npar);
3207                 asym = NULL;
3208         }
3209         
3210         for (n = 1; n <= narg; n++) {
3211
3212                 /*
3213                  * The rightmost argument is at the top of the argument
3214                  * subtree.
3215                  */
3216                 for (i = narg, arg = args; i > n; i--, arg = arg->tn_right) ;
3217
3218                 /* some things which are always not allowd */
3219                 if ((at = arg->tn_left->tn_type->t_tspec) == VOID) {
3220                         /* void expressions may not be arguments, arg #%d */
3221                         error(151, n);
3222                         return (NULL);
3223                 } else if ((at == STRUCT || at == UNION) &&
3224                            incompl(arg->tn_left->tn_type)) {
3225                         /* argument cannot have unknown size, arg #%d */
3226                         error(152, n);
3227                         return (NULL);
3228                 } else if (isityp(at) && arg->tn_left->tn_type->t_isenum &&
3229                            incompl(arg->tn_left->tn_type)) {
3230                         /* argument cannot have unknown size, arg #%d */
3231                         warning(152, n);
3232                 }
3233
3234                 /* class conversions (arg in value context) */
3235                 arg->tn_left = cconv(arg->tn_left);
3236
3237                 if (asym != NULL) {
3238                         arg->tn_left = parg(n, asym->s_type, arg->tn_left);
3239                 } else {
3240                         arg->tn_left = promote(NOOP, 1, arg->tn_left);
3241                 }
3242                 arg->tn_type = arg->tn_left->tn_type;
3243
3244                 if (asym != NULL)
3245                         asym = asym->s_nxt;
3246         }
3247
3248         return (args);
3249 }
3250
3251 /*
3252  * Compare the type of an argument with the corresponding type of a
3253  * prototype parameter. If it is a valid combination, but both types
3254  * are not the same, insert a conversion to convert the argument into
3255  * the type of the parameter.
3256  */
3257 static tnode_t *
3258 parg(n, tp, tn)
3259         int     n;              /* pos of arg */
3260         type_t  *tp;            /* expected type (from prototype) */
3261         tnode_t *tn;            /* argument */
3262 {
3263         tnode_t *ln;
3264         int     warn;
3265
3266         ln = xcalloc(1, sizeof (tnode_t));
3267         ln->tn_type = tduptyp(tp);
3268         ln->tn_type->t_const = 0;
3269         ln->tn_lvalue = 1;
3270         if (typeok(FARG, n, ln, tn)) {
3271                 if (!eqtype(tp, tn->tn_type, 1, 0, (warn = 0, &warn)) || warn)
3272                         tn = convert(FARG, n, tp, tn);
3273         }
3274         free(ln);
3275         return (tn);
3276 }
3277
3278 /*
3279  * Return the value of an integral constant expression.
3280  * If the expression is not constant or its type is not an integer
3281  * type, an error message is printed.
3282  */
3283 val_t *
3284 constant(tn)
3285         tnode_t *tn;
3286 {
3287         val_t   *v;
3288
3289         if (tn != NULL)
3290                 tn = cconv(tn);
3291         if (tn != NULL)
3292                 tn = promote(NOOP, 0, tn);
3293
3294         v = xcalloc(1, sizeof (val_t));
3295
3296         if (tn == NULL) {
3297                 if (nerr == 0)
3298                         lerror("constant() 1");
3299                 v->v_tspec = INT;
3300                 v->v_quad = 1;
3301                 return (v);
3302         }
3303
3304         v->v_tspec = tn->tn_type->t_tspec;
3305
3306         if (tn->tn_op == CON) {
3307                 if (tn->tn_type->t_tspec != tn->tn_val->v_tspec)
3308                         lerror("constant() 2");
3309                 if (isityp(tn->tn_val->v_tspec)) {
3310                         v->v_ansiu = tn->tn_val->v_ansiu;
3311                         v->v_quad = tn->tn_val->v_quad;
3312                         return (v);
3313                 }
3314                 v->v_quad = tn->tn_val->v_ldbl;
3315         } else {
3316                 v->v_quad = 1;
3317         }
3318
3319         /* integral constant expression expected */
3320         error(55);
3321
3322         if (!isityp(v->v_tspec))
3323                 v->v_tspec = INT;
3324
3325         return (v);
3326 }
3327
3328 /*
3329  * Perform some tests on expressions which can't be done in build() and
3330  * functions called by build(). These tests must be done here because
3331  * we need some information about the context in which the operations
3332  * are performed.
3333  * After all tests are performed, expr() frees the memory which is used
3334  * for the expression.
3335  */
3336 void
3337 expr(tn, vctx, tctx)
3338         tnode_t *tn;
3339         int     vctx, tctx;
3340 {
3341         if (tn == NULL && nerr == 0)
3342                 lerror("expr() 1");
3343
3344         if (tn == NULL) {
3345                 tfreeblk();
3346                 return;
3347         }
3348
3349         /* expr() is also called in global initialisations */
3350         if (dcs->d_ctx != EXTERN)
3351                 chkreach();
3352
3353         chkmisc(tn, vctx, tctx, !tctx, 0, 0, 0);
3354         if (tn->tn_op == ASSIGN) {
3355                 if (hflag && tctx)
3356                         /* assignment in conditional context */
3357                         warning(159);
3358         } else if (tn->tn_op == CON) {
3359                 if (hflag && tctx && !ccflg)
3360                         /* constant in conditional context */
3361                         warning(161);
3362         }
3363         if (!modtab[tn->tn_op].m_sideeff) {
3364                 /*
3365                  * for left operands of COMMA this warning is already
3366                  * printed
3367                  */
3368                 if (tn->tn_op != COMMA && !vctx && !tctx)
3369                         nulleff(tn);
3370         }
3371         if (dflag)
3372                 displexpr(tn, 0);
3373
3374         /* free the tree memory */
3375         tfreeblk();
3376 }
3377
3378 static void
3379 nulleff(tn)
3380         tnode_t *tn;
3381 {
3382         if (!hflag)
3383                 return;
3384
3385         while (!modtab[tn->tn_op].m_sideeff) {
3386                 if (tn->tn_op == CVT && tn->tn_type->t_tspec == VOID) {
3387                         tn = tn->tn_left;
3388                 } else if (tn->tn_op == LOGAND || tn->tn_op == LOGOR) {
3389                         /*
3390                          * && and || have a side effect if the right operand
3391                          * has a side effect.
3392                          */
3393                         tn = tn->tn_right;
3394                 } else if (tn->tn_op == QUEST) {
3395                         /*
3396                          * ? has a side effect if at least one of its right
3397                          * operands has a side effect
3398                          */
3399                         tn = tn->tn_right;
3400                 } else if (tn->tn_op == COLON) {
3401                         /*
3402                          * : has a side effect if at least one of its operands
3403                          * has a side effect
3404                          */
3405                         if (modtab[tn->tn_left->tn_op].m_sideeff) {
3406                                 tn = tn->tn_left;
3407                         } else if (modtab[tn->tn_right->tn_op].m_sideeff) {
3408                                 tn = tn->tn_right;
3409                         } else {
3410                                 break;
3411                         }
3412                 } else {
3413                         break;
3414                 }
3415         }
3416         if (!modtab[tn->tn_op].m_sideeff)
3417                 /* expression has null effect */
3418                 warning(129);
3419 }
3420
3421 /*
3422  * Dump an expression to stdout
3423  * only used for debugging
3424  */
3425 static void
3426 displexpr(tn, offs)
3427         tnode_t *tn;
3428         int     offs;
3429 {
3430         u_quad_t uq;
3431
3432         if (tn == NULL) {
3433                 (void)printf("%*s%s\n", offs, "", "NULL");
3434                 return;
3435         }
3436         (void)printf("%*sop %s  ", offs, "", modtab[tn->tn_op].m_name);
3437
3438         if (tn->tn_op == NAME) {
3439                 (void)printf("%s: %s ",
3440                              tn->tn_sym->s_name, scltoa(tn->tn_sym->s_scl));
3441         } else if (tn->tn_op == CON && isftyp(tn->tn_type->t_tspec)) {
3442                 (void)printf("%#g ", (double)tn->tn_val->v_ldbl);
3443         } else if (tn->tn_op == CON && isityp(tn->tn_type->t_tspec)) {
3444                 uq = tn->tn_val->v_quad;
3445                 (void)printf("0x %08lx %08lx ", (long)(uq >> 32) & 0xffffffffl,
3446                              (long)uq & 0xffffffffl);
3447         } else if (tn->tn_op == CON) {
3448                 if (tn->tn_type->t_tspec != PTR)
3449                         lerror("displexpr() 1");
3450                 (void)printf("0x%0*lx ", (int)(sizeof (void *) * CHAR_BIT / 4),
3451                              (u_long)tn->tn_val->v_quad);
3452         } else if (tn->tn_op == STRING) {
3453                 if (tn->tn_strg->st_tspec == CHAR) {
3454                         (void)printf("\"%s\"", tn->tn_strg->st_cp);
3455                 } else {
3456                         char    *s;
3457                         size_t  n;
3458                         n = MB_CUR_MAX * (tn->tn_strg->st_len + 1);
3459                         s = xmalloc(n);
3460                         (void)wcstombs(s, tn->tn_strg->st_wcp, n);
3461                         (void)printf("L\"%s\"", s);
3462                         free(s);
3463                 }
3464                 (void)printf(" ");
3465         } else if (tn->tn_op == FSEL) {
3466                 (void)printf("o=%d, l=%d ", tn->tn_type->t_foffs,
3467                              tn->tn_type->t_flen);
3468         }
3469         (void)printf("%s\n", ttos(tn->tn_type));
3470         if (tn->tn_op == NAME || tn->tn_op == CON || tn->tn_op == STRING)
3471                 return;
3472         displexpr(tn->tn_left, offs + 2);
3473         if (modtab[tn->tn_op].m_binary ||
3474             (tn->tn_op == PUSH && tn->tn_right != NULL)) {
3475                 displexpr(tn->tn_right, offs + 2);
3476         }
3477 }
3478
3479 /*
3480  * Called by expr() to recursively perform some tests.
3481  */
3482 /* ARGSUSED */
3483 void
3484 chkmisc(tn, vctx, tctx, eqwarn, fcall, rvdisc, szof)
3485         tnode_t *tn;
3486         int     vctx, tctx, eqwarn, fcall, rvdisc, szof;
3487 {
3488         tnode_t *ln, *rn;
3489         mod_t   *mp;
3490         int     nrvdisc, cvctx, ctctx;
3491         op_t    op;
3492         scl_t   sc;
3493         dinfo_t *di;
3494
3495         if (tn == NULL)
3496                 return;
3497
3498         ln = tn->tn_left;
3499         rn = tn->tn_right;
3500         mp = &modtab[op = tn->tn_op];
3501
3502         switch (op) {
3503         case AMPER:
3504                 if (ln->tn_op == NAME && (reached || rchflg)) {
3505                         if (!szof)
3506                                 setsflg(ln->tn_sym);
3507                         setuflg(ln->tn_sym, fcall, szof);
3508                 }
3509                 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
3510                         /* check the range of array indices */
3511                         chkaidx(ln->tn_left, 1);
3512                 break;
3513         case LOAD:
3514                 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
3515                         /* check the range of array indices */
3516                         chkaidx(ln->tn_left, 0);
3517                 /* FALLTHROUGH */
3518         case PUSH:
3519         case INCBEF:
3520         case DECBEF:
3521         case INCAFT:
3522         case DECAFT:
3523         case ADDASS:
3524         case SUBASS:
3525         case MULASS:
3526         case DIVASS:
3527         case MODASS:
3528         case ANDASS:
3529         case ORASS:
3530         case XORASS:
3531         case SHLASS:
3532         case SHRASS:
3533                 if (ln->tn_op == NAME && (reached || rchflg)) {
3534                         sc = ln->tn_sym->s_scl;
3535                         /*
3536                          * Look if there was a asm statement in one of the
3537                          * compound statements we are in. If not, we don't
3538                          * print a warning.
3539                          */
3540                         for (di = dcs; di != NULL; di = di->d_nxt) {
3541                                 if (di->d_asm)
3542                                         break;
3543                         }
3544                         if (sc != EXTERN && sc != STATIC &&
3545                             !ln->tn_sym->s_set && !szof && di == NULL) {
3546                                 /* %s may be used before set */
3547                                 warning(158, ln->tn_sym->s_name);
3548                                 setsflg(ln->tn_sym);
3549                         }
3550                         setuflg(ln->tn_sym, 0, 0);
3551                 }
3552                 break;
3553         case ASSIGN:
3554                 if (ln->tn_op == NAME && !szof && (reached || rchflg)) {
3555                         setsflg(ln->tn_sym);
3556                         if (ln->tn_sym->s_scl == EXTERN)
3557                                 outusg(ln->tn_sym);
3558                 }
3559                 if (ln->tn_op == STAR && ln->tn_left->tn_op == PLUS)
3560                         /* check the range of array indices */
3561                         chkaidx(ln->tn_left, 0);
3562                 break;
3563         case CALL:
3564                 if (ln->tn_op != AMPER || ln->tn_left->tn_op != NAME)
3565                         lerror("chkmisc() 1");
3566                 if (!szof)
3567                         outcall(tn, vctx || tctx, rvdisc);
3568                 break;
3569         case EQ:
3570                 /* equality operator "==" found where "=" was exp. */
3571                 if (hflag && eqwarn)
3572                         warning(160);
3573                 break;
3574         case CON:
3575         case NAME:
3576         case STRING:
3577                 return;
3578                 /* LINTED (enumeration values not handled in switch) */
3579         default:
3580         }
3581
3582         cvctx = mp->m_vctx;
3583         ctctx = mp->m_tctx;
3584         /*
3585          * values of operands of ':' are not used if the type of at least
3586          * one of the operands (for gcc compatibility) is void
3587          * XXX test/value context of QUEST should probably be used as
3588          * context for both operands of COLON
3589          */
3590         if (op == COLON && tn->tn_type->t_tspec == VOID)
3591                 cvctx = ctctx = 0;
3592         nrvdisc = op == CVT && tn->tn_type->t_tspec == VOID;
3593         chkmisc(ln, cvctx, ctctx, mp->m_eqwarn, op == CALL, nrvdisc, szof);
3594
3595         switch (op) {
3596         case PUSH:
3597                 if (rn != NULL)
3598                         chkmisc(rn, 0, 0, mp->m_eqwarn, 0, 0, szof);
3599                 break;
3600         case LOGAND:
3601         case LOGOR:
3602                 chkmisc(rn, 0, 1, mp->m_eqwarn, 0, 0, szof);
3603                 break;
3604         case COLON:
3605                 chkmisc(rn, cvctx, ctctx, mp->m_eqwarn, 0, 0, szof);
3606                 break;
3607         default:
3608                 if (mp->m_binary)
3609                         chkmisc(rn, 1, 0, mp->m_eqwarn, 0, 0, szof);
3610                 break;
3611         }
3612
3613 }
3614
3615 /*
3616  * Checks the range of array indices, if possible.
3617  * amper is set if only the address of the element is used. This
3618  * means that the index is allowd to refere to the first element
3619  * after the array.
3620  */
3621 static void
3622 chkaidx(tn, amper)
3623         tnode_t *tn;
3624         int     amper;
3625 {
3626         int     dim;
3627         tnode_t *ln, *rn;
3628         int     elsz;
3629         quad_t  con;
3630
3631         ln = tn->tn_left;
3632         rn = tn->tn_right;
3633
3634         /* We can only check constant indices. */
3635         if (rn->tn_op != CON)
3636                 return;
3637
3638         /* Return if the left node does not stem from an array. */
3639         if (ln->tn_op != AMPER)
3640                 return;
3641         if (ln->tn_left->tn_op != STRING && ln->tn_left->tn_op != NAME)
3642                 return;
3643         if (ln->tn_left->tn_type->t_tspec != ARRAY)
3644                 return;
3645         
3646         /*
3647          * For incomplete array types, we can print a warning only if
3648          * the index is negative.
3649          */
3650         if (incompl(ln->tn_left->tn_type) && rn->tn_val->v_quad >= 0)
3651                 return;
3652
3653         /* Get the size of one array element */
3654         if ((elsz = length(ln->tn_type->t_subt, NULL)) == 0)
3655                 return;
3656         elsz /= CHAR_BIT;
3657
3658         /* Change the unit of the index from bytes to element size. */
3659         if (isutyp(rn->tn_type->t_tspec)) {
3660                 con = (u_quad_t)rn->tn_val->v_quad / elsz;
3661         } else {
3662                 con = rn->tn_val->v_quad / elsz;
3663         }
3664
3665         dim = ln->tn_left->tn_type->t_dim + (amper ? 1 : 0);
3666
3667         if (!isutyp(rn->tn_type->t_tspec) && con < 0) {
3668                 /* array subscript cannot be negative: %ld */
3669                 warning(167, (long)con);
3670         } else if (dim > 0 && (u_quad_t)con >= dim) {
3671                 /* array subscript cannot be > %d: %ld */
3672                 warning(168, dim - 1, (long)con);
3673         }
3674 }
3675
3676 /*
3677  * Check for ordered comparisions of unsigned values with 0.
3678  */
3679 static void
3680 chkcomp(op, ln, rn)
3681         op_t    op;
3682         tnode_t *ln, *rn;
3683 {
3684         tspec_t lt, rt;
3685         mod_t   *mp;
3686
3687         lt = ln->tn_type->t_tspec;
3688         rt = rn->tn_type->t_tspec;
3689         mp = &modtab[op];
3690
3691         if (ln->tn_op != CON && rn->tn_op != CON)
3692                 return;
3693
3694         if (!isityp(lt) || !isityp(rt))
3695                 return;
3696
3697         if ((hflag || pflag) && lt == CHAR && rn->tn_op == CON &&
3698             (rn->tn_val->v_quad < 0 ||
3699              rn->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) {
3700                 /* nonportable character comparision, op %s */
3701                 warning(230, mp->m_name);
3702                 return;
3703         }
3704         if ((hflag || pflag) && rt == CHAR && ln->tn_op == CON &&
3705             (ln->tn_val->v_quad < 0 ||
3706              ln->tn_val->v_quad > ~(~0 << (CHAR_BIT - 1)))) {
3707                 /* nonportable character comparision, op %s */
3708                 warning(230, mp->m_name);
3709                 return;
3710         }
3711         if (isutyp(lt) && !isutyp(rt) &&
3712             rn->tn_op == CON && rn->tn_val->v_quad <= 0) {
3713                 if (rn->tn_val->v_quad < 0) {
3714                         /* comparision of %s with %s, op %s */
3715                         warning(162, tyname(ln->tn_type), "negative constant",
3716                                 mp->m_name);
3717                 } else if (op == LT || op == GE || (hflag && op == LE)) {
3718                         /* comparision of %s with %s, op %s */
3719                         warning(162, tyname(ln->tn_type), "0", mp->m_name);
3720                 }
3721                 return;
3722         }
3723         if (isutyp(rt) && !isutyp(lt) &&
3724             ln->tn_op == CON && ln->tn_val->v_quad <= 0) {
3725                 if (ln->tn_val->v_quad < 0) {
3726                         /* comparision of %s with %s, op %s */
3727                         warning(162, "negative constant", tyname(rn->tn_type),
3728                                 mp->m_name);
3729                 } else if (op == GT || op == LE || (hflag && op == GE)) {
3730                         /* comparision of %s with %s, op %s */
3731                         warning(162, "0", tyname(rn->tn_type), mp->m_name);
3732                 }
3733                 return;
3734         }
3735 }
3736
3737 /*
3738  * Takes an expression an returns 0 if this expression can be used
3739  * for static initialisation, otherwise -1.
3740  *
3741  * Constant initialisation expressions must be costant or an address
3742  * of a static object with an optional offset. In the first case,
3743  * the result is returned in *offsp. In the second case, the static
3744  * object is returned in *symp and the offset in *offsp.
3745  *
3746  * The expression can consist of PLUS, MINUS, AMPER, NAME, STRING and
3747  * CON. Type conversions are allowed if they do not change binary
3748  * representation (including width).
3749  */
3750 int
3751 conaddr(tn, symp, offsp)
3752         tnode_t *tn;
3753         sym_t   **symp;
3754         ptrdiff_t *offsp;
3755 {
3756         sym_t   *sym;
3757         ptrdiff_t offs1, offs2;
3758         tspec_t t, ot;
3759
3760         switch (tn->tn_op) {
3761         case MINUS:
3762                 if (tn->tn_right->tn_op != CON)
3763                         return (-1);
3764                 /* FALLTHROUGH */
3765         case PLUS:
3766                 offs1 = offs2 = 0;
3767                 if (tn->tn_left->tn_op == CON) {
3768                         offs1 = (ptrdiff_t)tn->tn_left->tn_val->v_quad;
3769                         if (conaddr(tn->tn_right, &sym, &offs2) == -1)
3770                                 return (-1);
3771                 } else if (tn->tn_right->tn_op == CON) {
3772                         offs2 = (ptrdiff_t)tn->tn_right->tn_val->v_quad;
3773                         if (tn->tn_op == MINUS)
3774                                 offs2 = -offs2;
3775                         if (conaddr(tn->tn_left, &sym, &offs1) == -1)
3776                                 return (-1);
3777                 } else {
3778                         return (-1);
3779                 }
3780                 *symp = sym;
3781                 *offsp = offs1 + offs2;
3782                 break;
3783         case AMPER:
3784                 if (tn->tn_left->tn_op == NAME) {
3785                         *symp = tn->tn_left->tn_sym;
3786                         *offsp = 0;
3787                 } else if (tn->tn_left->tn_op == STRING) {
3788                         /*
3789                          * If this would be the front end of a compiler we
3790                          * would return a label instead of 0.
3791                          */
3792                         *offsp = 0;
3793                 }
3794                 break;
3795         case CVT:
3796                 t = tn->tn_type->t_tspec;
3797                 ot = tn->tn_left->tn_type->t_tspec;
3798                 if ((!isityp(t) && t != PTR) || (!isityp(ot) && ot != PTR)) {
3799                         return (-1);
3800                 } else if (psize(t) != psize(ot)) {
3801                         return (-1);
3802                 }
3803                 if (conaddr(tn->tn_left, symp, offsp) == -1)
3804                         return (-1);
3805                 break;
3806         default:
3807                 return (-1);
3808         }
3809         return (0);
3810 }
3811
3812 /*
3813  * Concatenate two string constants.
3814  */
3815 strg_t *
3816 catstrg(strg1, strg2)
3817         strg_t  *strg1, *strg2;
3818 {
3819         size_t  len1, len2, len;
3820
3821         if (strg1->st_tspec != strg2->st_tspec) {
3822                 /* cannot concatenate wide and regular string literals */
3823                 error(292);
3824                 return (strg1);
3825         }
3826
3827         len = (len1 = strg1->st_len) + (len2 = strg2->st_len);
3828
3829         if (strg1->st_tspec == CHAR) {
3830                 strg1->st_cp = xrealloc(strg1->st_cp, len + 1);
3831                 (void)memcpy(strg1->st_cp + len1, strg2->st_cp, len2 + 1);
3832                 free(strg2->st_cp);
3833         } else {
3834                 strg1->st_wcp = xrealloc(strg1->st_wcp,
3835                                          (len + 1) * sizeof (wchar_t));
3836                 (void)memcpy(strg1->st_wcp + len1, strg2->st_wcp,
3837                              (len2 + 1) * sizeof (wchar_t));
3838                 free(strg2->st_wcp);
3839         }
3840         free(strg2);
3841
3842         return (strg1);
3843 }
3844
3845 /*
3846  * Print a warning if the given node has operands which should be
3847  * parenthesized.
3848  *
3849  * XXX Does not work if an operand is a constant expression. Constant
3850  * expressions are already folded.
3851  */
3852 static void
3853 precconf(tn)
3854         tnode_t *tn;
3855 {
3856         tnode_t *ln, *rn;
3857         op_t    lop, rop;
3858         int     lparn, rparn;
3859         mod_t   *mp;
3860         int     warn;
3861
3862         if (!hflag)
3863                 return;
3864
3865         mp = &modtab[tn->tn_op];
3866
3867         lparn = 0;
3868         for (ln = tn->tn_left; ln->tn_op == CVT; ln = ln->tn_left)
3869                 lparn |= ln->tn_parn;
3870         lparn |= ln->tn_parn;
3871         lop = ln->tn_op;
3872
3873         if (mp->m_binary) {
3874                 rparn = 0;
3875                 for (rn = tn->tn_right; tn->tn_op == CVT; rn = rn->tn_left)
3876                         rparn |= rn->tn_parn;
3877                 rparn |= rn->tn_parn;
3878                 rop = rn->tn_op;
3879         }
3880
3881         warn = 0;
3882
3883         switch (tn->tn_op) {
3884         case SHL:
3885         case SHR:
3886                 if (!lparn && (lop == PLUS || lop == MINUS)) {
3887                         warn = 1;
3888                 } else if (!rparn && (rop == PLUS || rop == MINUS)) {
3889                         warn = 1;
3890                 }
3891                 break;
3892         case LOGOR:
3893                 if (!lparn && lop == LOGAND) {
3894                         warn = 1;
3895                 } else if (!rparn && rop == LOGAND) {
3896                         warn = 1;
3897                 }
3898                 break;
3899         case AND:
3900         case XOR:
3901         case OR:
3902                 if (!lparn && lop != tn->tn_op) {
3903                         if (lop == PLUS || lop == MINUS) {
3904                                 warn = 1;
3905                         } else if (lop == AND || lop == XOR) {
3906                                 warn = 1;
3907                         }
3908                 }
3909                 if (!warn && !rparn && rop != tn->tn_op) {
3910                         if (rop == PLUS || rop == MINUS) {
3911                                 warn = 1;
3912                         } else if (rop == AND || rop == XOR) {
3913                                 warn = 1;
3914                         }
3915                 }
3916                 break;
3917                 /* LINTED (enumeration values not handled in switch) */
3918         default:
3919         }
3920
3921         if (warn) {
3922                 /* precedence confusion possible: parenthesize! */
3923                 warning(169);
3924         }
3925
3926 }