mirror of
				https://github.com/golang/go.git
				synced 2025-11-03 18:20:59 +00:00 
			
		
		
		
	bug in stack size used in
extending segmented stack R=r OCL=27319 CL=27319
This commit is contained in:
		
							parent
							
								
									78edbfdcf4
								
							
						
					
					
						commit
						cb15bbe748
					
				
					 2 changed files with 1 additions and 551 deletions
				
			
		| 
						 | 
				
			
			@ -37,7 +37,7 @@ argsize(void)
 | 
			
		|||
	int32 s;
 | 
			
		||||
 | 
			
		||||
//print("t=%T\n", thisfn);
 | 
			
		||||
	s = 0;
 | 
			
		||||
	s = align(0, thisfn->link, Aarg0);
 | 
			
		||||
	for(t=thisfn->down; t!=T; t=t->down) {
 | 
			
		||||
		switch(t->etype) {
 | 
			
		||||
		case TVOID:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,550 +0,0 @@
 | 
			
		|||
// Inferno utils/6c/sgen.c
 | 
			
		||||
// http://code.google.com/p/inferno-os/source/browse/utils/6c/sgen.c
 | 
			
		||||
//
 | 
			
		||||
//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
 | 
			
		||||
//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
 | 
			
		||||
//	Portions Copyright © 1997-1999 Vita Nuova Limited
 | 
			
		||||
//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
 | 
			
		||||
//	Portions Copyright © 2004,2006 Bruce Ellis
 | 
			
		||||
//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
 | 
			
		||||
//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
 | 
			
		||||
//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
 | 
			
		||||
//
 | 
			
		||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
			
		||||
// of this software and associated documentation files (the "Software"), to deal
 | 
			
		||||
// in the Software without restriction, including without limitation the rights
 | 
			
		||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
			
		||||
// copies of the Software, and to permit persons to whom the Software is
 | 
			
		||||
// furnished to do so, subject to the following conditions:
 | 
			
		||||
//
 | 
			
		||||
// The above copyright notice and this permission notice shall be included in
 | 
			
		||||
// all copies or substantial portions of the Software.
 | 
			
		||||
//
 | 
			
		||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
			
		||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
			
		||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 | 
			
		||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
			
		||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
			
		||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | 
			
		||||
// THE SOFTWARE.
 | 
			
		||||
 | 
			
		||||
#include "gc.h"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
codgen(Node *n, Node *nn)
 | 
			
		||||
{
 | 
			
		||||
	Prog *sp;
 | 
			
		||||
	Node *n1, nod, nod1;
 | 
			
		||||
 | 
			
		||||
	cursafe = 0;
 | 
			
		||||
	curarg = 0;
 | 
			
		||||
	maxargsafe = 0;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * isolate name
 | 
			
		||||
	 */
 | 
			
		||||
	for(n1 = nn;; n1 = n1->left) {
 | 
			
		||||
		if(n1 == Z) {
 | 
			
		||||
			diag(nn, "cant find function name");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		if(n1->op == ONAME)
 | 
			
		||||
			break;
 | 
			
		||||
	}
 | 
			
		||||
	nearln = nn->lineno;
 | 
			
		||||
	gpseudo(ATEXT, n1->sym, nodconst(stkoff));
 | 
			
		||||
	sp = p;
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * isolate first argument
 | 
			
		||||
	 */
 | 
			
		||||
	if(REGARG) {	
 | 
			
		||||
		if(typecmplx[thisfn->link->etype]) {
 | 
			
		||||
			nod1 = *nodret->left;
 | 
			
		||||
			nodreg(&nod, &nod1, REGARG);
 | 
			
		||||
			gmove(&nod, &nod1);
 | 
			
		||||
		} else
 | 
			
		||||
		if(firstarg && typeword[firstargtype->etype]) {
 | 
			
		||||
			nod1 = *nodret->left;
 | 
			
		||||
			nod1.sym = firstarg;
 | 
			
		||||
			nod1.type = firstargtype;
 | 
			
		||||
			nod1.xoffset = align(0, firstargtype, Aarg1);
 | 
			
		||||
			nod1.etype = firstargtype->etype;
 | 
			
		||||
			nodreg(&nod, &nod1, REGARG);
 | 
			
		||||
			gmove(&nod, &nod1);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	canreach = 1;
 | 
			
		||||
	warnreach = 1;
 | 
			
		||||
	gen(n);
 | 
			
		||||
	if(canreach && thisfn->link->etype != TVOID)
 | 
			
		||||
		warn(Z, "no return at end of function: %s", n1->sym->name);
 | 
			
		||||
	noretval(3);
 | 
			
		||||
	gbranch(ORETURN);
 | 
			
		||||
 | 
			
		||||
	if(!debug['N'] || debug['R'] || debug['P'])
 | 
			
		||||
		regopt(sp);
 | 
			
		||||
	
 | 
			
		||||
	if(thechar=='6' || thechar=='7')	/* [sic] */
 | 
			
		||||
		maxargsafe = xround(maxargsafe, 8);
 | 
			
		||||
	sp->to.offset += maxargsafe;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
supgen(Node *n)
 | 
			
		||||
{
 | 
			
		||||
	int owarn;
 | 
			
		||||
	int32 spc;
 | 
			
		||||
	Prog *sp;
 | 
			
		||||
 | 
			
		||||
	if(n == Z)
 | 
			
		||||
		return;
 | 
			
		||||
	suppress++;
 | 
			
		||||
	owarn = warnreach;
 | 
			
		||||
	warnreach = 0;
 | 
			
		||||
	spc = pc;
 | 
			
		||||
	sp = lastp;
 | 
			
		||||
	gen(n);
 | 
			
		||||
	lastp = sp;
 | 
			
		||||
	pc = spc;
 | 
			
		||||
	sp->link = nil;
 | 
			
		||||
	suppress--;
 | 
			
		||||
	warnreach = owarn;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
gen(Node *n)
 | 
			
		||||
{
 | 
			
		||||
	Node *l, nod;
 | 
			
		||||
	Prog *sp, *spc, *spb;
 | 
			
		||||
	Case *cn;
 | 
			
		||||
	int32 sbc, scc;
 | 
			
		||||
	int snbreak, sncontin;
 | 
			
		||||
	int f, o, oldreach;
 | 
			
		||||
 | 
			
		||||
loop:
 | 
			
		||||
	if(n == Z)
 | 
			
		||||
		return;
 | 
			
		||||
	nearln = n->lineno;
 | 
			
		||||
	o = n->op;
 | 
			
		||||
	if(debug['G'])
 | 
			
		||||
		if(o != OLIST)
 | 
			
		||||
			print("%L %O\n", nearln, o);
 | 
			
		||||
 | 
			
		||||
	if(!canreach) {
 | 
			
		||||
		switch(o) {
 | 
			
		||||
		case OLABEL:
 | 
			
		||||
		case OCASE:
 | 
			
		||||
		case OLIST:
 | 
			
		||||
		case OBREAK:
 | 
			
		||||
		case OFOR:
 | 
			
		||||
		case OWHILE:
 | 
			
		||||
		case ODWHILE:
 | 
			
		||||
			/* all handled specially - see switch body below */
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			if(warnreach) {
 | 
			
		||||
				warn(n, "unreachable code %O", o);
 | 
			
		||||
				warnreach = 0;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch(o) {
 | 
			
		||||
 | 
			
		||||
	default:
 | 
			
		||||
		complex(n);
 | 
			
		||||
		cgen(n, Z);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case OLIST:
 | 
			
		||||
		gen(n->left);
 | 
			
		||||
 | 
			
		||||
	rloop:
 | 
			
		||||
		n = n->right;
 | 
			
		||||
		goto loop;
 | 
			
		||||
 | 
			
		||||
	case ORETURN:
 | 
			
		||||
		canreach = 0;
 | 
			
		||||
		warnreach = !suppress;
 | 
			
		||||
		complex(n);
 | 
			
		||||
		if(n->type == T)
 | 
			
		||||
			break;
 | 
			
		||||
		l = n->left;
 | 
			
		||||
		if(l == Z) {
 | 
			
		||||
			noretval(3);
 | 
			
		||||
			gbranch(ORETURN);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		if(typecmplx[n->type->etype]) {
 | 
			
		||||
			sugen(l, nodret, n->type->width);
 | 
			
		||||
			noretval(3);
 | 
			
		||||
			gbranch(ORETURN);
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		regret(&nod, n);
 | 
			
		||||
		cgen(l, &nod);
 | 
			
		||||
		regfree(&nod);
 | 
			
		||||
		if(typefd[n->type->etype])
 | 
			
		||||
			noretval(1);
 | 
			
		||||
		else
 | 
			
		||||
			noretval(2);
 | 
			
		||||
		gbranch(ORETURN);
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case OLABEL:
 | 
			
		||||
		canreach = 1;
 | 
			
		||||
		l = n->left;
 | 
			
		||||
		if(l) {
 | 
			
		||||
			l->pc = pc;
 | 
			
		||||
			if(l->label)
 | 
			
		||||
				patch(l->label, pc);
 | 
			
		||||
		}
 | 
			
		||||
		gbranch(OGOTO);	/* prevent self reference in reg */
 | 
			
		||||
		patch(p, pc);
 | 
			
		||||
		goto rloop;
 | 
			
		||||
 | 
			
		||||
	case OGOTO:
 | 
			
		||||
		canreach = 0;
 | 
			
		||||
		warnreach = !suppress;
 | 
			
		||||
		n = n->left;
 | 
			
		||||
		if(n == Z)
 | 
			
		||||
			return;
 | 
			
		||||
		if(n->complex == 0) {
 | 
			
		||||
			diag(Z, "label undefined: %s", n->sym->name);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		if(suppress)
 | 
			
		||||
			return;
 | 
			
		||||
		gbranch(OGOTO);
 | 
			
		||||
		if(n->pc) {
 | 
			
		||||
			patch(p, n->pc);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		if(n->label)
 | 
			
		||||
			patch(n->label, pc-1);
 | 
			
		||||
		n->label = p;
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	case OCASE:
 | 
			
		||||
		canreach = 1;
 | 
			
		||||
		l = n->left;
 | 
			
		||||
		if(cases == C)
 | 
			
		||||
			diag(n, "case/default outside a switch");
 | 
			
		||||
		if(l == Z) {
 | 
			
		||||
			cas();
 | 
			
		||||
			cases->val = 0;
 | 
			
		||||
			cases->def = 1;
 | 
			
		||||
			cases->label = pc;
 | 
			
		||||
			cases->isv = 0;
 | 
			
		||||
			goto rloop;
 | 
			
		||||
		}
 | 
			
		||||
		complex(l);
 | 
			
		||||
		if(l->type == T)
 | 
			
		||||
			goto rloop;
 | 
			
		||||
		if(l->op == OCONST)
 | 
			
		||||
		if(typeword[l->type->etype] && l->type->etype != TIND) {
 | 
			
		||||
			cas();
 | 
			
		||||
			cases->val = l->vconst;
 | 
			
		||||
			cases->def = 0;
 | 
			
		||||
			cases->label = pc;
 | 
			
		||||
			cases->isv = typev[l->type->etype];
 | 
			
		||||
			goto rloop;
 | 
			
		||||
		}
 | 
			
		||||
		diag(n, "case expression must be integer constant");
 | 
			
		||||
		goto rloop;
 | 
			
		||||
 | 
			
		||||
	case OSWITCH:
 | 
			
		||||
		l = n->left;
 | 
			
		||||
		complex(l);
 | 
			
		||||
		if(l->type == T)
 | 
			
		||||
			break;
 | 
			
		||||
		if(!typeword[l->type->etype] || l->type->etype == TIND) {
 | 
			
		||||
			diag(n, "switch expression must be integer");
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		gbranch(OGOTO);		/* entry */
 | 
			
		||||
		sp = p;
 | 
			
		||||
 | 
			
		||||
		cn = cases;
 | 
			
		||||
		cases = C;
 | 
			
		||||
		cas();
 | 
			
		||||
 | 
			
		||||
		sbc = breakpc;
 | 
			
		||||
		breakpc = pc;
 | 
			
		||||
		snbreak = nbreak;
 | 
			
		||||
		nbreak = 0;
 | 
			
		||||
		gbranch(OGOTO);
 | 
			
		||||
		spb = p;
 | 
			
		||||
 | 
			
		||||
		gen(n->right);		/* body */
 | 
			
		||||
		if(canreach){
 | 
			
		||||
			gbranch(OGOTO);
 | 
			
		||||
			patch(p, breakpc);
 | 
			
		||||
			nbreak++;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		patch(sp, pc);
 | 
			
		||||
		regalloc(&nod, l, Z);
 | 
			
		||||
		/* always signed */
 | 
			
		||||
		if(typev[l->type->etype])
 | 
			
		||||
			nod.type = types[TVLONG];
 | 
			
		||||
		else
 | 
			
		||||
			nod.type = types[TLONG];
 | 
			
		||||
		cgen(l, &nod);
 | 
			
		||||
		doswit(&nod);
 | 
			
		||||
		regfree(&nod);
 | 
			
		||||
		patch(spb, pc);
 | 
			
		||||
 | 
			
		||||
		cases = cn;
 | 
			
		||||
		breakpc = sbc;
 | 
			
		||||
		canreach = nbreak!=0;
 | 
			
		||||
		if(canreach == 0)
 | 
			
		||||
			warnreach = !suppress;
 | 
			
		||||
		nbreak = snbreak;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case OWHILE:
 | 
			
		||||
	case ODWHILE:
 | 
			
		||||
		l = n->left;
 | 
			
		||||
		gbranch(OGOTO);		/* entry */
 | 
			
		||||
		sp = p;
 | 
			
		||||
 | 
			
		||||
		scc = continpc;
 | 
			
		||||
		continpc = pc;
 | 
			
		||||
		gbranch(OGOTO);
 | 
			
		||||
		spc = p;
 | 
			
		||||
 | 
			
		||||
		sbc = breakpc;
 | 
			
		||||
		breakpc = pc;
 | 
			
		||||
		snbreak = nbreak;
 | 
			
		||||
		nbreak = 0;
 | 
			
		||||
		gbranch(OGOTO);
 | 
			
		||||
		spb = p;
 | 
			
		||||
 | 
			
		||||
		patch(spc, pc);
 | 
			
		||||
		if(n->op == OWHILE)
 | 
			
		||||
			patch(sp, pc);
 | 
			
		||||
		bcomplex(l, Z);		/* test */
 | 
			
		||||
		patch(p, breakpc);
 | 
			
		||||
		if(l->op != OCONST || vconst(l) == 0)
 | 
			
		||||
			nbreak++;
 | 
			
		||||
 | 
			
		||||
		if(n->op == ODWHILE)
 | 
			
		||||
			patch(sp, pc);
 | 
			
		||||
		gen(n->right);		/* body */
 | 
			
		||||
		gbranch(OGOTO);
 | 
			
		||||
		patch(p, continpc);
 | 
			
		||||
 | 
			
		||||
		patch(spb, pc);
 | 
			
		||||
		continpc = scc;
 | 
			
		||||
		breakpc = sbc;
 | 
			
		||||
		canreach = nbreak!=0;
 | 
			
		||||
		if(canreach == 0)
 | 
			
		||||
			warnreach = !suppress;
 | 
			
		||||
		nbreak = snbreak;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case OFOR:
 | 
			
		||||
		l = n->left;
 | 
			
		||||
		if(!canreach && l->right->left && warnreach) {
 | 
			
		||||
			warn(n, "unreachable code FOR");
 | 
			
		||||
			warnreach = 0;
 | 
			
		||||
		}
 | 
			
		||||
		gen(l->right->left);	/* init */
 | 
			
		||||
		gbranch(OGOTO);		/* entry */
 | 
			
		||||
		sp = p;
 | 
			
		||||
 | 
			
		||||
		/* 
 | 
			
		||||
		 * if there are no incoming labels in the 
 | 
			
		||||
		 * body and the top's not reachable, warn
 | 
			
		||||
		 */
 | 
			
		||||
		if(!canreach && warnreach && deadheads(n)) {
 | 
			
		||||
			warn(n, "unreachable code %O", o);
 | 
			
		||||
			warnreach = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		scc = continpc;
 | 
			
		||||
		continpc = pc;
 | 
			
		||||
		gbranch(OGOTO);
 | 
			
		||||
		spc = p;
 | 
			
		||||
 | 
			
		||||
		sbc = breakpc;
 | 
			
		||||
		breakpc = pc;
 | 
			
		||||
		snbreak = nbreak;
 | 
			
		||||
		nbreak = 0;
 | 
			
		||||
		sncontin = ncontin;
 | 
			
		||||
		ncontin = 0;
 | 
			
		||||
		gbranch(OGOTO);
 | 
			
		||||
		spb = p;
 | 
			
		||||
 | 
			
		||||
		patch(spc, pc);
 | 
			
		||||
		gen(l->right->right);	/* inc */
 | 
			
		||||
		patch(sp, pc);	
 | 
			
		||||
		if(l->left != Z) {	/* test */
 | 
			
		||||
			bcomplex(l->left, Z);
 | 
			
		||||
			patch(p, breakpc);
 | 
			
		||||
			if(l->left->op != OCONST || vconst(l->left) == 0)
 | 
			
		||||
				nbreak++;
 | 
			
		||||
		}
 | 
			
		||||
		canreach = 1;
 | 
			
		||||
		gen(n->right);		/* body */
 | 
			
		||||
		if(canreach){
 | 
			
		||||
			gbranch(OGOTO);
 | 
			
		||||
			patch(p, continpc);
 | 
			
		||||
			ncontin++;
 | 
			
		||||
		}
 | 
			
		||||
		if(!ncontin && l->right->right && warnreach) {
 | 
			
		||||
			warn(l->right->right, "unreachable FOR inc");
 | 
			
		||||
			warnreach = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		patch(spb, pc);
 | 
			
		||||
		continpc = scc;
 | 
			
		||||
		breakpc = sbc;
 | 
			
		||||
		canreach = nbreak!=0;
 | 
			
		||||
		if(canreach == 0)
 | 
			
		||||
			warnreach = !suppress;
 | 
			
		||||
		nbreak = snbreak;
 | 
			
		||||
		ncontin = sncontin;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case OCONTINUE:
 | 
			
		||||
		if(continpc < 0) {
 | 
			
		||||
			diag(n, "continue not in a loop");
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		gbranch(OGOTO);
 | 
			
		||||
		patch(p, continpc);
 | 
			
		||||
		ncontin++;
 | 
			
		||||
		canreach = 0;
 | 
			
		||||
		warnreach = !suppress;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case OBREAK:
 | 
			
		||||
		if(breakpc < 0) {
 | 
			
		||||
			diag(n, "break not in a loop");
 | 
			
		||||
			break;
 | 
			
		||||
		}
 | 
			
		||||
		/*
 | 
			
		||||
		 * Don't complain about unreachable break statements.
 | 
			
		||||
		 * There are breaks hidden in yacc's output and some people
 | 
			
		||||
		 * write return; break; in their switch statements out of habit.
 | 
			
		||||
		 * However, don't confuse the analysis by inserting an 
 | 
			
		||||
		 * unreachable reference to breakpc either.
 | 
			
		||||
		 */
 | 
			
		||||
		if(!canreach)
 | 
			
		||||
			break;
 | 
			
		||||
		gbranch(OGOTO);
 | 
			
		||||
		patch(p, breakpc);
 | 
			
		||||
		nbreak++;
 | 
			
		||||
		canreach = 0;
 | 
			
		||||
		warnreach = !suppress;
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case OIF:
 | 
			
		||||
		l = n->left;
 | 
			
		||||
		if(bcomplex(l, n->right)) {
 | 
			
		||||
			if(typefd[l->type->etype])
 | 
			
		||||
				f = !l->fconst;
 | 
			
		||||
			else
 | 
			
		||||
				f = !l->vconst;
 | 
			
		||||
			if(debug['c'])
 | 
			
		||||
				print("%L const if %s\n", nearln, f ? "false" : "true");
 | 
			
		||||
			if(f) {
 | 
			
		||||
				canreach = 1;
 | 
			
		||||
				supgen(n->right->left);
 | 
			
		||||
				oldreach = canreach;
 | 
			
		||||
				canreach = 1;
 | 
			
		||||
				gen(n->right->right);
 | 
			
		||||
				/*
 | 
			
		||||
				 * treat constant ifs as regular ifs for 
 | 
			
		||||
				 * reachability warnings.
 | 
			
		||||
				 */
 | 
			
		||||
				if(!canreach && oldreach && debug['w'] < 2)
 | 
			
		||||
					warnreach = 0;
 | 
			
		||||
			}
 | 
			
		||||
			else {
 | 
			
		||||
				canreach = 1;
 | 
			
		||||
				gen(n->right->left);
 | 
			
		||||
				oldreach = canreach;
 | 
			
		||||
				canreach = 1;
 | 
			
		||||
				supgen(n->right->right);
 | 
			
		||||
				/*
 | 
			
		||||
				 * treat constant ifs as regular ifs for 
 | 
			
		||||
				 * reachability warnings.
 | 
			
		||||
				 */
 | 
			
		||||
				if(!oldreach && canreach && debug['w'] < 2)
 | 
			
		||||
					warnreach = 0;
 | 
			
		||||
				canreach = oldreach;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			sp = p;
 | 
			
		||||
			canreach = 1;
 | 
			
		||||
			if(n->right->left != Z)
 | 
			
		||||
				gen(n->right->left);
 | 
			
		||||
			oldreach = canreach;
 | 
			
		||||
			canreach = 1;
 | 
			
		||||
			if(n->right->right != Z) {
 | 
			
		||||
				gbranch(OGOTO);
 | 
			
		||||
				patch(sp, pc);
 | 
			
		||||
				sp = p;
 | 
			
		||||
				gen(n->right->right);
 | 
			
		||||
			}
 | 
			
		||||
			patch(sp, pc);
 | 
			
		||||
			canreach = canreach || oldreach;
 | 
			
		||||
			if(canreach == 0)
 | 
			
		||||
				warnreach = !suppress;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
 | 
			
		||||
	case OSET:
 | 
			
		||||
	case OUSED:
 | 
			
		||||
		usedset(n->left, o);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
usedset(Node *n, int o)
 | 
			
		||||
{
 | 
			
		||||
	if(n->op == OLIST) {
 | 
			
		||||
		usedset(n->left, o);
 | 
			
		||||
		usedset(n->right, o);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	complex(n);
 | 
			
		||||
	switch(n->op) {
 | 
			
		||||
	case OADDR:	/* volatile */
 | 
			
		||||
		gins(ANOP, n, Z);
 | 
			
		||||
		break;
 | 
			
		||||
	case ONAME:
 | 
			
		||||
		if(o == OSET)
 | 
			
		||||
			gins(ANOP, Z, n);
 | 
			
		||||
		else
 | 
			
		||||
			gins(ANOP, n, Z);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
bcomplex(Node *n, Node *c)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
	complex(n);
 | 
			
		||||
	if(n->type != T)
 | 
			
		||||
	if(tcompat(n, T, n->type, tnot))
 | 
			
		||||
		n->type = T;
 | 
			
		||||
	if(n->type == T) {
 | 
			
		||||
		gbranch(OGOTO);
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	if(c != Z && n->op == OCONST && deadheads(c))
 | 
			
		||||
		return 1;
 | 
			
		||||
	bool64(n);
 | 
			
		||||
	boolgen(n, 1, Z);
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue