xref: /netbsd/external/bsd/pcc/dist/pcc/cc/ccom/trees.c (revision 6550d01e)
1 /*	Id: trees.c,v 1.248 2010/06/02 10:39:52 ragge Exp 	*/
2 /*	$NetBSD: trees.c,v 1.1.1.3 2010/06/03 18:57:45 plunky Exp $	*/
3 /*
4  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
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. The name of the author may not be used to endorse or promote products
16  *    derived from this software without specific prior written permission
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 /*
31  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
32  *
33  * Redistribution and use in source and binary forms, with or without
34  * modification, are permitted provided that the following conditions
35  * are met:
36  *
37  * Redistributions of source code and documentation must retain the above
38  * copyright notice, this list of conditions and the following disclaimer.
39  * Redistributions in binary form must reproduce the above copyright
40  * notice, this list of conditionsand the following disclaimer in the
41  * documentation and/or other materials provided with the distribution.
42  * All advertising materials mentioning features or use of this software
43  * must display the following acknowledgement:
44  * 	This product includes software developed or owned by Caldera
45  *	International, Inc.
46  * Neither the name of Caldera International, Inc. nor the names of other
47  * contributors may be used to endorse or promote products derived from
48  * this software without specific prior written permission.
49  *
50  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
51  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
52  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
55  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
59  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
60  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
61  * POSSIBILITY OF SUCH DAMAGE.
62  */
63 /*
64  * Some of the changes from 32V include:
65  * - Understand "void" as type.
66  * - Handle enums as ints everywhere.
67  * - Convert some C-specific ops into branches.
68  */
69 
70 # include "pass1.h"
71 # include "pass2.h"
72 
73 # include <stdarg.h>
74 # include <string.h>
75 
76 static void chkpun(NODE *p);
77 static int opact(NODE *p);
78 static int moditype(TWORD);
79 static NODE *strargs(NODE *);
80 static void rmcops(NODE *p);
81 static void putjops(NODE *, void *);
82 static struct symtab *findmember(struct symtab *, char *);
83 int inftn; /* currently between epilog/prolog */
84 
85 static char *tnames[] = {
86 	"undef",
87 	"farg",
88 	"char",
89 	"unsigned char",
90 	"short",
91 	"unsigned short",
92 	"int",
93 	"unsigned int",
94 	"long",
95 	"unsigned long",
96 	"long long",
97 	"unsigned long long",
98 	"float",
99 	"double",
100 	"long double",
101 	"strty",
102 	"unionty",
103 	"enumty",
104 	"moety",
105 	"void",
106 	"signed", /* pass1 */
107 	"bool", /* pass1 */
108 	"fimag", /* pass1 */
109 	"dimag", /* pass1 */
110 	"limag", /* pass1 */
111 	"fcomplex", /* pass1 */
112 	"dcomplex", /* pass1 */
113 	"lcomplex", /* pass1 */
114 	"enumty", /* pass1 */
115 	"?", "?"
116 };
117 
118 /*	some special actions, used in finding the type of nodes */
119 # define NCVT 01
120 # define PUN 02
121 # define TYPL 04
122 # define TYPR 010
123 # define TYMATCH 040
124 # define LVAL 0100
125 # define CVTO 0200
126 # define CVTL 0400
127 # define CVTR 01000
128 # define PTMATCH 02000
129 # define OTHER 04000
130 # define NCVTR 010000
131 
132 /* node conventions:
133 
134 	NAME:	rval>0 is stab index for external
135 		rval<0 is -inlabel number
136 		lval is offset in bits
137 	ICON:	lval has the value
138 		rval has the STAB index, or - label number,
139 			if a name whose address is in the constant
140 		rval = NONAME means no name
141 	REG:	rval is reg. identification cookie
142 
143 	*/
144 
145 int bdebug = 0;
146 extern int negrel[];
147 
148 NODE *
149 buildtree(int o, NODE *l, NODE *r)
150 {
151 	NODE *p, *q;
152 	int actions;
153 	int opty;
154 	struct symtab *sp = NULL; /* XXX gcc */
155 	NODE *lr, *ll;
156 
157 #ifdef PCC_DEBUG
158 	if (bdebug) {
159 		printf("buildtree(%s, %p, %p)\n", copst(o), l, r);
160 		if (l) fwalk(l, eprint, 0);
161 		if (r) fwalk(r, eprint, 0);
162 	}
163 #endif
164 	opty = coptype(o);
165 
166 	/* check for constants */
167 
168 	if( opty == UTYPE && l->n_op == ICON ){
169 
170 		switch( o ){
171 
172 		case NOT:
173 		case UMINUS:
174 		case COMPL:
175 			if( conval( l, o, l ) ) return(l);
176 			break;
177 		}
178 	} else if (o == NOT && l->n_op == FCON) {
179 		l = clocal(block(SCONV, l, NIL, INT, 0, MKSUE(INT)));
180 	} else if( o == UMINUS && l->n_op == FCON ){
181 			l->n_dcon = FLOAT_NEG(l->n_dcon);
182 			return(l);
183 
184 	} else if( o==QUEST && l->n_op==ICON ) {
185 		CONSZ c = l->n_lval;
186 		nfree(l);
187 		if (c) {
188 			walkf(r->n_right, putjops, 0);
189 			tfree(r->n_right);
190 			l = r->n_left;
191 		} else {
192 			walkf(r->n_left, putjops, 0);
193 			tfree(r->n_left);
194 			l = r->n_right;
195 		}
196 		nfree(r);
197 		return(l);
198 	} else if( opty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
199 
200 		switch( o ){
201 
202 		case PLUS:
203 		case MINUS:
204 		case MUL:
205 		case DIV:
206 		case MOD:
207 			/*
208 			 * Do type propagation for simple types here.
209 			 * The constant value is correct anyway.
210 			 * Maybe this op shortcut should be removed?
211 			 */
212 			if (l->n_sp == NULL && r->n_sp == NULL &&
213 			    l->n_type < BTMASK && r->n_type < BTMASK) {
214 				if (l->n_type > r->n_type)
215 					r->n_type = l->n_type;
216 				else
217 					l->n_type = r->n_type;
218 			}
219 			/* FALLTHROUGH */
220 		case ULT:
221 		case UGT:
222 		case ULE:
223 		case UGE:
224 		case LT:
225 		case GT:
226 		case LE:
227 		case GE:
228 		case EQ:
229 		case NE:
230 		case ANDAND:
231 		case OROR:
232 		case AND:
233 		case OR:
234 		case ER:
235 		case LS:
236 		case RS:
237 			if (!ISPTR(l->n_type) && !ISPTR(r->n_type)) {
238 				if( conval( l, o, r ) ) {
239 					nfree(r);
240 					return(l);
241 				}
242 			}
243 			break;
244 		}
245 	} else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
246 	    (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
247 	    o == MUL || o == DIV || (o >= EQ && o <= GT) )) {
248 		if (l->n_op == ICON)
249 			l->n_dcon = FLOAT_CAST(l->n_lval, l->n_type);
250 		if (r->n_op == ICON)
251 			r->n_dcon = FLOAT_CAST(r->n_lval, r->n_type);
252 		switch(o){
253 		case PLUS:
254 		case MINUS:
255 		case MUL:
256 		case DIV:
257 			switch (o) {
258 			case PLUS:
259 				l->n_dcon = FLOAT_PLUS(l->n_dcon, r->n_dcon);
260 				break;
261 			case MINUS:
262 				l->n_dcon = FLOAT_MINUS(l->n_dcon, r->n_dcon);
263 				break;
264 			case MUL:
265 				l->n_dcon = FLOAT_MUL(l->n_dcon, r->n_dcon);
266 				break;
267 			case DIV:
268 				if (FLOAT_ISZERO(r->n_dcon))
269 					goto runtime;
270 				l->n_dcon = FLOAT_DIV(l->n_dcon, r->n_dcon);
271 				break;
272 			}
273 			l->n_op = FCON;
274 			l->n_type = DOUBLE;
275 			l->n_sue = MKSUE(DOUBLE);
276 			nfree(r);
277 			return(l);
278 		case EQ:
279 		case NE:
280 		case LE:
281 		case LT:
282 		case GE:
283 		case GT:
284 			switch (o) {
285 			case EQ:
286 				l->n_lval = FLOAT_EQ(l->n_dcon, r->n_dcon);
287 				break;
288 			case NE:
289 				l->n_lval = FLOAT_NE(l->n_dcon, r->n_dcon);
290 				break;
291 			case LE:
292 				l->n_lval = FLOAT_LE(l->n_dcon, r->n_dcon);
293 				break;
294 			case LT:
295 				l->n_lval = FLOAT_LT(l->n_dcon, r->n_dcon);
296 				break;
297 			case GE:
298 				l->n_lval = FLOAT_GE(l->n_dcon, r->n_dcon);
299 				break;
300 			case GT:
301 				l->n_lval = FLOAT_GT(l->n_dcon, r->n_dcon);
302 				break;
303 			}
304 			nfree(r);
305 			r = bcon(l->n_lval);
306 			nfree(l);
307 			return r;
308 		}
309 	}
310 runtime:
311 	/* its real; we must make a new node */
312 
313 	p = block(o, l, r, INT, 0, MKSUE(INT));
314 
315 	actions = opact(p);
316 
317 	if (actions & LVAL) { /* check left descendent */
318 		if (notlval(p->n_left)) {
319 			uerror("lvalue required");
320 			nfree(p);
321 			return l;
322 #ifdef notyet
323 		} else {
324 			if ((l->n_type > BTMASK && ISCON(l->n_qual)) ||
325 			    (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT)))
326 				if (blevel > 0)
327 					uerror("lvalue is declared const");
328 #endif
329 		}
330 	}
331 
332 	if( actions & NCVTR ){
333 		p->n_left = pconvert( p->n_left );
334 		}
335 	else if( !(actions & NCVT ) ){
336 		switch( opty ){
337 
338 		case BITYPE:
339 			p->n_right = pconvert( p->n_right );
340 		case UTYPE:
341 			p->n_left = pconvert( p->n_left );
342 
343 			}
344 		}
345 
346 	if ((actions&PUN) && (o!=CAST))
347 		chkpun(p);
348 
349 	if( actions & (TYPL|TYPR) ){
350 
351 		q = (actions&TYPL) ? p->n_left : p->n_right;
352 
353 		p->n_type = q->n_type;
354 		p->n_qual = q->n_qual;
355 		p->n_df = q->n_df;
356 		p->n_sue = q->n_sue;
357 		}
358 
359 	if( actions & CVTL ) p = convert( p, CVTL );
360 	if( actions & CVTR ) p = convert( p, CVTR );
361 	if( actions & TYMATCH ) p = tymatch(p);
362 	if( actions & PTMATCH ) p = ptmatch(p);
363 
364 	if( actions & OTHER ){
365 		struct suedef *sue2;
366 		struct suedef *sue;
367 
368 		l = p->n_left;
369 		r = p->n_right;
370 
371 		switch(o){
372 
373 		case NAME:
374 			cerror("buildtree NAME");
375 
376 		case STREF:
377 			/* p->x turned into *(p+offset) */
378 			/* rhs must be a name; check correctness */
379 
380 			/* Find member symbol struct */
381 			if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
382 				uerror("struct or union required");
383 				break;
384 			}
385 
386 			/* find type sue */
387 			GETSUE(sue, l->n_sue);
388 			if ((sp = sue->suem) == NULL) {
389 				uerror("undefined struct or union");
390 				break;
391 			}
392 
393 			sp = findmember(sp, r->n_name);
394 #ifdef notdef
395 			name = r->n_name;
396 			for (; sp != NULL; sp = sp->snext) {
397 				if (sp->sname == name)
398 					break;
399 			}
400 #endif
401 			if (sp == NULL) {
402 				uerror("member '%s' not declared", r->n_name);
403 				break;
404 			}
405 
406 			r->n_sp = sp;
407 			p = stref(p);
408 			break;
409 
410 		case UMUL:
411 			if (l->n_op == ADDROF) {
412 				nfree(p);
413 				p = l->n_left;
414 				nfree(l);
415 			}
416 			if( !ISPTR(l->n_type))uerror("illegal indirection");
417 			p->n_type = DECREF(l->n_type);
418 			p->n_qual = DECREF(l->n_qual);
419 			p->n_df = l->n_df;
420 			p->n_sue = l->n_sue;
421 			break;
422 
423 		case ADDROF:
424 			switch( l->n_op ){
425 
426 			case UMUL:
427 				nfree(p);
428 				p = l->n_left;
429 				nfree(l);
430 			case TEMP:
431 			case NAME:
432 				p->n_type = INCREF(l->n_type);
433 				p->n_qual = INCQAL(l->n_qual);
434 				p->n_df = l->n_df;
435 				p->n_sue = l->n_sue;
436 				break;
437 
438 			case COMOP:
439 				nfree(p);
440 				lr = buildtree(ADDROF, l->n_right, NIL);
441 				p = buildtree( COMOP, l->n_left, lr );
442 				nfree(l);
443 				break;
444 
445 			case QUEST:
446 				lr = buildtree( ADDROF, l->n_right->n_right, NIL );
447 				ll = buildtree( ADDROF, l->n_right->n_left, NIL );
448 				nfree(p); nfree(l->n_right);
449 				p = buildtree( QUEST, l->n_left, buildtree( COLON, ll, lr ) );
450 				nfree(l);
451 				break;
452 
453 			default:
454 				uerror("unacceptable operand of &: %d", l->n_op );
455 				break;
456 				}
457 			break;
458 
459 		case LS:
460 		case RS: /* must make type size at least int... */
461 			if (p->n_type == CHAR || p->n_type == SHORT) {
462 				p->n_left = makety(l, INT, 0, 0, MKSUE(INT));
463 			} else if (p->n_type == UCHAR || p->n_type == USHORT) {
464 				p->n_left = makety(l, UNSIGNED, 0, 0,
465 				    MKSUE(UNSIGNED));
466 			}
467 			l = p->n_left;
468 			p->n_type = l->n_type;
469 			p->n_qual = l->n_qual;
470 			p->n_df = l->n_df;
471 			p->n_sue = l->n_sue;
472 
473 			/* FALLTHROUGH */
474 		case LSEQ:
475 		case RSEQ: /* ...but not for assigned types */
476 			if(tsize(r->n_type, r->n_df, r->n_sue) > SZINT)
477 				p->n_right = makety(r, INT, 0, 0, MKSUE(INT));
478 			break;
479 
480 		case RETURN:
481 		case ASSIGN:
482 		case CAST:
483 			/* structure assignment */
484 			/* take the addresses of the two sides; then make an
485 			 * operator using STASG and
486 			 * the addresses of left and right */
487 
488 			{
489 				TWORD t;
490 				union dimfun *d;
491 
492 				GETSUE(sue, l->n_sue);
493 				GETSUE(sue2, r->n_sue);
494 				if (sue->suem != sue2->suem)
495 					uerror("assignment of different structures");
496 
497 				r = buildtree(ADDROF, r, NIL);
498 				t = r->n_type;
499 				d = r->n_df;
500 				sue = r->n_sue;
501 
502 				l = block(STASG, l, r, t, d, sue);
503 				l = clocal(l);
504 
505 				if( o == RETURN ){
506 					nfree(p);
507 					p = l;
508 					break;
509 				}
510 
511 				p->n_op = UMUL;
512 				p->n_left = l;
513 				p->n_right = NIL;
514 				break;
515 				}
516 		case COLON:
517 			/* structure colon */
518 
519 			GETSUE(sue, l->n_sue);
520 			GETSUE(sue2, r->n_sue);
521 			if (sue->suem != sue2->suem)
522 				uerror( "type clash in conditional" );
523 			break;
524 
525 		case CALL:
526 			p->n_right = r = strargs(p->n_right);
527 			p = funcode(p);
528 			/* FALLTHROUGH */
529 		case UCALL:
530 			if (!ISPTR(l->n_type))
531 				uerror("illegal function");
532 			p->n_type = DECREF(l->n_type);
533 			if (!ISFTN(p->n_type))
534 				uerror("illegal function");
535 			p->n_type = DECREF(p->n_type);
536 			p->n_df = l->n_df;
537 			p->n_sue = l->n_sue;
538 			if (l->n_op == ADDROF && l->n_left->n_op == NAME &&
539 			    l->n_left->n_sp != NULL && l->n_left->n_sp != NULL &&
540 			    (l->n_left->n_sp->sclass == FORTRAN ||
541 			    l->n_left->n_sp->sclass == UFORTRAN)) {
542 				p->n_op += (FORTCALL-CALL);
543 			}
544 			if (p->n_type == STRTY || p->n_type == UNIONTY) {
545 				/* function returning structure */
546 				/*  make function really return ptr to str., with * */
547 
548 				p->n_op += STCALL-CALL;
549 				p->n_type = INCREF(p->n_type);
550 				p = clocal(p); /* before recursing */
551 				p = buildtree(UMUL, p, NIL);
552 
553 				}
554 			break;
555 
556 		default:
557 			cerror( "other code %d", o );
558 			}
559 
560 		}
561 
562 	/*
563 	 * Allow (void)0 casts.
564 	 * XXX - anything on the right side must be possible to cast.
565 	 * XXX - remove void types further on.
566 	 */
567 	if (p->n_op == CAST && p->n_type == VOID &&
568 	    p->n_right->n_op == ICON)
569 		p->n_right->n_type = VOID;
570 
571 	if (actions & CVTO)
572 		p = oconvert(p);
573 	p = clocal(p);
574 
575 #ifdef PCC_DEBUG
576 	if (bdebug) {
577 		printf("End of buildtree:\n");
578 		fwalk(p, eprint, 0);
579 	}
580 #endif
581 
582 	return(p);
583 
584 	}
585 
586 /* Find a member in a struct or union.  May be an unnamed member */
587 static struct symtab *
588 findmember(struct symtab *sp, char *s)
589 {
590 	struct symtab *sp2, *sp3;
591 
592 	for (; sp != NULL; sp = sp->snext) {
593 		if (sp->sname[0] == '*') {
594 			/* unnamed member, recurse down */
595 			if ((sp2 = findmember(sp->ssue->suem, s))) {
596 				sp3 = tmpalloc(sizeof (struct symtab));
597 				*sp3 = *sp2;
598 				sp3->soffset += sp->soffset;
599 				return sp3;
600 			}
601 		} else if (sp->sname == s)
602 			return sp;
603 	}
604 	return NULL;
605 }
606 
607 
608 /*
609  * Check if there will be a lost label destination inside of a ?:
610  * It cannot be reached so just print it out.
611  */
612 static void
613 putjops(NODE *p, void *arg)
614 {
615 	if (p->n_op == COMOP && p->n_left->n_op == GOTO)
616 		plabel(p->n_left->n_left->n_lval+1);
617 }
618 
619 /*
620  * Build a name node based on a symtab entry.
621  * broken out from buildtree().
622  */
623 NODE *
624 nametree(struct symtab *sp)
625 {
626 	NODE *p;
627 
628 	p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->ssue);
629 	p->n_qual = sp->squal;
630 	p->n_sp = sp;
631 
632 #ifndef NO_C_BUILTINS
633 	if (sp->sname[0] == '_' && strncmp(sp->sname, "__builtin_", 10) == 0)
634 		return p;  /* do not touch builtins here */
635 
636 #endif
637 
638 	if (sp->sflags & STNODE) {
639 		/* Generated for optimizer */
640 		p->n_op = TEMP;
641 		p->n_rval = sp->soffset;
642 	}
643 
644 #ifdef GCC_COMPAT
645 	/* Get a label name */
646 	if (sp->sflags == SLBLNAME) {
647 		p->n_type = VOID;
648 		p->n_sue = MKSUE(VOID);
649 	}
650 #endif
651 	if (sp->stype == UNDEF) {
652 		uerror("%s undefined", sp->sname);
653 		/* make p look reasonable */
654 		p->n_type = INT;
655 		p->n_sue = MKSUE(INT);
656 		p->n_df = NULL;
657 		defid(p, SNULL);
658 	}
659 	if (sp->sclass == MOE) {
660 		p->n_op = ICON;
661 		p->n_lval = sp->soffset;
662 		p->n_df = NULL;
663 		p->n_sp = NULL;
664 	}
665 	return clocal(p);
666 }
667 
668 /*
669  * Cast a node to another type by inserting a cast.
670  * Just a nicer interface to buildtree.
671  * Returns the new tree.
672  */
673 NODE *
674 cast(NODE *p, TWORD t, TWORD u)
675 {
676 	NODE *q;
677 
678 	q = block(NAME, NIL, NIL, t, 0, MKSUE(BTYPE(t)));
679 	q->n_qual = u;
680 	q = buildtree(CAST, q, p);
681 	p = q->n_right;
682 	nfree(q->n_left);
683 	nfree(q);
684 	return p;
685 }
686 
687 /*
688  * Cast and complain if necessary by not inserining a cast.
689  */
690 NODE *
691 ccast(NODE *p, TWORD t, TWORD u, union dimfun *df, struct suedef *sue)
692 {
693 	NODE *q;
694 
695 	/* let buildtree do typechecking (and casting) */
696 	q = block(NAME, NIL, NIL, t, df, sue);
697 	p = buildtree(ASSIGN, q, p);
698 	nfree(p->n_left);
699 	q = optim(p->n_right);
700 	nfree(p);
701 	return q;
702 }
703 
704 /*
705  * Do a conditional branch.
706  */
707 void
708 cbranch(NODE *p, NODE *q)
709 {
710 	p = buildtree(CBRANCH, p, q);
711 	if (p->n_left->n_op == ICON) {
712 		if (p->n_left->n_lval != 0) {
713 			branch(q->n_lval); /* branch always */
714 			reached = 0;
715 		}
716 		tfree(p);
717 		tfree(q);
718 		return;
719 	}
720 	ecomp(p);
721 }
722 
723 NODE *
724 strargs( p ) register NODE *p;  { /* rewrite structure flavored arguments */
725 
726 	if( p->n_op == CM ){
727 		p->n_left = strargs( p->n_left );
728 		p->n_right = strargs( p->n_right );
729 		return( p );
730 		}
731 
732 	if( p->n_type == STRTY || p->n_type == UNIONTY ){
733 		p = block(STARG, p, NIL, p->n_type, p->n_df, p->n_sue);
734 		p->n_left = buildtree( ADDROF, p->n_left, NIL );
735 		p = clocal(p);
736 		}
737 	return( p );
738 }
739 
740 /*
741  * apply the op o to the lval part of p; if binary, rhs is val
742  */
743 int
744 conval(NODE *p, int o, NODE *q)
745 {
746 	int i, u;
747 	CONSZ val;
748 	U_CONSZ v1, v2;
749 
750 	val = q->n_lval;
751 	u = ISUNSIGNED(p->n_type) || ISUNSIGNED(q->n_type);
752 	if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
753 
754 	if (p->n_sp != NULL && q->n_sp != NULL)
755 		return(0);
756 	if (q->n_sp != NULL && o != PLUS)
757 		return(0);
758 	if (p->n_sp != NULL && o != PLUS && o != MINUS)
759 		return(0);
760 	v1 = p->n_lval;
761 	v2 = q->n_lval;
762 	switch( o ){
763 
764 	case PLUS:
765 		p->n_lval += val;
766 		if (p->n_sp == NULL) {
767 			p->n_right = q->n_right;
768 			p->n_type = q->n_type;
769 		}
770 		break;
771 	case MINUS:
772 		p->n_lval -= val;
773 		break;
774 	case MUL:
775 		p->n_lval *= val;
776 		break;
777 	case DIV:
778 		if (val == 0)
779 			uerror("division by 0");
780 		else  {
781 			if (u) {
782 				v1 /= v2;
783 				p->n_lval = v1;
784 			} else
785 				p->n_lval /= val;
786 		}
787 		break;
788 	case MOD:
789 		if (val == 0)
790 			uerror("division by 0");
791 		else  {
792 			if (u) {
793 				v1 %= v2;
794 				p->n_lval = v1;
795 			} else
796 				p->n_lval %= val;
797 		}
798 		break;
799 	case AND:
800 		p->n_lval &= val;
801 		break;
802 	case OR:
803 		p->n_lval |= val;
804 		break;
805 	case ER:
806 		p->n_lval ^= val;
807 		break;
808 	case LS:
809 		i = (int)val;
810 		p->n_lval = p->n_lval << i;
811 		break;
812 	case RS:
813 		i = (int)val;
814 		if (u) {
815 			v1 = v1 >> i;
816 			p->n_lval = v1;
817 		} else
818 			p->n_lval = p->n_lval >> i;
819 		break;
820 
821 	case UMINUS:
822 		p->n_lval = - p->n_lval;
823 		break;
824 	case COMPL:
825 		p->n_lval = ~p->n_lval;
826 		break;
827 	case NOT:
828 		p->n_lval = !p->n_lval;
829 		break;
830 	case LT:
831 		p->n_lval = p->n_lval < val;
832 		break;
833 	case LE:
834 		p->n_lval = p->n_lval <= val;
835 		break;
836 	case GT:
837 		p->n_lval = p->n_lval > val;
838 		break;
839 	case GE:
840 		p->n_lval = p->n_lval >= val;
841 		break;
842 	case ULT:
843 		p->n_lval = v1 < v2;
844 		break;
845 	case ULE:
846 		p->n_lval = v1 <= v2;
847 		break;
848 	case UGT:
849 		p->n_lval = v1 > v2;
850 		break;
851 	case UGE:
852 		p->n_lval = v1 >= v2;
853 		break;
854 	case EQ:
855 		p->n_lval = p->n_lval == val;
856 		break;
857 	case NE:
858 		p->n_lval = p->n_lval != val;
859 		break;
860 	case ANDAND:
861 		p->n_lval = p->n_lval && val;
862 		break;
863 	case OROR:
864 		p->n_lval = p->n_lval || val;
865 		break;
866 	default:
867 		return(0);
868 		}
869 	return(1);
870 	}
871 
872 /*
873  * Checks p for the existance of a pun.  This is called when the op of p
874  * is ASSIGN, RETURN, CAST, COLON, or relational.
875  * One case is when enumerations are used: this applies only to lint.
876  * In the other case, one operand is a pointer, the other integer type
877  * we check that this integer is in fact a constant zero...
878  * in the case of ASSIGN, any assignment of pointer to integer is illegal
879  * this falls out, because the LHS is never 0.
880  * XXX - check for COMOPs in assignment RHS?
881  */
882 void
883 chkpun(NODE *p)
884 {
885 	union dimfun *d1, *d2;
886 	NODE *q;
887 	int t1, t2;
888 
889 	t1 = p->n_left->n_type;
890 	t2 = p->n_right->n_type;
891 
892 	switch (p->n_op) {
893 	case RETURN:
894 		/* return of void allowed but nothing else */
895 		if (t1 == VOID && t2 == VOID)
896 			return;
897 		if (t1 == VOID) {
898 			werror("returning value from void function");
899 			return;
900 		}
901 		if (t2 == VOID) {
902 			uerror("using void value");
903 			return;
904 		}
905 	case COLON:
906 		if (t1 == VOID && t2 == VOID)
907 			return;
908 		break;
909 	default:
910 		if ((t1 == VOID && t2 != VOID) || (t1 != VOID && t2 == VOID)) {
911 			uerror("value of void expression used");
912 			return;
913 		}
914 		break;
915 	}
916 
917 	/* allow void pointer assignments in any direction */
918 	if (BTYPE(t1) == VOID && (t2 & TMASK))
919 		return;
920 	if (BTYPE(t2) == VOID && (t1 & TMASK))
921 		return;
922 
923 	if (ISPTR(t1) || ISARY(t1))
924 		q = p->n_right;
925 	else
926 		q = p->n_left;
927 
928 	if (!ISPTR(q->n_type) && !ISARY(q->n_type)) {
929 		if (q->n_op != ICON || q->n_lval != 0)
930 			werror("illegal combination of pointer and integer");
931 	} else {
932 		d1 = p->n_left->n_df;
933 		d2 = p->n_right->n_df;
934 		if (t1 == t2) {
935 			struct suedef *s1, *s2;
936 
937 			GETSUE(s1, p->n_left->n_sue);
938 			GETSUE(s2, p->n_right->n_sue);
939 			if (s1->suem != s2->suem)
940 				werror("illegal structure pointer combination");
941 			return;
942 		}
943 		for (;;) {
944 			if (ISARY(t1) || ISPTR(t1)) {
945 				if (!ISARY(t2) && !ISPTR(t2))
946 					break;
947 				if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) {
948 					werror("illegal array size combination");
949 					return;
950 				}
951 				if (ISARY(t1))
952 					++d1;
953 				if (ISARY(t2))
954 					++d2;
955 			} else if (ISFTN(t1)) {
956 				if (chkftn(d1->dfun, d2->dfun)) {
957 					werror("illegal function "
958 					    "pointer combination");
959 					return;
960 				}
961 				++d1;
962 				++d2;
963 			} else
964 				break;
965 			t1 = DECREF(t1);
966 			t2 = DECREF(t2);
967 		}
968 		if (Wpointer_sign)
969 			werror("illegal pointer combination");
970 	}
971 }
972 
973 NODE *
974 stref(NODE *p)
975 {
976 	NODE *r;
977 	struct suedef *sue;
978 	union dimfun *d;
979 	TWORD t, q;
980 	int dsc;
981 	OFFSZ off;
982 	struct symtab *s;
983 
984 	/* make p->x */
985 	/* this is also used to reference automatic variables */
986 
987 	s = p->n_right->n_sp;
988 	nfree(p->n_right);
989 	r = p->n_left;
990 	nfree(p);
991 	p = pconvert(r);
992 
993 	/* make p look like ptr to x */
994 
995 	if (!ISPTR(p->n_type))
996 		p->n_type = PTR+UNIONTY;
997 
998 	t = INCREF(s->stype);
999 	q = INCQAL(s->squal);
1000 	d = s->sdf;
1001 	sue = s->ssue;
1002 
1003 	p = makety(p, t, q, d, sue);
1004 
1005 	/* compute the offset to be added */
1006 
1007 	off = s->soffset;
1008 	dsc = s->sclass;
1009 
1010 #ifndef CAN_UNALIGN
1011 	/*
1012 	 * If its a packed struct, and the target cannot do unaligned
1013 	 * accesses, then split it up in two bitfield operations.
1014 	 * LHS and RHS accesses are different, so must delay
1015 	 * it until we know.  Do the bitfield construct here though.
1016 	 */
1017 	if ((dsc & FIELD) == 0 && (off % talign(s->stype, s->ssue))) {
1018 #if 0
1019 		int sz = tsize(s->stype, s->sdf, s->ssue);
1020 		int al = talign(s->stype, s->ssue);
1021 		int sz1 = al - (off % al);
1022 #endif
1023 	}
1024 #endif
1025 
1026 	if (dsc & FIELD) {  /* make fields look like ints */
1027 		off = (off/ALINT)*ALINT;
1028 		sue = MKSUE(INT);
1029 	}
1030 	if (off != 0) {
1031 		p = block(PLUS, p, offcon(off, t, d, sue), t, d, sue);
1032 		p->n_qual = q;
1033 		p = optim(p);
1034 	}
1035 
1036 	p = buildtree(UMUL, p, NIL);
1037 
1038 	/* if field, build field info */
1039 
1040 	if (dsc & FIELD) {
1041 		p = block(FLD, p, NIL, s->stype, 0, s->ssue);
1042 		p->n_qual = q;
1043 		p->n_rval = PKFIELD(dsc&FLDSIZ, s->soffset%ALINT);
1044 	}
1045 
1046 	p = clocal(p);
1047 	return p;
1048 }
1049 
1050 int
1051 notlval(p) register NODE *p; {
1052 
1053 	/* return 0 if p an lvalue, 1 otherwise */
1054 
1055 	again:
1056 
1057 	switch( p->n_op ){
1058 
1059 	case FLD:
1060 		p = p->n_left;
1061 		goto again;
1062 
1063 	case NAME:
1064 	case OREG:
1065 	case UMUL:
1066 		if( ISARY(p->n_type) || ISFTN(p->n_type) ) return(1);
1067 	case TEMP:
1068 	case REG:
1069 		return(0);
1070 
1071 	default:
1072 		return(1);
1073 
1074 		}
1075 
1076 	}
1077 /* make a constant node with value i */
1078 NODE *
1079 bcon(int i)
1080 {
1081 	return xbcon(i, NULL, INT);
1082 }
1083 
1084 NODE *
1085 xbcon(CONSZ val, struct symtab *sp, TWORD type)
1086 {
1087 	NODE *p;
1088 
1089 	p = block(ICON, NIL, NIL, type, 0, MKSUE(type));
1090 	p->n_lval = val;
1091 	p->n_sp = sp;
1092 	return clocal(p);
1093 }
1094 
1095 NODE *
1096 bpsize(NODE *p)
1097 {
1098 	return(offcon(psize(p), p->n_type, p->n_df, p->n_sue));
1099 }
1100 
1101 /*
1102  * p is a node of type pointer; psize returns the
1103  * size of the thing pointed to
1104  */
1105 OFFSZ
1106 psize(NODE *p)
1107 {
1108 
1109 	if (!ISPTR(p->n_type)) {
1110 		uerror("pointer required");
1111 		return(SZINT);
1112 	}
1113 	/* note: no pointers to fields */
1114 	return(tsize(DECREF(p->n_type), p->n_df, p->n_sue));
1115 }
1116 
1117 /*
1118  * convert an operand of p
1119  * f is either CVTL or CVTR
1120  * operand has type int, and is converted by the size of the other side
1121  * convert is called when an integer is to be added to a pointer, for
1122  * example in arrays or structures.
1123  */
1124 NODE *
1125 convert(NODE *p, int f)
1126 {
1127 	union dimfun *df;
1128 	TWORD ty, ty2;
1129 	NODE *q, *r, *s, *rv;
1130 
1131 	if (f == CVTL) {
1132 		q = p->n_left;
1133 		s = p->n_right;
1134 	} else {
1135 		q = p->n_right;
1136 		s = p->n_left;
1137 	}
1138 	ty2 = ty = DECREF(s->n_type);
1139 	while (ISARY(ty))
1140 		ty = DECREF(ty);
1141 
1142 	r = offcon(tsize(ty, s->n_df, s->n_sue), s->n_type, s->n_df, s->n_sue);
1143 	ty = ty2;
1144 	rv = bcon(1);
1145 	df = s->n_df;
1146 	while (ISARY(ty)) {
1147 		rv = buildtree(MUL, rv, df->ddim >= 0 ? bcon(df->ddim) :
1148 		    tempnode(-df->ddim, INT, 0, MKSUE(INT)));
1149 		df++;
1150 		ty = DECREF(ty);
1151 	}
1152 	rv = clocal(block(PMCONV, rv, r, INT, 0, MKSUE(INT)));
1153 	rv = optim(rv);
1154 
1155 	r = block(PMCONV, q, rv, INT, 0, MKSUE(INT));
1156 	r = clocal(r);
1157 	/*
1158 	 * Indexing is only allowed with integer arguments, so insert
1159 	 * SCONV here if arg is not an integer.
1160 	 * XXX - complain?
1161 	 */
1162 	if (r->n_type != INTPTR)
1163 		r = clocal(block(SCONV, r, NIL, INTPTR, 0, MKSUE(INTPTR)));
1164 	if (f == CVTL)
1165 		p->n_left = r;
1166 	else
1167 		p->n_right = r;
1168 	return(p);
1169 }
1170 
1171 NODE *
1172 pconvert( p ) register NODE *p; {
1173 
1174 	/* if p should be changed into a pointer, do so */
1175 
1176 	if( ISARY( p->n_type) ){
1177 		p->n_type = DECREF( p->n_type );
1178 		++p->n_df;
1179 		return( buildtree( ADDROF, p, NIL ) );
1180 	}
1181 	if( ISFTN( p->n_type) )
1182 		return( buildtree( ADDROF, p, NIL ) );
1183 
1184 	return( p );
1185 	}
1186 
1187 NODE *
1188 oconvert(p) register NODE *p; {
1189 	/* convert the result itself: used for pointer and unsigned */
1190 
1191 	switch(p->n_op) {
1192 
1193 	case LE:
1194 	case LT:
1195 	case GE:
1196 	case GT:
1197 		if(ISUNSIGNED(p->n_left->n_type) ||
1198 		    ISUNSIGNED(p->n_right->n_type) ||
1199 		    ISPTR(p->n_left->n_type) ||
1200 		    ISPTR(p->n_right->n_type))
1201 			 p->n_op += (ULE-LE);
1202 		/* FALLTHROUGH */
1203 	case EQ:
1204 	case NE:
1205 		return( p );
1206 
1207 	case MINUS:
1208 		return(  clocal( block( PVCONV,
1209 			p, bpsize(p->n_left), INT, 0, MKSUE(INT))));
1210 		}
1211 
1212 	cerror( "illegal oconvert: %d", p->n_op );
1213 
1214 	return(p);
1215 	}
1216 
1217 /*
1218  * makes the operands of p agree; they are
1219  * either pointers or integers, by this time
1220  * with MINUS, the sizes must be the same
1221  * with COLON, the types must be the same
1222  */
1223 NODE *
1224 ptmatch(NODE *p)
1225 {
1226 	struct suedef *sue, *sue2;
1227 	union dimfun *d, *d2;
1228 	TWORD t1, t2, t, q1, q2, q;
1229 	int o;
1230 
1231 	o = p->n_op;
1232 	t = t1 = p->n_left->n_type;
1233 	q = q1 = p->n_left->n_qual;
1234 	t2 = p->n_right->n_type;
1235 	q2 = p->n_right->n_qual;
1236 	d = p->n_left->n_df;
1237 	d2 = p->n_right->n_df;
1238 	sue = p->n_left->n_sue;
1239 	sue2 = p->n_right->n_sue;
1240 
1241 	switch( o ){
1242 
1243 	case ASSIGN:
1244 	case RETURN:
1245 	case CAST:
1246 		{  break; }
1247 
1248 	case MINUS:
1249 		{  if( psize(p->n_left) != psize(p->n_right) ){
1250 			uerror( "illegal pointer subtraction");
1251 			}
1252 		   break;
1253 		   }
1254 	case COLON:
1255 		if (t1 != t2) {
1256 			/*
1257 			 * Check for void pointer types. They are allowed
1258 			 * to cast to/from any pointers.
1259 			 */
1260 			if (ISPTR(t1) && ISPTR(t2) &&
1261 			    (BTYPE(t1) == VOID || BTYPE(t2) == VOID))
1262 				break;
1263 			uerror("illegal types in :");
1264 		}
1265 		break;
1266 
1267 	default:  /* must work harder: relationals or comparisons */
1268 
1269 		if( !ISPTR(t1) ){
1270 			t = t2;
1271 			q = q2;
1272 			d = d2;
1273 			sue = sue2;
1274 			break;
1275 			}
1276 		if( !ISPTR(t2) ){
1277 			break;
1278 			}
1279 
1280 		/* both are pointers */
1281 		if( talign(t2,sue2) < talign(t,sue) ){
1282 			t = t2;
1283 			q = q2;
1284 			sue = sue2;
1285 			}
1286 		break;
1287 		}
1288 
1289 	p->n_left = makety( p->n_left, t, q, d, sue );
1290 	p->n_right = makety( p->n_right, t, q, d, sue );
1291 	if( o!=MINUS && !clogop(o) ){
1292 
1293 		p->n_type = t;
1294 		p->n_qual = q;
1295 		p->n_df = d;
1296 		p->n_sue = sue;
1297 		}
1298 
1299 	return(clocal(p));
1300 	}
1301 
1302 int tdebug = 0;
1303 
1304 NODE *
1305 tymatch(p)  register NODE *p; {
1306 
1307 	/* satisfy the types of various arithmetic binary ops */
1308 
1309 	/* rules are:
1310 		if assignment, type of LHS
1311 		if any doubles, make double
1312 		else if any float make float
1313 		else if any longlongs, make long long
1314 		else if any longs, make long
1315 		else etcetc.
1316 		if either operand is unsigned, the result is...
1317 	*/
1318 
1319 	TWORD t1, t2, t, tu;
1320 	int o, lu, ru;
1321 
1322 	o = p->n_op;
1323 
1324 	t1 = p->n_left->n_type;
1325 	t2 = p->n_right->n_type;
1326 
1327 	lu = ru = 0;
1328 	if( ISUNSIGNED(t1) ){
1329 		lu = 1;
1330 		t1 = DEUNSIGN(t1);
1331 		}
1332 	if( ISUNSIGNED(t2) ){
1333 		ru = 1;
1334 		t2 = DEUNSIGN(t2);
1335 		}
1336 
1337 	if (Wsign_compare && clogop(o) && t1 == t2 && lu != ru &&
1338 	    p->n_left->n_op != ICON && p->n_right->n_op != ICON)
1339 		werror("comparison between signed and unsigned");
1340 
1341 #if 0
1342 	if ((t1 == CHAR || t1 == SHORT) && o!= RETURN)
1343 		t1 = INT;
1344 	if (t2 == CHAR || t2 == SHORT)
1345 		t2 = INT;
1346 #endif
1347 
1348 	if (t1 == LDOUBLE || t2 == LDOUBLE)
1349 		t = LDOUBLE;
1350 	else if (t1 == DOUBLE || t2 == DOUBLE)
1351 		t = DOUBLE;
1352 	else if (t1 == FLOAT || t2 == FLOAT)
1353 		t = FLOAT;
1354 	else if (t1==LONGLONG || t2 == LONGLONG)
1355 		t = LONGLONG;
1356 	else if (t1==LONG || t2==LONG)
1357 		t = LONG;
1358 	else /* if (t1==INT || t2==INT) */
1359 		t = INT;
1360 #if 0
1361 	else if (t1==SHORT || t2==SHORT)
1362 		t = SHORT;
1363 	else
1364 		t = CHAR;
1365 #endif
1366 
1367 	if( casgop(o) ){
1368 		tu = p->n_left->n_type;
1369 		t = t1;
1370 	} else {
1371 		tu = ((ru|lu) && UNSIGNABLE(t))?ENUNSIGN(t):t;
1372 	}
1373 
1374 	/* because expressions have values that are at least as wide
1375 	   as INT or UNSIGNED, the only conversions needed
1376 	   are those involving FLOAT/DOUBLE, and those
1377 	   from LONG to INT and ULONG to UNSIGNED */
1378 
1379 	if (t != t1 || (ru && !lu)) {
1380 		if (Wtruncate && o != CAST && p->n_right->n_op != ICON &&
1381 		    tsize(t1, 0, MKSUE(t2)) > tsize(tu, 0, MKSUE(tu)))
1382 			werror("conversion to '%s' from '%s' may alter its value",
1383 			    tnames[tu], tnames[t1]);
1384 		p->n_left = makety( p->n_left, tu, 0, 0, MKSUE(tu));
1385 	}
1386 
1387 	if (t != t2 || o==CAST || (lu && !ru)) {
1388 		if (Wtruncate && o != CAST && p->n_right->n_op != ICON &&
1389 		    tsize(t2, 0, MKSUE(t2)) > tsize(tu, 0, MKSUE(tu)))
1390 			werror("conversion to '%s' from '%s' may alter its value",
1391 			    tnames[tu], tnames[t2]);
1392 		p->n_right = makety(p->n_right, tu, 0, 0, MKSUE(tu));
1393 	}
1394 
1395 	if( casgop(o) ){
1396 		p->n_type = p->n_left->n_type;
1397 		p->n_df = p->n_left->n_df;
1398 		p->n_sue = p->n_left->n_sue;
1399 		}
1400 	else if( !clogop(o) ){
1401 		p->n_type = tu;
1402 		p->n_df = NULL;
1403 		p->n_sue = MKSUE(t);
1404 		}
1405 
1406 #ifdef PCC_DEBUG
1407 	if (tdebug) {
1408 		printf("tymatch(%p): ", p);
1409 		tprint(stdout, t1, 0);
1410 		printf(" %s ", copst(o));
1411 		tprint(stdout, t2, 0);
1412 		printf(" => ");
1413 		tprint(stdout, tu, 0);
1414 		printf("\n");
1415 		fwalk(p, eprint, 0);
1416 	}
1417 #endif
1418 
1419 	return(p);
1420 	}
1421 
1422 /*
1423  * Create a float const node of zero.
1424  */
1425 static NODE *
1426 fzero(TWORD t)
1427 {
1428 	NODE *p = block(FCON, NIL, NIL, t, 0, MKSUE(t));
1429 
1430 	p->n_dcon = FLOAT_CAST(0, INT);
1431 	return p;
1432 }
1433 
1434 /*
1435  * make p into type t by inserting a conversion
1436  */
1437 NODE *
1438 makety(NODE *p, TWORD t, TWORD q, union dimfun *d, struct suedef *sue)
1439 {
1440 
1441 	if (t == p->n_type) {
1442 		p->n_df = d;
1443 		p->n_sue = sue;
1444 		p->n_qual = q;
1445 		return(p);
1446 	}
1447 
1448 	if (p->n_op == FCON && (t >= FLOAT && t <= LDOUBLE)) {
1449 		if (t == FLOAT)
1450 			p->n_dcon = (float)p->n_dcon;
1451 		else if (t == DOUBLE)
1452 			p->n_dcon = (double)p->n_dcon;
1453 		else
1454 			p->n_dcon = (long double)p->n_dcon;
1455 		p->n_type = t;
1456 		return p;
1457 	}
1458 
1459 	if (p->n_op == FCON) {
1460 		int isf = ISFTY(t);
1461 		NODE *r;
1462 
1463 		if (isf||ISITY(t)) {
1464 			if (isf == ISFTY(p->n_type)) {
1465 				p->n_type = t;
1466 				p->n_qual = q;
1467 				p->n_df = d;
1468 				p->n_sue = sue;
1469 				return(p);
1470 			} else if (isf == ISITY(p->n_type)) {
1471 				/* will be zero */
1472 				nfree(p);
1473 				return fzero(t);
1474 			} else if (ISCTY(p->n_type))
1475 				cerror("complex constant");
1476 		} else if (ISCTY(t)) {
1477 			if (ISITY(p->n_type)) {
1478 				/* convert to correct subtype */
1479 				r = fzero(t - (COMPLEX-DOUBLE));
1480 				p->n_type = t + (IMAG-COMPLEX);
1481 				p->n_qual = q;
1482 				p->n_df = d;
1483 				p->n_sue = MKSUE(p->n_type);
1484 				return block(CM, r, p, t, 0, MKSUE(t));
1485 			} else if (ISFTY(p->n_type)) {
1486 				/* convert to correct subtype */
1487 				r = fzero(t + (IMAG-COMPLEX));
1488 				p->n_type = t - (COMPLEX-DOUBLE);
1489 				p->n_qual = q;
1490 				p->n_df = d;
1491 				p->n_sue = MKSUE(p->n_type);
1492 				return block(CM, p, r, t, 0, MKSUE(t));
1493 			} else if (ISCTY(p->n_type))
1494 				cerror("complex constant2");
1495 		}
1496 	}
1497 
1498 	if (t & TMASK) {
1499 		/* non-simple type */
1500 		p = block(PCONV, p, NIL, t, d, sue);
1501 		p->n_qual = q;
1502 		return clocal(p);
1503 	}
1504 
1505 	if (p->n_op == ICON) {
1506 		if (ISFTY(t)) {
1507 			p->n_op = FCON;
1508 			p->n_dcon = FLOAT_CAST(p->n_lval, p->n_type);
1509 			p->n_type = t;
1510 			p->n_qual = q;
1511 			p->n_sue = MKSUE(t);
1512 			return (clocal(p));
1513 		} else if (ISCTY(t) || ISITY(t))
1514 			cerror("complex constant3");
1515 	}
1516 
1517 	p = block(SCONV, p, NIL, t, d, sue);
1518 	p->n_qual = q;
1519 	return clocal(p);
1520 
1521 }
1522 
1523 NODE *
1524 block(int o, NODE *l, NODE *r, TWORD t, union dimfun *d, struct suedef *sue)
1525 {
1526 	register NODE *p;
1527 
1528 	p = talloc();
1529 	p->n_rval = 0;
1530 	p->n_op = o;
1531 	p->n_lval = 0; /* Protect against large lval */
1532 	p->n_left = l;
1533 	p->n_right = r;
1534 	p->n_type = t;
1535 	p->n_qual = 0;
1536 	p->n_df = d;
1537 	p->n_sue = sue;
1538 #if !defined(MULTIPASS)
1539 	/* p->n_reg = */p->n_su = 0;
1540 	p->n_regw = 0;
1541 #endif
1542 	return(p);
1543 	}
1544 
1545 /*
1546  * Return the constant value from an ICON.
1547  */
1548 CONSZ
1549 icons(NODE *p)
1550 {
1551 	/* if p is an integer constant, return its value */
1552 	CONSZ val;
1553 
1554 	if (p->n_op != ICON || p->n_sp != NULL) {
1555 		uerror( "constant expected");
1556 		val = 1;
1557 	} else
1558 		val = p->n_lval;
1559 	tfree(p);
1560 	return(val);
1561 }
1562 
1563 /*
1564  * the intent of this table is to examine the
1565  * operators, and to check them for
1566  * correctness.
1567  *
1568  * The table is searched for the op and the
1569  * modified type (where this is one of the
1570  * types INT (includes char and short), LONG,
1571  * DOUBLE (includes FLOAT), and POINTER
1572  *
1573  * The default action is to make the node type integer
1574  *
1575  * The actions taken include:
1576  * 	PUN	  check for puns
1577  * 	CVTL	  convert the left operand
1578  * 	CVTR	  convert the right operand
1579  * 	TYPL	  the type is determined by the left operand
1580  * 	TYPR	  the type is determined by the right operand
1581  * 	TYMATCH	  force type of left and right to match,by inserting conversions
1582  * 	PTMATCH	  like TYMATCH, but for pointers
1583  * 	LVAL	  left operand must be lval
1584  * 	CVTO	  convert the op
1585  * 	NCVT	  do not convert the operands
1586  * 	OTHER	  handled by code
1587  * 	NCVTR	  convert the left operand, not the right...
1588  *
1589  */
1590 
1591 # define MINT 01	/* integer */
1592 # define MDBI 02	/* integer or double */
1593 # define MSTR 04	/* structure */
1594 # define MPTR 010	/* pointer */
1595 # define MPTI 020	/* pointer or integer */
1596 
1597 int
1598 opact(NODE *p)
1599 {
1600 	int mt12, mt1, mt2, o;
1601 
1602 	mt1 = mt2 = mt12 = 0;
1603 
1604 	switch (coptype(o = p->n_op)) {
1605 	case BITYPE:
1606 		mt12=mt2 = moditype(p->n_right->n_type);
1607 	case UTYPE:
1608 		mt12 &= (mt1 = moditype(p->n_left->n_type));
1609 		break;
1610 	}
1611 
1612 	switch( o ){
1613 
1614 	case NAME :
1615 	case ICON :
1616 	case FCON :
1617 	case CALL :
1618 	case UCALL:
1619 	case UMUL:
1620 		{  return( OTHER ); }
1621 	case UMINUS:
1622 		if( mt1 & MDBI ) return( TYPL );
1623 		break;
1624 
1625 	case COMPL:
1626 		if( mt1 & MINT ) return( TYPL );
1627 		break;
1628 
1629 	case ADDROF:
1630 		return( NCVT+OTHER );
1631 	case NOT:
1632 /*	case INIT: */
1633 	case CM:
1634 	case CBRANCH:
1635 	case ANDAND:
1636 	case OROR:
1637 		return( 0 );
1638 
1639 	case MUL:
1640 	case DIV:
1641 		if( mt12 & MDBI ) return( TYMATCH );
1642 		break;
1643 
1644 	case MOD:
1645 	case AND:
1646 	case OR:
1647 	case ER:
1648 		if( mt12 & MINT ) return( TYMATCH );
1649 		break;
1650 
1651 	case LS:
1652 	case RS:
1653 		if( mt12 & MINT ) return( TYPL+OTHER );
1654 		break;
1655 
1656 	case EQ:
1657 	case NE:
1658 	case LT:
1659 	case LE:
1660 	case GT:
1661 	case GE:
1662 		if( mt12 & MDBI ) return( TYMATCH+CVTO );
1663 		else if( mt12 & MPTR ) return( PTMATCH+PUN+CVTO );
1664 		else if( mt12 & MPTI ) return( PTMATCH+PUN );
1665 		else break;
1666 
1667 	case QUEST:
1668 	case COMOP:
1669 		return( TYPR );
1670 
1671 	case STREF:
1672 		return( NCVTR+OTHER );
1673 
1674 	case FORCE:
1675 		return( TYPL );
1676 
1677 	case COLON:
1678 		if( mt12 & MDBI ) return( TYMATCH );
1679 		else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN );
1680 		else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN );
1681 		else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN );
1682 		else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER );
1683 		break;
1684 
1685 	case ASSIGN:
1686 	case RETURN:
1687 		if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER );
1688 	case CAST:
1689 		if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
1690 		else if( mt1 & MPTR) return( LVAL+PTMATCH+PUN );
1691 		else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
1692 		break;
1693 
1694 	case LSEQ:
1695 	case RSEQ:
1696 		if( mt12 & MINT ) return( TYPL+LVAL+OTHER );
1697 		break;
1698 
1699 	case MULEQ:
1700 	case DIVEQ:
1701 		if( mt12 & MDBI ) return( LVAL+TYMATCH );
1702 		break;
1703 
1704 	case MODEQ:
1705 	case ANDEQ:
1706 	case OREQ:
1707 	case EREQ:
1708 		if (mt12 & MINT)
1709 			return(LVAL+TYMATCH);
1710 		break;
1711 
1712 	case PLUSEQ:
1713 	case MINUSEQ:
1714 	case INCR:
1715 	case DECR:
1716 		if (mt12 & MDBI)
1717 			return(TYMATCH+LVAL);
1718 		else if ((mt1&MPTR) && (mt2&MINT))
1719 			return(TYPL+LVAL+CVTR);
1720 		break;
1721 
1722 	case MINUS:
1723 		if (mt12 & MPTR)
1724 			return(CVTO+PTMATCH+PUN);
1725 		if (mt2 & MPTR)
1726 			break;
1727 		/* FALLTHROUGH */
1728 	case PLUS:
1729 		if (mt12 & MDBI)
1730 			return(TYMATCH);
1731 		else if ((mt1&MPTR) && (mt2&MINT))
1732 			return(TYPL+CVTR);
1733 		else if ((mt1&MINT) && (mt2&MPTR))
1734 			return(TYPR+CVTL);
1735 
1736 	}
1737 	uerror("operands of %s have incompatible types", copst(o));
1738 	return(NCVT);
1739 }
1740 
1741 int
1742 moditype(TWORD ty)
1743 {
1744 	switch (ty) {
1745 
1746 	case STRTY:
1747 	case UNIONTY:
1748 		return( MSTR );
1749 
1750 	case BOOL:
1751 	case CHAR:
1752 	case SHORT:
1753 	case UCHAR:
1754 	case USHORT:
1755 	case UNSIGNED:
1756 	case ULONG:
1757 	case ULONGLONG:
1758 	case INT:
1759 	case LONG:
1760 	case LONGLONG:
1761 		return( MINT|MDBI|MPTI );
1762 	case FLOAT:
1763 	case DOUBLE:
1764 	case LDOUBLE:
1765 #ifndef NO_COMPLEX
1766 	case FCOMPLEX:
1767 	case COMPLEX:
1768 	case LCOMPLEX:
1769 	case FIMAG:
1770 	case IMAG:
1771 	case LIMAG:
1772 #endif
1773 		return( MDBI );
1774 	default:
1775 		return( MPTR|MPTI );
1776 
1777 	}
1778 }
1779 
1780 int tvaloff = MAXREGS+NPERMREG > 100 ? MAXREGS+NPERMREG + 100 : 100;
1781 
1782 /*
1783  * Returns a TEMP node with temp number nr.
1784  * If nr == 0, return a node with a new number.
1785  */
1786 NODE *
1787 tempnode(int nr, TWORD type, union dimfun *df, struct suedef *sue)
1788 {
1789 	NODE *r;
1790 
1791 	r = block(TEMP, NIL, NIL, type, df, sue);
1792 	regno(r) = nr ? nr : tvaloff;
1793 	tvaloff += szty(type);
1794 	return r;
1795 }
1796 
1797 /*
1798  * Do sizeof on p.
1799  */
1800 NODE *
1801 doszof(NODE *p)
1802 {
1803 	extern NODE *arrstk[10];
1804 	extern int arrstkp;
1805 	union dimfun *df;
1806 	TWORD ty;
1807 	NODE *rv, *q;
1808 	int astkp;
1809 
1810 	if (p->n_op == FLD)
1811 		uerror("can't apply sizeof to bit-field");
1812 
1813 	/*
1814 	 * Arrays may be dynamic, may need to make computations.
1815 	 */
1816 
1817 	rv = bcon(1);
1818 	df = p->n_df;
1819 	ty = p->n_type;
1820 	astkp = 0;
1821 	while (ISARY(ty)) {
1822 		if (df->ddim == NOOFFSET)
1823 			uerror("sizeof of incomplete type");
1824 		if (df->ddim < 0) {
1825 			if (arrstkp)
1826 				q = arrstk[astkp++];
1827 			else
1828 				q = tempnode(-df->ddim, INT, 0, MKSUE(INT));
1829 		} else
1830 			q = bcon(df->ddim);
1831 		rv = buildtree(MUL, rv, q);
1832 		df++;
1833 		ty = DECREF(ty);
1834 	}
1835 	rv = buildtree(MUL, rv, bcon(tsize(ty, p->n_df, p->n_sue)/SZCHAR));
1836 	tfree(p);
1837 	arrstkp = 0; /* XXX - may this fail? */
1838 	return rv;
1839 }
1840 
1841 #ifdef PCC_DEBUG
1842 void
1843 eprint(NODE *p, int down, int *a, int *b)
1844 {
1845 	int ty;
1846 
1847 	*a = *b = down+1;
1848 	while( down > 1 ){
1849 		printf( "\t" );
1850 		down -= 2;
1851 		}
1852 	if( down ) printf( "    " );
1853 
1854 	ty = coptype( p->n_op );
1855 
1856 	printf("%p) %s, ", p, copst(p->n_op));
1857 	if (p->n_op == XARG || p->n_op == XASM)
1858 		printf("id '%s', ", p->n_name);
1859 	if (ty == LTYPE) {
1860 		printf(CONFMT, p->n_lval);
1861 		printf(", %d, ", (p->n_op != NAME && p->n_op != ICON) ?
1862 		    p->n_rval : 0);
1863 	}
1864 	tprint(stdout, p->n_type, p->n_qual);
1865 	printf( ", %p, %p\n", p->n_df, p->n_sue );
1866 }
1867 # endif
1868 
1869 /*
1870  * Emit everything that should be emitted on the left side
1871  * of a comma operator, and remove the operator.
1872  * Do not traverse through QUEST, ANDAND and OROR.
1873  * Enable this for all targets when stable enough.
1874  */
1875 static void
1876 comops(NODE *p)
1877 {
1878 	int o;
1879 	NODE *q;
1880 
1881 	while (p->n_op == COMOP) {
1882 		/* XXX hack for GCC ({ }) ops */
1883 		if (p->n_left->n_op == GOTO) {
1884 			int v = (int)p->n_left->n_left->n_lval;
1885 			ecomp(p->n_left);
1886 			plabel(v+1);
1887 		} else
1888 			ecomp(p->n_left); /* will recurse if more COMOPs */
1889 		q = p->n_right;
1890 		*p = *q;
1891 		nfree(q);
1892 	}
1893 	o = coptype(p->n_op);
1894 	if (p->n_op == QUEST || p->n_op == ANDAND || p->n_op == OROR)
1895 		o = UTYPE;
1896 	if (o != LTYPE)
1897 		comops(p->n_left);
1898 	if (o == BITYPE)
1899 		comops(p->n_right);
1900 }
1901 
1902 /*
1903  * Walk up through the tree from the leaves,
1904  * removing constant operators.
1905  */
1906 static void
1907 logwalk(NODE *p)
1908 {
1909 	int o = coptype(p->n_op);
1910 	NODE *l, *r;
1911 
1912 	l = p->n_left;
1913 	r = p->n_right;
1914 	switch (o) {
1915 	case LTYPE:
1916 		return;
1917 	case BITYPE:
1918 		logwalk(r);
1919 	case UTYPE:
1920 		logwalk(l);
1921 	}
1922 	if (!clogop(p->n_op))
1923 		return;
1924 	if (p->n_op == NOT && l->n_op == ICON) {
1925 		p->n_lval = l->n_lval == 0;
1926 		nfree(l);
1927 		p->n_op = ICON;
1928 	}
1929 	if (l->n_op == ICON && r->n_op == ICON) {
1930 		if (conval(l, p->n_op, r) == 0) {
1931 			/*
1932 			 * people sometimes tend to do really odd compares,
1933 			 * like "if ("abc" == "def")" etc.
1934 			 * do it runtime instead.
1935 			 */
1936 		} else {
1937 			p->n_lval = l->n_lval;
1938 			p->n_op = ICON;
1939 			nfree(l);
1940 			nfree(r);
1941 		}
1942 	}
1943 }
1944 
1945 /*
1946  * Removes redundant logical operators for branch conditions.
1947  */
1948 static void
1949 fixbranch(NODE *p, int label)
1950 {
1951 
1952 	logwalk(p);
1953 
1954 	if (p->n_op == ICON) {
1955 		if (p->n_lval != 0)
1956 			branch(label);
1957 		nfree(p);
1958 	} else {
1959 		if (!clogop(p->n_op)) /* Always conditional */
1960 			p = buildtree(NE, p, bcon(0));
1961 		ecode(buildtree(CBRANCH, p, bcon(label)));
1962 	}
1963 }
1964 
1965 /*
1966  * Write out logical expressions as branches.
1967  */
1968 static void
1969 andorbr(NODE *p, int true, int false)
1970 {
1971 	NODE *q;
1972 	int o, lab;
1973 
1974 	lab = -1;
1975 	switch (o = p->n_op) {
1976 	case EQ:
1977 	case NE:
1978 		/*
1979 		 * Remove redundant EQ/NE nodes.
1980 		 */
1981 		while (((o = p->n_left->n_op) == EQ || o == NE) &&
1982 		    p->n_right->n_op == ICON) {
1983 			o = p->n_op;
1984 			q = p->n_left;
1985 			if (p->n_right->n_lval == 0) {
1986 				nfree(p->n_right);
1987 				*p = *q;
1988 				nfree(q);
1989 				if (o == EQ)
1990 					p->n_op = negrel[p->n_op - EQ];
1991 #if 0
1992 					p->n_op = NE; /* toggla */
1993 #endif
1994 			} else if (p->n_right->n_lval == 1) {
1995 				nfree(p->n_right);
1996 				*p = *q;
1997 				nfree(q);
1998 				if (o == NE)
1999 					p->n_op = negrel[p->n_op - EQ];
2000 #if 0
2001 					p->n_op = EQ; /* toggla */
2002 #endif
2003 			} else
2004 				break; /* XXX - should always be false */
2005 
2006 		}
2007 		/* FALLTHROUGH */
2008 	case LE:
2009 	case LT:
2010 	case GE:
2011 	case GT:
2012 calc:		if (true < 0) {
2013 			p->n_op = negrel[p->n_op - EQ];
2014 			true = false;
2015 			false = -1;
2016 		}
2017 
2018 		rmcops(p->n_left);
2019 		rmcops(p->n_right);
2020 		fixbranch(p, true);
2021 		if (false >= 0)
2022 			branch(false);
2023 		break;
2024 
2025 	case ULE:
2026 	case UGT:
2027 		/* Convert to friendlier ops */
2028 		if (p->n_right->n_op == ICON && p->n_right->n_lval == 0)
2029 			p->n_op = o == ULE ? EQ : NE;
2030 		goto calc;
2031 
2032 	case UGE:
2033 	case ULT:
2034 		/* Already true/false by definition */
2035 		if (p->n_right->n_op == ICON && p->n_right->n_lval == 0) {
2036 			if (true < 0) {
2037 				o = o == ULT ? UGE : ULT;
2038 				true = false;
2039 			}
2040 			rmcops(p->n_left);
2041 			ecode(p->n_left);
2042 			rmcops(p->n_right);
2043 			ecode(p->n_right);
2044 			nfree(p);
2045 			if (o == UGE) /* true */
2046 				branch(true);
2047 			break;
2048 		}
2049 		goto calc;
2050 
2051 	case ANDAND:
2052 		lab = false<0 ? getlab() : false ;
2053 		andorbr(p->n_left, -1, lab);
2054 		comops(p->n_right);
2055 		andorbr(p->n_right, true, false);
2056 		if (false < 0)
2057 			plabel( lab);
2058 		nfree(p);
2059 		break;
2060 
2061 	case OROR:
2062 		lab = true<0 ? getlab() : true;
2063 		andorbr(p->n_left, lab, -1);
2064 		comops(p->n_right);
2065 		andorbr(p->n_right, true, false);
2066 		if (true < 0)
2067 			plabel( lab);
2068 		nfree(p);
2069 		break;
2070 
2071 	case NOT:
2072 		andorbr(p->n_left, false, true);
2073 		nfree(p);
2074 		break;
2075 
2076 	default:
2077 		rmcops(p);
2078 		if (true >= 0)
2079 			fixbranch(p, true);
2080 		if (false >= 0) {
2081 			if (true >= 0)
2082 				branch(false);
2083 			else
2084 				fixbranch(buildtree(EQ, p, bcon(0)), false);
2085 		}
2086 	}
2087 }
2088 
2089 /*
2090  * Massage the output trees to remove C-specific nodes:
2091  *	COMOPs are split into separate statements.
2092  *	QUEST/COLON are rewritten to branches.
2093  *	ANDAND/OROR/NOT are rewritten to branches for lazy-evaluation.
2094  *	CBRANCH conditions are rewritten for lazy-evaluation.
2095  */
2096 static void
2097 rmcops(NODE *p)
2098 {
2099 	TWORD type;
2100 	NODE *q, *r;
2101 	int o, ty, lbl, lbl2, tval = 0;
2102 
2103 	o = p->n_op;
2104 	ty = coptype(o);
2105 	if (BTYPE(p->n_type) == ENUMTY) { /* fixup enum */
2106 		MODTYPE(p->n_type, p->n_sue->suem->stype);
2107 		/*
2108 		 * XXX may fail if these are true:
2109 		 * - variable-sized enums
2110 		 * - non-byte-addressed targets.
2111 		 */
2112 		if (BTYPE(p->n_type) == ENUMTY && ISPTR(p->n_type))
2113 			MODTYPE(p->n_type, INT); /* INT ok? */
2114 	}
2115 	switch (o) {
2116 	case QUEST:
2117 
2118 		/*
2119 		 * Create a branch node from ?:
2120 		 * || and && must be taken special care of.
2121 		 */
2122 		type = p->n_type;
2123 		andorbr(p->n_left, -1, lbl = getlab());
2124 
2125 		/* Make ASSIGN node */
2126 		/* Only if type is not void */
2127 		q = p->n_right->n_left;
2128 		comops(q);
2129 		if (type != VOID) {
2130 			r = tempnode(0, q->n_type, q->n_df, q->n_sue);
2131 			tval = regno(r);
2132 			q = buildtree(ASSIGN, r, q);
2133 		}
2134 		rmcops(q);
2135 		ecode(q); /* Done with assign */
2136 		branch(lbl2 = getlab());
2137 		plabel( lbl);
2138 
2139 		q = p->n_right->n_right;
2140 		comops(q);
2141 		if (type != VOID) {
2142 			r = tempnode(tval, q->n_type, q->n_df, q->n_sue);
2143 			q = buildtree(ASSIGN, r, q);
2144 		}
2145 		rmcops(q);
2146 		ecode(q); /* Done with assign */
2147 
2148 		plabel( lbl2);
2149 
2150 		nfree(p->n_right);
2151 		if (p->n_type != VOID) {
2152 			r = tempnode(tval, p->n_type, p->n_df, p->n_sue);
2153 			*p = *r;
2154 			nfree(r);
2155 		} else {
2156 			p->n_op = ICON;
2157 			p->n_lval = 0;
2158 			p->n_sp = NULL;
2159 		}
2160 		break;
2161 
2162 	case ULE:
2163 	case ULT:
2164 	case UGE:
2165 	case UGT:
2166 	case EQ:
2167 	case NE:
2168 	case LE:
2169 	case LT:
2170 	case GE:
2171 	case GT:
2172 	case ANDAND:
2173 	case OROR:
2174 	case NOT:
2175 #ifdef SPECIAL_CCODES
2176 #error fix for private CCODES handling
2177 #else
2178 		r = talloc();
2179 		*r = *p;
2180 		andorbr(r, -1, lbl = getlab());
2181 		q = tempnode(0, p->n_type, p->n_df, p->n_sue);
2182 		tval = regno(q);
2183 		r = tempnode(tval, p->n_type, p->n_df, p->n_sue);
2184 		ecode(buildtree(ASSIGN, q, bcon(1)));
2185 		branch(lbl2 = getlab());
2186 		plabel( lbl);
2187 		ecode(buildtree(ASSIGN, r, bcon(0)));
2188 		plabel( lbl2);
2189 		r = tempnode(tval, p->n_type, p->n_df, p->n_sue);
2190 		*p = *r;
2191 		nfree(r);
2192 #endif
2193 		break;
2194 	case CBRANCH:
2195 		andorbr(p->n_left, p->n_right->n_lval, -1);
2196 		nfree(p->n_right);
2197 		p->n_op = ICON; p->n_type = VOID;
2198 		break;
2199 	case COMOP:
2200 		cerror("COMOP error");
2201 
2202 	default:
2203 		if (ty == LTYPE)
2204 			return;
2205 		rmcops(p->n_left);
2206 		if (ty == BITYPE)
2207 			rmcops(p->n_right);
2208        }
2209 }
2210 
2211 /*
2212  * Return 1 if an assignment is found.
2213  */
2214 static int
2215 has_se(NODE *p)
2216 {
2217 	if (cdope(p->n_op) & ASGFLG)
2218 		return 1;
2219 	if (coptype(p->n_op) == LTYPE)
2220 		return 0;
2221 	if (has_se(p->n_left))
2222 		return 1;
2223 	if (coptype(p->n_op) == BITYPE)
2224 		return has_se(p->n_right);
2225 	return 0;
2226 }
2227 
2228 /*
2229  * Find and convert asgop's to separate statements.
2230  * Be careful about side effects.
2231  * assign tells whether ASSIGN should be considered giving
2232  * side effects or not.
2233  */
2234 static NODE *
2235 delasgop(NODE *p)
2236 {
2237 	NODE *q, *r;
2238 	int tval;
2239 
2240 	if (p->n_op == INCR || p->n_op == DECR) {
2241 		/*
2242 		 * Rewrite x++ to (x += 1) -1; and deal with it further down.
2243 		 * Pass2 will remove -1 if unnecessary.
2244 		 */
2245 		q = ccopy(p);
2246 		tfree(p->n_left);
2247 		q->n_op = (p->n_op==INCR)?PLUSEQ:MINUSEQ;
2248 		p->n_op = (p->n_op==INCR)?MINUS:PLUS;
2249 		p->n_left = delasgop(q);
2250 
2251 	} else if ((cdope(p->n_op)&ASGOPFLG) &&
2252 	    p->n_op != RETURN && p->n_op != CAST) {
2253 		NODE *l = p->n_left;
2254 		NODE *ll = l->n_left;
2255 
2256 		if (has_se(l)) {
2257 			q = tempnode(0, ll->n_type, ll->n_df, ll->n_sue);
2258 			tval = regno(q);
2259 			r = tempnode(tval, ll->n_type, ll->n_df,ll->n_sue);
2260 			l->n_left = q;
2261 			/* Now the left side of node p has no side effects. */
2262 			/* side effects on the right side must be obeyed */
2263 			p = delasgop(p);
2264 
2265 			r = buildtree(ASSIGN, r, ll);
2266 			r = delasgop(r);
2267 			ecode(r);
2268 		} else {
2269 #if 0 /* Cannot call buildtree() here, it would invoke double add shifts */
2270 			p->n_right = buildtree(UNASG p->n_op, ccopy(l),
2271 			    p->n_right);
2272 #else
2273 			p->n_right = block(UNASG p->n_op, ccopy(l),
2274 			    p->n_right, p->n_type, p->n_df, p->n_sue);
2275 #endif
2276 			p->n_op = ASSIGN;
2277 			p->n_right = delasgop(p->n_right);
2278 			p->n_right = clocal(p->n_right);
2279 		}
2280 
2281 	} else {
2282 		if (coptype(p->n_op) == LTYPE)
2283 			return p;
2284 		p->n_left = delasgop(p->n_left);
2285 		if (coptype(p->n_op) == BITYPE)
2286 			p->n_right = delasgop(p->n_right);
2287 	}
2288 	return p;
2289 }
2290 
2291 int edebug = 0;
2292 void
2293 ecomp(NODE *p)
2294 {
2295 
2296 #ifdef PCC_DEBUG
2297 	if (edebug)
2298 		fwalk(p, eprint, 0);
2299 #endif
2300 	if (!reached) {
2301 		if (Wunreachable_code)
2302 			werror("statement not reached");
2303 		reached = 1;
2304 	}
2305 	p = optim(p);
2306 	comops(p);
2307 	rmcops(p);
2308 	p = delasgop(p);
2309 	if (p->n_op == ICON && p->n_type == VOID)
2310 		tfree(p);
2311 	else
2312 		ecode(p);
2313 }
2314 
2315 
2316 #if defined(MULTIPASS)
2317 void
2318 p2tree(NODE *p)
2319 {
2320 	struct symtab *q;
2321 	int ty;
2322 
2323 	myp2tree(p);  /* local action can be taken here */
2324 
2325 	ty = coptype(p->n_op);
2326 
2327 	printf("%d\t", p->n_op);
2328 
2329 	if (ty == LTYPE) {
2330 		printf(CONFMT, p->n_lval);
2331 		printf("\t");
2332 	}
2333 	if (ty != BITYPE) {
2334 		if (p->n_op == NAME || p->n_op == ICON)
2335 			printf("0\t");
2336 		else
2337 			printf("%d\t", p->n_rval);
2338 		}
2339 
2340 	printf("%o\t", p->n_type);
2341 
2342 	/* handle special cases */
2343 
2344 	switch (p->n_op) {
2345 
2346 	case NAME:
2347 	case ICON:
2348 		/* print external name */
2349 		if ((q = p->n_sp) != NULL) {
2350 			if ((q->sclass == STATIC && q->slevel > 0)) {
2351 				printf(LABFMT, q->soffset);
2352 			} else
2353 				printf("%s\n",
2354 				    q->soname ? q->soname : exname(q->sname));
2355 		} else
2356 			printf("\n");
2357 		break;
2358 
2359 	case STARG:
2360 	case STASG:
2361 	case STCALL:
2362 	case USTCALL:
2363 		/* print out size */
2364 		/* use lhs size, in order to avoid hassles
2365 		 * with the structure `.' operator
2366 		 */
2367 
2368 		/* note: p->left not a field... */
2369 		printf(CONFMT, (CONSZ)tsize(STRTY, p->n_left->n_df,
2370 		    p->n_left->n_sue));
2371 		printf("\t%d\t\n", talign(STRTY, p->n_left->n_sue));
2372 		break;
2373 
2374 	case XARG:
2375 	case XASM:
2376 		break;
2377 
2378 	default:
2379 		printf(	 "\n" );
2380 	}
2381 
2382 	if (ty != LTYPE)
2383 		p2tree(p->n_left);
2384 	if (ty == BITYPE)
2385 		p2tree(p->n_right);
2386 }
2387 #else
2388 static char *
2389 sptostr(struct symtab *sp)
2390 {
2391 	char *cp = inlalloc(32);
2392 	int n = sp->soffset;
2393 	if (n < 0)
2394 		n = -n;
2395 	snprintf(cp, 32, LABFMT, n);
2396 	return cp;
2397 }
2398 
2399 void
2400 p2tree(NODE *p)
2401 {
2402 	struct symtab *q;
2403 	int ty;
2404 
2405 	myp2tree(p);  /* local action can be taken here */
2406 
2407 	ty = coptype(p->n_op);
2408 
2409 	switch( p->n_op ){
2410 
2411 	case NAME:
2412 	case ICON:
2413 		if ((q = p->n_sp) != NULL) {
2414 			if ((q->sclass == STATIC && q->slevel > 0)
2415 #ifdef GCC_COMPAT
2416 			    || q->sflags == SLBLNAME
2417 #endif
2418 			    ) {
2419 				p->n_name = sptostr(q);
2420 			} else {
2421 				if ((p->n_name = q->soname) == NULL)
2422 					p->n_name = addname(exname(q->sname));
2423 			}
2424 		} else
2425 			p->n_name = "";
2426 		break;
2427 
2428 	case STASG:
2429 		/* STASG used for stack array init */
2430 		if (ISARY(p->n_type)) {
2431 			int size1 = (int)tsize(p->n_type, p->n_left->n_df,
2432 			    p->n_left->n_sue)/SZCHAR;
2433 			p->n_stsize = (int)tsize(p->n_type, p->n_right->n_df,
2434 			    p->n_right->n_sue)/SZCHAR;
2435 			if (size1 < p->n_stsize)
2436 				p->n_stsize = size1;
2437 			p->n_stalign = talign(p->n_type,
2438 			    p->n_left->n_sue)/SZCHAR;
2439 			break;
2440 		}
2441 		/* FALLTHROUGH */
2442 	case STARG:
2443 	case STCALL:
2444 	case USTCALL:
2445 		/* set up size parameters */
2446 		p->n_stsize = (int)((tsize(STRTY, p->n_left->n_df,
2447 		    p->n_left->n_sue)+SZCHAR-1)/SZCHAR);
2448 		p->n_stalign = talign(STRTY,p->n_left->n_sue)/SZCHAR;
2449 		if (p->n_stalign == 0)
2450 			p->n_stalign = 1; /* At least char for packed structs */
2451 		break;
2452 
2453 	case XARG:
2454 	case XASM:
2455 		break;
2456 
2457 	default:
2458 		p->n_name = "";
2459 		}
2460 
2461 	if( ty != LTYPE ) p2tree( p->n_left );
2462 	if( ty == BITYPE ) p2tree( p->n_right );
2463 	}
2464 
2465 #endif
2466 
2467 /*
2468  * Change void data types into char.
2469  */
2470 static void
2471 delvoid(NODE *p, void *arg)
2472 {
2473 	/* Convert "PTR undef" (void *) to "PTR uchar" */
2474 	if (BTYPE(p->n_type) == VOID)
2475 		p->n_type = (p->n_type & ~BTMASK) | UCHAR;
2476 	if (BTYPE(p->n_type) == BOOL) {
2477 		if (p->n_op == SCONV && p->n_type == BOOL) {
2478 			/* create a jump and a set */
2479 			NODE *q, *r, *s;
2480 			int l, val;
2481 
2482 			q = talloc();
2483 			*q = *p;
2484 			q->n_type = BOOL_TYPE;
2485 			r = tempnode(0, BOOL_TYPE, NULL, MKSUE(BOOL_TYPE));
2486 			val = regno(r);
2487 			s = tempnode(val, BOOL_TYPE, NULL, MKSUE(BOOL_TYPE));
2488 			*p = *s;
2489 			q = buildtree(ASSIGN, r, q);
2490 			cbranch(buildtree(EQ, q, bcon(0)), bcon(l = getlab()));
2491 			ecode(buildtree(ASSIGN, s, bcon(1)));
2492 			plabel(l);
2493 		} else
2494 			p->n_type = (p->n_type & ~BTMASK) | BOOL_TYPE;
2495 	}
2496 
2497 }
2498 
2499 void
2500 ecode(NODE *p)
2501 {
2502 	/* walk the tree and write out the nodes.. */
2503 
2504 	if (nerrors)
2505 		return;
2506 
2507 #ifdef GCC_COMPAT
2508 	{
2509 		NODE *q = p;
2510 
2511 		if (q->n_op == UMUL)
2512 			q = p->n_left;
2513 		if (cdope(q->n_op)&CALLFLG &&
2514 		    gcc_get_attr(q->n_sue, GCC_ATYP_WARN_UNUSED_RESULT))
2515 			werror("return value ignored");
2516 	}
2517 #endif
2518 	p = optim(p);
2519 	p = delasgop(p);
2520 	walkf(p, delvoid, 0);
2521 #ifdef PCC_DEBUG
2522 	if (xdebug) {
2523 		printf("Fulltree:\n");
2524 		fwalk(p, eprint, 0);
2525 	}
2526 #endif
2527 	p2tree(p);
2528 #if !defined(MULTIPASS)
2529 	send_passt(IP_NODE, p);
2530 #endif
2531 }
2532 
2533 /*
2534  * Send something further on to the next pass.
2535  */
2536 void
2537 send_passt(int type, ...)
2538 {
2539 	struct interpass *ip;
2540 	struct interpass_prolog *ipp;
2541 	extern int crslab;
2542 	va_list ap;
2543 	int sz;
2544 
2545 	va_start(ap, type);
2546 	if (type == IP_PROLOG || type == IP_EPILOG)
2547 		sz = sizeof(struct interpass_prolog);
2548 	else
2549 		sz = sizeof(struct interpass);
2550 
2551 	ip = inlalloc(sz);
2552 	ip->type = type;
2553 	ip->lineno = lineno;
2554 	switch (type) {
2555 	case IP_NODE:
2556 		ip->ip_node = va_arg(ap, NODE *);
2557 		break;
2558 	case IP_EPILOG:
2559 		if (!isinlining)
2560 			defloc(cftnsp);
2561 		/* FALLTHROUGH */
2562 	case IP_PROLOG:
2563 		inftn = type == IP_PROLOG ? 1 : 0;
2564 		ipp = (struct interpass_prolog *)ip;
2565 		memset(ipp->ipp_regs, (type == IP_PROLOG)? -1 : 0,
2566 		    sizeof(ipp->ipp_regs));
2567 		ipp->ipp_autos = va_arg(ap, int);
2568 		ipp->ipp_name = va_arg(ap, char *);
2569 		ipp->ipp_type = va_arg(ap, TWORD);
2570 		ipp->ipp_vis = va_arg(ap, int);
2571 		ip->ip_lbl = va_arg(ap, int);
2572 		ipp->ip_tmpnum = va_arg(ap, int);
2573 		ipp->ip_lblnum = crslab;
2574 		if (type == IP_PROLOG)
2575 			ipp->ip_lblnum--;
2576 		break;
2577 	case IP_DEFLAB:
2578 		ip->ip_lbl = va_arg(ap, int);
2579 		break;
2580 	case IP_ASM:
2581 		if (blevel == 0) { /* outside function */
2582 			printf("\t");
2583 			printf("%s", va_arg(ap, char *));
2584 			printf("\n");
2585 			va_end(ap);
2586 			defloc(NULL);
2587 			return;
2588 		}
2589 		ip->ip_asm = va_arg(ap, char *);
2590 		break;
2591 	default:
2592 		cerror("bad send_passt type %d", type);
2593 	}
2594 	va_end(ap);
2595 	pass1_lastchance(ip); /* target-specific info */
2596 	if (isinlining)
2597 		inline_addarg(ip);
2598 	else
2599 		pass2_compile(ip);
2600 }
2601 
2602 char *
2603 copst(int op)
2604 {
2605 	if (op <= MAXOP)
2606 		return opst[op];
2607 #define	SNAM(x,y) case x: return #y;
2608 	switch (op) {
2609 	SNAM(QUALIFIER,QUALIFIER)
2610 	SNAM(CLASS,CLASS)
2611 	SNAM(RB,])
2612 	SNAM(DOT,.)
2613 	SNAM(ELLIPSIS,...)
2614 	SNAM(LB,[)
2615 	SNAM(TYPE,TYPE)
2616 	SNAM(COMOP,COMOP)
2617 	SNAM(QUEST,?)
2618 	SNAM(COLON,:)
2619 	SNAM(ANDAND,&&)
2620 	SNAM(OROR,||)
2621 	SNAM(NOT,!)
2622 	SNAM(CAST,CAST)
2623 	SNAM(PLUSEQ,+=)
2624 	SNAM(MINUSEQ,-=)
2625 	SNAM(MULEQ,*=)
2626 	SNAM(DIVEQ,/=)
2627 	SNAM(MODEQ,%=)
2628 	SNAM(ANDEQ,&=)
2629 	SNAM(OREQ,|=)
2630 	SNAM(EREQ,^=)
2631 	SNAM(LSEQ,<<=)
2632 	SNAM(RSEQ,>>=)
2633 	SNAM(INCR,++)
2634 	SNAM(DECR,--)
2635 	SNAM(STRING,STRING)
2636 	SNAM(SZOF,SIZEOF)
2637 	SNAM(ATTRIB,ATTRIBUTE)
2638 #ifdef GCC_COMPAT
2639 	SNAM(XREAL,__real__)
2640 	SNAM(XIMAG,__imag__)
2641 #endif
2642 	default:
2643 		cerror("bad copst %d", op);
2644 	}
2645 	return 0; /* XXX gcc */
2646 }
2647 
2648 int
2649 cdope(int op)
2650 {
2651 	if (op <= MAXOP)
2652 		return dope[op];
2653 	switch (op) {
2654 	case CLOP:
2655 	case STRING:
2656 	case QUALIFIER:
2657 	case CLASS:
2658 	case RB:
2659 	case ELLIPSIS:
2660 	case TYPE:
2661 		return LTYPE;
2662 	case DOT:
2663 	case SZOF:
2664 	case COMOP:
2665 	case QUEST:
2666 	case COLON:
2667 	case LB:
2668 		return BITYPE;
2669 	case XIMAG:
2670 	case XREAL:
2671 	case ATTRIB:
2672 		return UTYPE;
2673 	case ANDAND:
2674 	case OROR:
2675 		return BITYPE|LOGFLG;
2676 	case NOT:
2677 		return UTYPE|LOGFLG;
2678 	case CAST:
2679 		return BITYPE|ASGFLG|ASGOPFLG;
2680 	case PLUSEQ:
2681 		return BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG;
2682 	case MINUSEQ:
2683 		return BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG;
2684 	case MULEQ:
2685 		return BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG;
2686 	case OREQ:
2687 	case EREQ:
2688 	case ANDEQ:
2689 		return BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG;
2690 	case DIVEQ:
2691 		return BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG;
2692 	case MODEQ:
2693 		return BITYPE|DIVFLG|ASGFLG|ASGOPFLG;
2694 	case LSEQ:
2695 	case RSEQ:
2696 		return BITYPE|SHFFLG|ASGFLG|ASGOPFLG;
2697 	case INCR:
2698 	case DECR:
2699 		return BITYPE|ASGFLG;
2700 	}
2701 	cerror("cdope missing op %d", op);
2702 	return 0; /* XXX gcc */
2703 }
2704 
2705 /*
2706  * make a fresh copy of p
2707  */
2708 NODE *
2709 ccopy(NODE *p)
2710 {
2711 	NODE *q;
2712 
2713 	q = talloc();
2714 	*q = *p;
2715 
2716 	switch (coptype(q->n_op)) {
2717 	case BITYPE:
2718 		q->n_right = ccopy(p->n_right);
2719 	case UTYPE:
2720 		q->n_left = ccopy(p->n_left);
2721 	}
2722 
2723 	return(q);
2724 }
2725 
2726 /*
2727  * set PROG-seg label.
2728  */
2729 void
2730 plabel(int label)
2731 {
2732 	reached = 1; /* Will this always be correct? */
2733 	send_passt(IP_DEFLAB, label);
2734 }
2735 
2736 /*
2737  * Perform integer promotion on node n.
2738  */
2739 NODE *
2740 intprom(NODE *n)
2741 {
2742 	if ((n->n_type >= CHAR && n->n_type < INT) || n->n_type == BOOL) {
2743 		if ((n->n_type == UCHAR && MAX_UCHAR > MAX_INT) ||
2744 		    (n->n_type == USHORT && MAX_USHORT > MAX_INT))
2745 			return makety(n, UNSIGNED, 0, 0, MKSUE(UNSIGNED));
2746 		return makety(n, INT, 0, 0, MKSUE(INT));
2747 	}
2748 	return n;
2749 }
2750 
2751 /*
2752  * Return CON/VOL/0, whichever are active for the current type.
2753  */
2754 int
2755 cqual(TWORD t, TWORD q)
2756 {
2757 	while (ISARY(t))
2758 		t = DECREF(t), q = DECQAL(q);
2759 	if (t <= BTMASK)
2760 		q <<= TSHIFT;
2761 	return q & (CON|VOL);
2762 }
2763 
2764 int crslab = 10;
2765 /*
2766  * Return a number for internal labels.
2767  */
2768 int
2769 getlab(void)
2770 {
2771 	return crslab++;
2772 }
2773