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