1 #include "c.h"
2 
3 
4 #define SWSIZE 512
5 
6 #define den(i,j) ((j-buckets[i]+1.0)/(v[j]-v[buckets[i]]+1))
7 
8 struct code codehead = { Start };
9 Code codelist = &codehead;
10 float density = 0.5;
11 Table stmtlabs;
12 
13 static int foldcond(Tree e1, Tree e2);
14 static void caselabel(Swtch, long, int);
15 static void cmp(int, Symbol, long, int);
16 static Tree conditional(int);
17 static void dostmt(int, Swtch, int);
18 static int equal(Symbol, Symbol);
19 static void forstmt(int, Swtch, int);
20 static void ifstmt(int, int, Swtch, int);
21 static Symbol localaddr(Tree);
22 static void stmtlabel(void);
23 static void swstmt(int, int, int);
24 static void whilestmt(int, Swtch, int);
code(int kind)25 Code code(int kind) {
26 	Code cp;
27 
28 	if (!reachable(kind))
29 		warning("unreachable code\n");
30 
31 	NEW(cp, FUNC);
32 	cp->kind = kind;
33 	cp->prev = codelist;
34 	cp->next = NULL;
35 	codelist->next = cp;
36 	codelist = cp;
37 	return cp;
38 }
reachable(int kind)39 int reachable(int kind) {
40 
41 	if (kind > Start) {
42 		Code cp;
43 		for (cp = codelist; cp->kind < Label; )
44 			cp = cp->prev;
45 		if (cp->kind == Jump || cp->kind == Switch)
46 			return 0;
47 	}
48 	return 1;
49 }
addlocal(Symbol p)50 void addlocal(Symbol p) {
51 	if (!p->defined) {
52 		code(Local)->u.var = p;
53 		p->defined = 1;
54 		p->scope = level;
55 	}
56 }
definept(Coordinate * p)57 void definept(Coordinate *p) {
58 	Code cp = code(Defpoint);
59 
60 	cp->u.point.src = p ? *p : src;
61 	cp->u.point.point = npoints;
62 	if (ncalled > 0) {
63 		int n = findcount(cp->u.point.src.file,
64 			cp->u.point.src.x, cp->u.point.src.y);
65 		if (n > 0)
66 			refinc = (float)n/ncalled;
67 	}
68 	if (glevel > 2)	locus(identifiers, &cp->u.point.src);
69 	if (events.points && reachable(Gen))
70 		{
71 			Tree e = NULL;
72 			apply(events.points, &cp->u.point.src, &e);
73 			if (e)
74 				listnodes(e, 0, 0);
75 		}
76 }
statement(int loop,Swtch swp,int lev)77 void statement(int loop, Swtch swp, int lev) {
78 	float ref = refinc;
79 
80 	if (Aflag >= 2 && lev == 15)
81 		warning("more than 15 levels of nested statements\n");
82 	switch (t) {
83 	case IF:       ifstmt(genlabel(2), loop, swp, lev + 1);
84  break;
85 	case WHILE:    whilestmt(genlabel(3), swp, lev + 1); break;
86 	case DO:       dostmt(genlabel(3), swp, lev + 1); expect(';');
87 					break;
88 
89 	case FOR:      forstmt(genlabel(4), swp, lev + 1);
90  break;
91 	case BREAK:    walk(NULL, 0, 0);
92 		       definept(NULL);
93 		       if (swp && swp->lab > loop)
94 		       	branch(swp->lab + 1);
95 		       else if (loop)
96 		       	branch(loop + 2);
97 		       else
98 		       	error("illegal break statement\n");
99 		       t = gettok(); expect(';');
100 					   break;
101 
102 	case CONTINUE: walk(NULL, 0, 0);
103 		       definept(NULL);
104 		       if (loop)
105 		       	branch(loop + 1);
106 		       else
107 		       	error("illegal continue statement\n");
108 		       t = gettok(); expect(';');
109 					      break;
110 
111 	case SWITCH:   swstmt(loop, genlabel(2), lev + 1);
112  break;
113 	case CASE:     {
114 		       	int lab = genlabel(1);
115 		       	if (swp == NULL)
116 		       		error("illegal case label\n");
117 		       	definelab(lab);
118 		       	while (t == CASE) {
119 		       		static char stop[] = { IF, ID, 0 };
120 		       		Tree p;
121 		       		t = gettok();
122 		       		p = constexpr(0);
123 		       		if (generic(p->op) == CNST && isint(p->type)) {
124 		       			if (swp) {
125 		       				needconst++;
126 		       				p = cast(p, swp->sym->type);
127 		       				if (p->type->op == UNSIGNED)
128 		       					p->u.v.i = extend(p->u.v.u, p->type);
129 		       				needconst--;
130 		       				caselabel(swp, p->u.v.i, lab);
131 		       			}
132 		       		} else {
133 		       			error("case label must be a constant integer expression\n");
134 		       		}
135 		       		test(':', stop);
136 		       	}
137 		       	statement(loop, swp, lev);
138 		       } break;
139 	case DEFAULT:  if (swp == NULL)
140 		       	error("illegal default label\n");
141 		       else if (swp->deflab)
142 		       	error("extra default label\n");
143 		       else {
144 		       	swp->deflab = findlabel(swp->lab);
145 		       	definelab(swp->deflab->u.l.label);
146 		       }
147 		       t = gettok();
148 		       expect(':');
149 		       statement(loop, swp, lev); break;
150 	case RETURN:   {
151 		       	Type rty = freturn(cfunc->type);
152 		       	t = gettok();
153 		       	definept(NULL);
154 		       	if (t != ';')
155 		       		if (rty == voidtype) {
156 		       			error("extraneous return value\n");
157 		       			expr(0);
158 		       			retcode(NULL);
159 		       		} else
160 		       			retcode(expr(0));
161 		       	else {
162 		       		if (rty != voidtype)
163 		       			warning("missing return value\n");
164 		       		retcode(NULL);
165 		       	}
166 		       	branch(cfunc->u.f.label);
167 		       } expect(';');
168 					    break;
169 
170 	case '{':      compound(loop, swp, lev + 1); break;
171 	case ';':      definept(NULL); t = gettok(); break;
172 	case GOTO:     walk(NULL, 0, 0);
173 		       definept(NULL);
174 		       t = gettok();
175 		       if (t == ID) {
176 		       	Symbol p = lookup(token, stmtlabs);
177 		       	if (p == NULL) {
178 				p = install(token, &stmtlabs, 0, FUNC);
179 				p->scope = LABELS;
180 				p->u.l.label = genlabel(1);
181 				p->src = src;
182 			}
183 		       	use(p, src);
184 		       	branch(p->u.l.label);
185 		       	t = gettok();
186 		       } else {
187 		       	error("missing label in goto\n");
188 		       } expect(';');
189 					  break;
190 
191 	case ID:       if (getchr() == ':') {
192 		       	stmtlabel();
193 		       	statement(loop, swp, lev);
194 		       	break;
195 		       }
196 	default:       definept(NULL);
197 		       if (kind[t] != ID) {
198 		       	error("unrecognized statement\n");
199 		       	t = gettok();
200 		       } else {
201 		       	Tree e = expr0(0);
202 		       	listnodes(e, 0, 0);
203 		       	if (nodecount == 0 || nodecount > 200)
204 		       		walk(NULL, 0, 0);
205 		       	else if (glevel)
206 				walk(NULL, 0, 0);
207 		       	deallocate(STMT);
208 		       } expect(';');
209 						break;
210 
211 	}
212 	if (kind[t] != IF && kind[t] != ID
213 	&& t != '}' && t != EOI) {
214 		static char stop[] = { IF, ID, '}', 0 };
215 		error("illegal statement termination\n");
216 		skipto(0, stop);
217 	}
218 	refinc = ref;
219 }
220 
ifstmt(int lab,int loop,Swtch swp,int lev)221 static void ifstmt(int lab, int loop, Swtch swp, int lev) {
222 	t = gettok();
223 	expect('(');
224 	definept(NULL);
225 	walk(conditional(')'), 0, lab);
226 	refinc /= 2.0;
227 	statement(loop, swp, lev);
228 	if (t == ELSE) {
229 		branch(lab + 1);
230 		t = gettok();
231 		definelab(lab);
232 		statement(loop, swp, lev);
233 		if (findlabel(lab + 1)->ref)
234 			definelab(lab + 1);
235 	} else
236 		definelab(lab);
237 }
conditional(int tok)238 static Tree conditional(int tok) {
239 	Tree p = expr(tok);
240 
241 	if (Aflag > 1 && isfunc(p->type))
242 		warning("%s used in a conditional expression\n",
243 			funcname(p));
244 	return cond(p);
245 }
stmtlabel(void)246 static void stmtlabel(void) {
247 	Symbol p = lookup(token, stmtlabs);
248 
249 	if (p == NULL) {
250 		p = install(token, &stmtlabs, 0, FUNC);
251 		p->scope = LABELS;
252 		p->u.l.label = genlabel(1);
253 		p->src = src;
254 	}
255 	if (p->defined)
256 		error("redefinition of label `%s' previously defined at %w\n", p->name, &p->src);
257 
258 	p->defined = 1;
259 	definelab(p->u.l.label);
260 	t = gettok();
261 	expect(':');
262 }
forstmt(int lab,Swtch swp,int lev)263 static void forstmt(int lab, Swtch swp, int lev) {
264 	int once = 0;
265 	Tree e1 = NULL, e2 = NULL, e3 = NULL;
266 	Coordinate pt2, pt3;
267 
268 	t = gettok();
269 	expect('(');
270 	definept(NULL);
271 	if (kind[t] == ID)
272 		e1 = texpr(expr0, ';', FUNC);
273 	else
274 		expect(';');
275 	walk(e1, 0, 0);
276 	pt2 = src;
277 	refinc *= 10.0;
278 	if (kind[t] == ID)
279 		e2 = texpr(conditional, ';', FUNC);
280 	else
281 		expect(';');
282 	pt3 = src;
283 	if (kind[t] == ID)
284 		e3 = texpr(expr0, ')', FUNC);
285 	else {
286 		static char stop[] = { IF, ID, '}', 0 };
287 		test(')', stop);
288 	}
289 	if (e2) {
290 		once = foldcond(e1, e2);
291 		if (!once)
292 			branch(lab + 3);
293 	}
294 	definelab(lab);
295 	statement(lab, swp, lev);
296 	definelab(lab + 1);
297 	definept(&pt3);
298 	if (e3)
299 		walk(e3, 0, 0);
300 	if (e2) {
301 		if (!once)
302 			definelab(lab + 3);
303 		definept(&pt2);
304 		walk(e2, lab, 0);
305 	} else {
306 		definept(&pt2);
307 		branch(lab);
308 	}
309 	if (findlabel(lab + 2)->ref)
310 		definelab(lab + 2);
311 }
swstmt(int loop,int lab,int lev)312 static void swstmt(int loop, int lab, int lev) {
313 	Tree e;
314 	struct swtch sw;
315 	Code head, tail;
316 
317 	t = gettok();
318 	expect('(');
319 	definept(NULL);
320 	e = expr(')');
321 	if (!isint(e->type)) {
322 		error("illegal type `%t' in switch expression\n",
323 			e->type);
324 		e = retype(e, inttype);
325 	}
326 	e = cast(e, promote(e->type));
327 	if (generic(e->op) == INDIR && isaddrop(e->kids[0]->op)
328 	&& e->kids[0]->u.sym->type == e->type
329 	&& !isvolatile(e->kids[0]->u.sym->type)) {
330 		sw.sym = e->kids[0]->u.sym;
331 		walk(NULL, 0, 0);
332 	} else {
333 		sw.sym = genident(REGISTER, e->type, level);
334 		addlocal(sw.sym);
335 		walk(asgn(sw.sym, e), 0, 0);
336 	}
337 	head = code(Switch);
338 	sw.lab = lab;
339 	sw.deflab = NULL;
340 	sw.ncases = 0;
341 	sw.size = SWSIZE;
342 	sw.values = newarray(SWSIZE, sizeof *sw.values, FUNC);
343 	sw.labels = newarray(SWSIZE, sizeof *sw.labels, FUNC);
344 	refinc /= 10.0;
345 	statement(loop, &sw, lev);
346 	if (sw.deflab == NULL) {
347 		sw.deflab = findlabel(lab);
348 		definelab(lab);
349 		if (sw.ncases == 0)
350 			warning("switch statement with no cases\n");
351 	}
352 	if (findlabel(lab + 1)->ref)
353 		definelab(lab + 1);
354 	tail = codelist;
355 	codelist = head->prev;
356 	codelist->next = head->prev = NULL;
357 	if (sw.ncases > 0)
358 		swgen(&sw);
359 	branch(lab);
360 	head->next->prev = codelist;
361 	codelist->next = head->next;
362 	codelist = tail;
363 }
caselabel(Swtch swp,long val,int lab)364 static void caselabel(Swtch swp, long val, int lab) {
365 	int k;
366 
367 	if (swp->ncases >= swp->size)
368 		{
369 		long   *vals = swp->values;
370 		Symbol *labs = swp->labels;
371 		swp->size *= 2;
372 		swp->values = newarray(swp->size, sizeof *swp->values, FUNC);
373 		swp->labels = newarray(swp->size, sizeof *swp->labels, FUNC);
374 		for (k = 0; k < swp->ncases; k++) {
375 			swp->values[k] = vals[k];
376 			swp->labels[k] = labs[k];
377 		}
378 		}
379 	k = swp->ncases;
380 	for ( ; k > 0 && swp->values[k-1] >= val; k--) {
381 		swp->values[k] = swp->values[k-1];
382 		swp->labels[k] = swp->labels[k-1];
383 	}
384 	if (k < swp->ncases && swp->values[k] == val)
385 		error("duplicate case label `%d'\n", val);
386 	swp->values[k] = val;
387 	swp->labels[k] = findlabel(lab);
388 	++swp->ncases;
389 	if (Aflag >= 2 && swp->ncases == 258)
390 		warning("more than 257 cases in a switch\n");
391 }
swgen(Swtch swp)392 void swgen(Swtch swp) {
393 	int *buckets, k, n;
394 	long *v = swp->values;
395 
396 	buckets = newarray(swp->ncases + 1,
397 		sizeof *buckets, FUNC);
398 	for (n = k = 0; k < swp->ncases; k++, n++) {
399 		buckets[n] = k;
400 		while (n > 0 && den(n-1, k) >= density)
401 			n--;
402 	}
403 	buckets[n] = swp->ncases;
404 	swcode(swp, buckets, 0, n - 1);
405 }
swcode(Swtch swp,int b[],int lb,int ub)406 void swcode(Swtch swp, int b[], int lb, int ub) {
407 	int hilab, lolab, l, u, k = (lb + ub)/2;
408 	long *v = swp->values;
409 
410 	if (k > lb && k < ub) {
411 		lolab = genlabel(1);
412 		hilab = genlabel(1);
413 	} else if (k > lb) {
414 		lolab = genlabel(1);
415 		hilab = swp->deflab->u.l.label;
416 	} else if (k < ub) {
417 		lolab = swp->deflab->u.l.label;
418 		hilab = genlabel(1);
419 	} else
420 		lolab = hilab = swp->deflab->u.l.label;
421 	l = b[k];
422 	u = b[k+1] - 1;
423 	if (u - l + 1 <= 3)
424 		{
425 			int i;
426 			for (i = l; i <= u; i++)
427 				cmp(EQ, swp->sym, v[i], swp->labels[i]->u.l.label);
428 			if (k > lb && k < ub)
429 				cmp(GT, swp->sym, v[u], hilab);
430 			else if (k > lb)
431 				cmp(GT, swp->sym, v[u], hilab);
432 			else if (k < ub)
433 				cmp(LT, swp->sym, v[l], lolab);
434 			else
435 				assert(lolab == hilab),
436 				branch(lolab);
437 			walk(NULL, 0, 0);
438 		}
439 	else {
440 		Tree e;
441 		Type ty = signedint(swp->sym->type);
442 		Symbol table = genident(STATIC,
443 			array(voidptype, u - l + 1, 0), GLOBAL);
444 		(*IR->defsymbol)(table);
445 		if (!isunsigned(swp->sym->type) || v[l] != 0)
446 			cmp(LT, swp->sym, v[l], lolab);
447 		cmp(GT, swp->sym, v[u], hilab);
448 		e = (*optree['-'])(SUB, cast(idtree(swp->sym), ty), cnsttree(ty, v[l]));
449 		if (e->type->size < unsignedptr->size)
450 			e = cast(e, unsignedlong);
451 		walk(tree(JUMP, voidtype,
452 			rvalue((*optree['+'])(ADD, pointer(idtree(table)), e)), NULL),
453 			0, 0);
454 		code(Switch);
455 		codelist->u.swtch.table = table;
456 		codelist->u.swtch.sym = swp->sym;
457 		codelist->u.swtch.deflab = swp->deflab;
458 		codelist->u.swtch.size = u - l + 1;
459 		codelist->u.swtch.values = &v[l];
460 		codelist->u.swtch.labels = &swp->labels[l];
461 		if (v[u] - v[l] + 1 >= 10000)
462 			warning("switch generates a huge table\n");
463 	}
464 	if (k > lb) {
465 		assert(lolab != swp->deflab->u.l.label);
466 		definelab(lolab);
467 		swcode(swp, b, lb, k - 1);
468 	}
469 	if (k < ub) {
470 		assert(hilab != swp->deflab->u.l.label);
471 		definelab(hilab);
472 		swcode(swp, b, k + 1, ub);
473 	}
474 }
cmp(int op,Symbol p,long n,int lab)475 static void cmp(int op, Symbol p, long n, int lab) {
476 	Type ty = signedint(p->type);
477 
478 	listnodes(eqtree(op,
479 			cast(idtree(p), ty),
480 			cnsttree(ty, n)),
481 		lab, 0);
482 }
retcode(Tree p)483 void retcode(Tree p) {
484 	Type ty;
485 
486 	if (p == NULL) {
487 		if (events.returns)
488 			apply(events.returns, cfunc, NULL);
489 		return;
490 	}
491 	p = pointer(p);
492 	ty = assign(freturn(cfunc->type), p);
493 	if (ty == NULL) {
494 		error("illegal return type; found `%t' expected `%t'\n",
495 			p->type, freturn(cfunc->type));
496 		return;
497 	}
498 	p = cast(p, ty);
499 	if (retv)
500 		{
501 			if (iscallb(p))
502 				p = tree(RIGHT, p->type,
503 					tree(CALL+B, p->type,
504 						p->kids[0]->kids[0], idtree(retv)),
505 					rvalue(idtree(retv)));
506 			else
507 				p = asgntree(ASGN, rvalue(idtree(retv)), p);
508 			walk(p, 0, 0);
509 			if (events.returns)
510 				apply(events.returns, cfunc, rvalue(idtree(retv)));
511 			return;
512 		}
513 	if (events.returns)
514 		{
515 			Symbol t1 = genident(AUTO, p->type, level);
516 			addlocal(t1);
517 			walk(asgn(t1, p), 0, 0);
518 			apply(events.returns, cfunc, idtree(t1));
519 			p = idtree(t1);
520 		}
521 	if (!isfloat(p->type))
522 		p = cast(p, promote(p->type));
523 	if (isptr(p->type))
524 		{
525 			Symbol q = localaddr(p);
526 			if (q && (q->computed || q->generated))
527 				warning("pointer to a %s is an illegal return value\n",
528 					q->scope == PARAM ? "parameter" : "local");
529 			else if (q)
530 				warning("pointer to %s `%s' is an illegal return value\n",
531 					q->scope == PARAM ? "parameter" : "local", q->name);
532 		}
533 	walk(tree(mkop(RET,p->type), p->type, p, NULL), 0, 0);
534 }
definelab(int lab)535 void definelab(int lab) {
536 	Code cp;
537 	Symbol p = findlabel(lab);
538 
539 	assert(lab);
540 	walk(NULL, 0, 0);
541 	code(Label)->u.forest = newnode(LABEL+V, NULL, NULL, p);
542 	for (cp = codelist->prev; cp->kind <= Label; )
543 		cp = cp->prev;
544 	while (   cp->kind == Jump
545 	       && cp->u.forest->kids[0]
546 	       && specific(cp->u.forest->kids[0]->op) == ADDRG+P
547 	       && cp->u.forest->kids[0]->syms[0] == p) {
548 		assert(cp->u.forest->kids[0]->syms[0]->u.l.label == lab);
549 		p->ref--;
550 		assert(cp->next);
551 		assert(cp->prev);
552 		cp->prev->next = cp->next;
553 		cp->next->prev = cp->prev;
554 		cp = cp->prev;
555 		while (cp->kind <= Label)
556 			cp = cp->prev;
557 	}
558 }
jump(int lab)559 Node jump(int lab) {
560 	Symbol p = findlabel(lab);
561 
562 	p->ref++;
563 	return newnode(JUMP+V, newnode(ADDRG+ttob(voidptype), NULL, NULL, p),
564 		NULL, NULL);
565 }
branch(int lab)566 void branch(int lab) {
567 	Code cp;
568 	Symbol p = findlabel(lab);
569 
570 	assert(lab);
571 	walk(NULL, 0, 0);
572 	code(Label)->u.forest = jump(lab);
573 	for (cp = codelist->prev; cp->kind < Label; )
574 		cp = cp->prev;
575 	while (   cp->kind == Label
576 	       && cp->u.forest->op == LABEL+V
577 	       && !equal(cp->u.forest->syms[0], p)) {
578 		equatelab(cp->u.forest->syms[0], p);
579 		assert(cp->next);
580 		assert(cp->prev);
581 		cp->prev->next = cp->next;
582 		cp->next->prev = cp->prev;
583 		cp = cp->prev;
584 		while (cp->kind < Label)
585 			cp = cp->prev;
586 	}
587 	if (cp->kind == Jump || cp->kind == Switch) {
588 		p->ref--;
589 		codelist->prev->next = NULL;
590 		codelist = codelist->prev;
591 	} else {
592 		codelist->kind = Jump;
593 		if (cp->kind == Label
594 		&&  cp->u.forest->op == LABEL+V
595 		&&  equal(cp->u.forest->syms[0], p))
596 			warning("source code specifies an infinite loop");
597 	}
598 }
equatelab(Symbol old,Symbol new)599 void equatelab(Symbol old, Symbol new) {
600 	assert(old->u.l.equatedto == NULL);
601 	old->u.l.equatedto = new;
602 	new->ref++;
603 }
equal(Symbol lprime,Symbol dst)604 static int equal(Symbol lprime, Symbol dst) {
605 	assert(dst && lprime);
606 	for ( ; dst; dst = dst->u.l.equatedto)
607 		if (lprime == dst)
608 			return 1;
609 	return 0;
610 }
611 /* dostmt - do statement while ( expression ) */
dostmt(int lab,Swtch swp,int lev)612 static void dostmt(int lab, Swtch swp, int lev) {
613 	refinc *= 10.0;
614 	t = gettok();
615 	definelab(lab);
616 	statement(lab, swp, lev);
617 	definelab(lab + 1);
618 	expect(WHILE);
619 	expect('(');
620 	definept(NULL);
621 	walk(conditional(')'), lab, 0);
622 	if (findlabel(lab + 2)->ref)
623 		definelab(lab + 2);
624 }
625 
626 /* foldcond - check if initial test in for(e1;e2;e3) S is necessary */
foldcond(Tree e1,Tree e2)627 static int foldcond(Tree e1, Tree e2) {
628 	int op = generic(e2->op);
629 	Symbol v;
630 
631 	if (e1 == 0 || e2 == 0)
632 		return 0;
633 	if (generic(e1->op) == ASGN && isaddrop(e1->kids[0]->op)
634 	&& generic(e1->kids[1]->op) == CNST) {
635 		v = e1->kids[0]->u.sym;
636 		e1 = e1->kids[1];
637 	} else
638 		return 0;
639 	if ((op==LE || op==LT || op==EQ || op==NE || op==GT || op==GE)
640 	&& generic(e2->kids[0]->op) == INDIR
641 	&& e2->kids[0]->kids[0]->u.sym == v
642 	&& e2->kids[1]->op == e1->op) {
643 		e1 = simplify(op, e2->type, e1, e2->kids[1]);
644 		if (e1->op == CNST+I)
645 			return e1->u.v.i;
646 	}
647 	return 0;
648 }
649 
650 /* localaddr - returns q if p yields the address of local/parameter q; otherwise returns 0 */
localaddr(Tree p)651 static Symbol localaddr(Tree p) {
652 	if (p == NULL)
653 		return NULL;
654 	switch (generic(p->op)) {
655 	case INDIR: case CALL: case ARG:
656 		return NULL;
657 	case ADDRL: case ADDRF:
658 		return p->u.sym;
659 	case RIGHT: case ASGN:
660 		if (p->kids[1])
661 			return localaddr(p->kids[1]);
662 		return localaddr(p->kids[0]);
663 	case COND: {
664 		Symbol q;
665 		assert(p->kids[1] && p->kids[1]->op == RIGHT);
666 		if ((q = localaddr(p->kids[1]->kids[0])) != NULL)
667 			return q;
668 		return localaddr(p->kids[1]->kids[1]);
669 		}
670 	default: {
671 		Symbol q;
672 		if (p->kids[0] && (q = localaddr(p->kids[0])) != NULL)
673 			return q;
674 		return localaddr(p->kids[1]);
675 		}
676 	}
677 }
678 
679 /* whilestmt - while ( expression ) statement */
whilestmt(int lab,Swtch swp,int lev)680 static void whilestmt(int lab, Swtch swp, int lev) {
681 	Coordinate pt;
682 	Tree e;
683 
684 	refinc *= 10.0;
685 	t = gettok();
686 	expect('(');
687 	walk(NULL, 0, 0);
688 	pt = src;
689 	e = texpr(conditional, ')', FUNC);
690 	branch(lab + 1);
691 	definelab(lab);
692 	statement(lab, swp, lev);
693 	definelab(lab + 1);
694 	definept(&pt);
695 	walk(e, lab, 0);
696 	if (findlabel(lab + 2)->ref)
697 		definelab(lab + 2);
698 }
699