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