1 #include "c.h"
2 
3 
4 static Tree addtree(int, Tree, Tree);
5 static Tree andtree(int, Tree, Tree);
6 static Tree cmptree(int, Tree, Tree);
7 static int compatible(Type, Type);
8 static int isnullptr(Tree e);
9 static Tree multree(int, Tree, Tree);
10 static Tree subtree(int, Tree, Tree);
11 #define isvoidptr(ty) \
12 	(isptr(ty) && unqual(ty->type) == voidtype)
13 
14 Tree (*optree[])(int, Tree, Tree) = {
15 #define xx(a,b,c,d,e,f,g) e,
16 #define yy(a,b,c,d,e,f,g) e,
17 #include "token.h"
18 };
call(Tree f,Type fty,Coordinate src)19 Tree call(Tree f, Type fty, Coordinate src) {
20 	int n = 0;
21 	Tree args = NULL, r = NULL, e;
22 	Type *proto, rty = unqual(freturn(fty));
23 	Symbol t3 = NULL;
24 
25 	if (fty->u.f.oldstyle)
26 		proto = NULL;
27 	else
28 		proto = fty->u.f.proto;
29 	if (hascall(f))
30 		r = f;
31 	if (isstruct(rty))
32 		{
33 			t3 = temporary(AUTO, unqual(rty));
34 			if (rty->size == 0)
35 				error("illegal use of incomplete type `%t'\n", rty);
36 		}
37 	if (t != ')')
38 		for (;;) {
39 			Tree q = pointer(expr1(0));
40 			if (proto && *proto && *proto != voidtype)
41 				{
42 					Type aty;
43 					q = value(q);
44 					aty = assign(*proto, q);
45 					if (aty)
46 						q = cast(q, aty);
47 					else
48 						error("type error in argument %d to %s; found `%t' expected `%t'\n", n + 1, funcname(f),
49 
50 							q->type, *proto);
51 					if ((isint(q->type) || isenum(q->type))
52 					&& q->type->size != inttype->size)
53 						q = cast(q, promote(q->type));
54 					++proto;
55 				}
56 			else
57 				{
58 					if (!fty->u.f.oldstyle && *proto == NULL)
59 						error("too many arguments to %s\n", funcname(f));
60 					q = value(q);
61 					if (isarray(q->type) || q->type->size == 0)
62 						error("type error in argument %d to %s; `%t' is illegal\n", n + 1, funcname(f), q->type);
63 
64 					else
65 						q = cast(q, promote(q->type));
66 				}
67 			if (!IR->wants_argb && isstruct(q->type)) {
68 				if (iscallb(q))
69 					q = addrof(q);
70 				else {
71 					Symbol t1 = temporary(AUTO, unqual(q->type));
72 					q = asgn(t1, q);
73 					q = tree(RIGHT, ptr(t1->type),
74 						root(q), lvalue(idtree(t1)));
75 				}
76 			}
77 			if (q->type->size == 0)
78 				q->type = inttype;
79 			if (hascall(q))
80 				r = r ? tree(RIGHT, voidtype, r, q) : q;
81 			args = tree(mkop(ARG, q->type), q->type, q, args);
82 			n++;
83 			if (Aflag >= 2 && n == 32)
84 				warning("more than 31 arguments in a call to %s\n",
85 					funcname(f));
86 			if (t != ',')
87 				break;
88 			t = gettok();
89 		}
90 	expect(')');
91 	if (proto && *proto && *proto != voidtype)
92 		error("insufficient number of arguments to %s\n",
93 			funcname(f));
94 	if (r)
95 		args = tree(RIGHT, voidtype, r, args);
96 	e = calltree(f, rty, args, t3);
97 	if (events.calls)
98 		apply(events.calls, &src, &e);
99 	return e;
100 }
calltree(Tree f,Type ty,Tree args,Symbol t3)101 Tree calltree(Tree f, Type ty, Tree args, Symbol t3) {
102 	Tree p;
103 
104 	if (args)
105 		f = tree(RIGHT, f->type, args, f);
106 	if (isstruct(ty))
107 		assert(t3),
108 		p = tree(RIGHT, ty,
109 			tree(CALL+B, ty, f, addrof(idtree(t3))),
110 			idtree(t3));
111 	else {
112 		Type rty = ty;
113 		if (isenum(ty))
114 			rty = unqual(ty)->type;
115 		if (!isfloat(rty))
116 			rty = promote(rty);
117 		p = tree(mkop(CALL, rty), rty, f, NULL);
118 		if (isptr(ty) || p->type->size > ty->size)
119 			p = cast(p, ty);
120 	}
121 	return p;
122 }
vcall(Symbol func,Type ty,...)123 Tree vcall(Symbol func, Type ty, ...) {
124 	va_list ap;
125 	Tree args = NULL, e, f = pointer(idtree(func)), r = NULL;
126 
127 	assert(isfunc(func->type));
128 	if (ty == NULL)
129 		ty = freturn(func->type);
130 	va_start(ap, ty);
131 	while ((e = va_arg(ap, Tree)) != NULL) {
132 		if (hascall(e))
133 			r = r == NULL ? e : tree(RIGHT, voidtype, r, e);
134 		args = tree(mkop(ARG, e->type), e->type, e, args);
135 	}
136 	va_end(ap);
137 	if (r != NULL)
138 		args = tree(RIGHT, voidtype, r, args);
139 	return calltree(f, ty, args, NULL);
140 }
iscallb(Tree e)141 int iscallb(Tree e) {
142 	return e->op == RIGHT && e->kids[0] && e->kids[1]
143 		&& e->kids[0]->op == CALL+B
144 		&& e->kids[1]->op == INDIR+B
145 		&& isaddrop(e->kids[1]->kids[0]->op)
146 		&& e->kids[1]->kids[0]->u.sym->temporary;
147 }
148 
addtree(int op,Tree l,Tree r)149 static Tree addtree(int op, Tree l, Tree r) {
150 	Type ty = inttype;
151 
152 	if (isarith(l->type) && isarith(r->type)) {
153 		ty = binary(l->type, r->type);
154 		l = cast(l, ty);
155 		r = cast(r, ty);
156 	} else if (isptr(l->type) && isint(r->type))
157 		return addtree(ADD, r, l);
158 	else if (  isptr(r->type) && isint(l->type)
159 	&& !isfunc(r->type->type))
160 		{
161 			long n;
162 			ty = unqual(r->type);
163 			n = unqual(ty->type)->size;
164 			if (n == 0)
165 				error("unknown size for type `%t'\n", ty->type);
166 			l = cast(l, promote(l->type));
167 			if (n > 1)
168 				l = multree(MUL, cnsttree(signedptr, n), l);
169 			if (YYcheck && !isaddrop(r->op))		/* omit */
170 				return nullcall(ty, YYcheck, r, l);	/* omit */
171 			return simplify(ADD, ty, l, r);
172 		}
173 
174 	else
175 		typeerror(op, l, r);
176 	return simplify(op, ty, l, r);
177 }
178 
cnsttree(Type ty,...)179 Tree cnsttree(Type ty, ...) {
180 	Tree p = tree(mkop(CNST,ty), ty, NULL, NULL);
181 	va_list ap;
182 
183 	va_start(ap, ty);
184 	switch (ty->op) {
185 	case INT:     p->u.v.i = va_arg(ap, long); break;
186 	case UNSIGNED:p->u.v.u = va_arg(ap, unsigned long)&ones(8*ty->size); break;
187 	case FLOAT:   p->u.v.d = va_arg(ap, double); break;
188 	case POINTER: p->u.v.p = va_arg(ap, void *); break;
189 	default: assert(0);
190 	}
191 	va_end(ap);
192 	return p;
193 }
194 
consttree(unsigned n,Type ty)195 Tree consttree(unsigned n, Type ty) {
196 	if (isarray(ty))
197 		ty = atop(ty);
198 	else assert(isint(ty));
199 	return cnsttree(ty, (unsigned long)n);
200 }
cmptree(int op,Tree l,Tree r)201 static Tree cmptree(int op, Tree l, Tree r) {
202 	Type ty;
203 
204 	if (isarith(l->type) && isarith(r->type)) {
205 		ty = binary(l->type, r->type);
206 		l = cast(l, ty);
207 		r = cast(r, ty);
208 	} else if (compatible(l->type, r->type)) {
209 		ty = unsignedptr;
210 		l = cast(l, ty);
211 		r = cast(r, ty);
212 	} else {
213 		ty = unsignedtype;
214 		typeerror(op, l, r);
215 	}
216 	return simplify(mkop(op,ty), inttype, l, r);
217 }
compatible(Type ty1,Type ty2)218 static int compatible(Type ty1, Type ty2) {
219 	return isptr(ty1) && !isfunc(ty1->type)
220 	    && isptr(ty2) && !isfunc(ty2->type)
221 	    && eqtype(unqual(ty1->type), unqual(ty2->type), 0);
222 }
isnullptr(Tree e)223 static int isnullptr(Tree e) {
224 	Type ty = unqual(e->type);
225 
226 	return generic(e->op) == CNST
227 	    && ((ty->op == INT      && e->u.v.i == 0)
228 	     || (ty->op == UNSIGNED && e->u.v.u == 0)
229 	     || (isvoidptr(ty)      && e->u.v.p == NULL));
230 }
eqtree(int op,Tree l,Tree r)231 Tree eqtree(int op, Tree l, Tree r) {
232 	Type xty = l->type, yty = r->type;
233 
234 	if ((isptr(xty) && isnullptr(r))
235 	||  (isptr(xty) && !isfunc(xty->type) && isvoidptr(yty))
236 	||  (isptr(xty) && isptr(yty)
237 	    && eqtype(unqual(xty->type), unqual(yty->type), 1))) {
238 		Type ty = unsignedptr;
239 		l = cast(l, ty);
240 		r = cast(r, ty);
241 		return simplify(mkop(op,ty), inttype, l, r);
242 	}
243 	if ((isptr(yty) && isnullptr(l))
244 	||  (isptr(yty) && !isfunc(yty->type) && isvoidptr(xty)))
245 		return eqtree(op, r, l);
246 	return cmptree(op, l, r);
247 }
248 
assign(Type xty,Tree e)249 Type assign(Type xty, Tree e) {
250 	Type yty = unqual(e->type);
251 
252 	xty = unqual(xty);
253 	if (isenum(xty))
254 		xty = xty->type;
255 	if (xty->size == 0 || yty->size == 0)
256 		return NULL;
257 	if ( (isarith(xty) && isarith(yty))
258 	||  (isstruct(xty) && xty == yty))
259 		return xty;
260 	if (isptr(xty) && isnullptr(e))
261 		return xty;
262 	if (((isvoidptr(xty) && isptr(yty))
263 	  || (isptr(xty)     && isvoidptr(yty)))
264 	&& (  (isconst(xty->type)    || !isconst(yty->type))
265 	   && (isvolatile(xty->type) || !isvolatile(yty->type))))
266 		return xty;
267 
268 	if ((isptr(xty) && isptr(yty)
269 	    && eqtype(unqual(xty->type), unqual(yty->type), 1))
270 	&&  (  (isconst(xty->type)    || !isconst(yty->type))
271 	    && (isvolatile(xty->type) || !isvolatile(yty->type))))
272 		return xty;
273 	if (isptr(xty) && isptr(yty)
274 	&& (  (isconst(xty->type)    || !isconst(yty->type))
275 	   && (isvolatile(xty->type) || !isvolatile(yty->type)))) {
276 		Type lty = unqual(xty->type), rty = unqual(yty->type);
277 		if ((isenum(lty) && rty == inttype)
278 		||  (isenum(rty) && lty == inttype)) {
279 			if (Aflag >= 1)
280 				warning("assignment between `%t' and `%t' is compiler-dependent\n",
281 					xty, yty);
282 			return xty;
283 		}
284 	}
285 	return NULL;
286 }
asgntree(int op,Tree l,Tree r)287 Tree asgntree(int op, Tree l, Tree r) {
288 	Type aty, ty;
289 
290 	r = pointer(r);
291 	ty = assign(l->type, r);
292 	if (ty)
293 		r = cast(r, ty);
294 	else {
295 		typeerror(ASGN, l, r);
296 		if (r->type == voidtype)
297 			r = retype(r, inttype);
298 		ty = r->type;
299 	}
300 	if (l->op != FIELD)
301 		l = lvalue(l);
302 	aty = l->type;
303 	if (isptr(aty))
304 		aty = unqual(aty)->type;
305 	if ( isconst(aty)
306 	||  (isstruct(aty) && unqual(aty)->u.sym->u.s.cfields)) {
307 		if (isaddrop(l->op)
308 		&& !l->u.sym->computed && !l->u.sym->generated)
309 			error("assignment to const identifier `%s'\n",
310 				l->u.sym->name);
311 		else
312 			error("assignment to const location\n");
313 	}
314 	if (l->op == FIELD) {
315 		long n = 8*l->u.field->type->size - fieldsize(l->u.field);
316 		if (n > 0 && isunsigned(l->u.field->type))
317 			r = bittree(BAND, r,
318 				cnsttree(r->type, (unsigned long)fieldmask(l->u.field)));
319 		else if (n > 0) {
320 			if (r->op == CNST+I) {
321 				n = r->u.v.i;
322 				if (n&(1<<(fieldsize(l->u.field)-1)))
323 					n |= ~0UL<<fieldsize(l->u.field);
324 				r = cnsttree(r->type, n);
325 			} else
326 				r = shtree(RSH,
327 					shtree(LSH, r, cnsttree(inttype, n)),
328 					cnsttree(inttype, n));
329 		}
330 	}
331 	if (isstruct(ty) && isaddrop(l->op) && iscallb(r))
332 		return tree(RIGHT, ty,
333 			tree(CALL+B, ty, r->kids[0]->kids[0], l),
334 			idtree(l->u.sym));
335 	return tree(mkop(op,ty), ty, l, r);
336 }
condtree(Tree e,Tree l,Tree r)337 Tree condtree(Tree e, Tree l, Tree r) {
338 	Symbol t1;
339 	Type ty, xty = l->type, yty = r->type;
340 	Tree p;
341 
342 	if (isarith(xty) && isarith(yty))
343 		ty = binary(xty, yty);
344 	else if (eqtype(xty, yty, 1))
345 		ty = unqual(xty);
346 	else if (isptr(xty)   && isnullptr(r))
347 		ty = xty;
348 	else if (isnullptr(l) && isptr(yty))
349 		ty = yty;
350 	else if ((isptr(xty) && !isfunc(xty->type) && isvoidptr(yty))
351 	||       (isptr(yty) && !isfunc(yty->type) && isvoidptr(xty)))
352 		ty = voidptype;
353 	else if ((isptr(xty) && isptr(yty)
354 		 && eqtype(unqual(xty->type), unqual(yty->type), 1)))
355 		ty = xty;
356 	else {
357 		typeerror(COND, l, r);
358 		return consttree(0, inttype);
359 	}
360 	if (isptr(ty)) {
361 		ty = unqual(unqual(ty)->type);
362 		if ((isptr(xty) && isconst(unqual(xty)->type))
363 		||  (isptr(yty) && isconst(unqual(yty)->type)))
364 			ty = qual(CONST, ty);
365 		if ((isptr(xty) && isvolatile(unqual(xty)->type))
366 		||  (isptr(yty) && isvolatile(unqual(yty)->type)))
367 			ty = qual(VOLATILE, ty);
368 		ty = ptr(ty);
369 	}
370 	switch (e->op) {
371 	case CNST+I: return cast(e->u.v.i != 0   ? l : r, ty);
372 	case CNST+U: return cast(e->u.v.u != 0   ? l : r, ty);
373 	case CNST+P: return cast(e->u.v.p != 0   ? l : r, ty);
374 	case CNST+F: return cast(e->u.v.d != 0.0 ? l : r, ty);
375 	}
376 	if (ty != voidtype && ty->size > 0) {
377 		t1 = genident(REGISTER, unqual(ty), level);
378 	/*	t1 = temporary(REGISTER, unqual(ty)); */
379 		l = asgn(t1, l);
380 		r = asgn(t1, r);
381 	} else
382 		t1 = NULL;
383 	p = tree(COND, ty, cond(e),
384 		tree(RIGHT, ty, root(l), root(r)));
385 	p->u.sym = t1;
386 	return p;
387 }
388 /* addrof - address of p */
addrof(Tree p)389 Tree addrof(Tree p) {
390 	Tree q = p;
391 
392 	for (;;)
393 		switch (generic(q->op)) {
394 		case RIGHT:
395 			assert(q->kids[0] || q->kids[1]);
396 			q = q->kids[1] ? q->kids[1] : q->kids[0];
397 			continue;
398 		case ASGN:
399 			q = q->kids[1];
400 			continue;
401 		case COND: {
402 			Symbol t1 = q->u.sym;
403 			q->u.sym = 0;
404 			q = idtree(t1);
405 			/* fall thru */
406 			}
407 		case INDIR:
408 			if (p == q)
409 				return q->kids[0];
410 			q = q->kids[0];
411 			return tree(RIGHT, q->type, root(p), q);
412 		default:
413 			error("addressable object required\n");
414 			return value(p);
415 		}
416 }
417 
418 /* andtree - construct tree for l [&& ||] r */
andtree(int op,Tree l,Tree r)419 static Tree andtree(int op, Tree l, Tree r) {
420 	if (!isscalar(l->type) || !isscalar(r->type))
421 		typeerror(op, l, r);
422 	return simplify(op, inttype, cond(l), cond(r));
423 }
424 
425 /* asgn - generate tree for assignment of expr e to symbol p sans qualifiers */
asgn(Symbol p,Tree e)426 Tree asgn(Symbol p, Tree e) {
427 	if (isarray(p->type))
428 		e = tree(ASGN+B, p->type, idtree(p),
429 			tree(INDIR+B, e->type, e, NULL));
430 	else {
431 		Type ty = p->type;
432 		p->type = unqual(p->type);
433 		if (isstruct(p->type) && p->type->u.sym->u.s.cfields) {
434 			p->type->u.sym->u.s.cfields = 0;
435 			e = asgntree(ASGN, idtree(p), e);
436 			p->type->u.sym->u.s.cfields = 1;
437 		} else
438 			e = asgntree(ASGN, idtree(p), e);
439 		p->type = ty;
440 	}
441 	return e;
442 }
443 
444 /* bittree - construct tree for l [& | ^ %] r */
bittree(int op,Tree l,Tree r)445 Tree bittree(int op, Tree l, Tree r) {
446 	Type ty = inttype;
447 
448 	if (isint(l->type) && isint(r->type)) {
449  		ty = binary(l->type, r->type);
450 		l = cast(l, ty);
451 		r = cast(r, ty);
452 	} else
453 		typeerror(op, l, r);
454 	return simplify(op, ty, l, r);
455 }
456 
457 /* multree - construct tree for l [* /] r */
multree(int op,Tree l,Tree r)458 static Tree multree(int op, Tree l, Tree r) {
459 	Type ty = inttype;
460 
461 	if (isarith(l->type) && isarith(r->type)) {
462 		ty = binary(l->type, r->type);
463 		l = cast(l, ty);
464 		r = cast(r, ty);
465 	} else
466 		typeerror(op, l, r);
467 	return simplify(op, ty, l, r);
468 }
469 
470 /* shtree - construct tree for l [>> <<] r */
shtree(int op,Tree l,Tree r)471 Tree shtree(int op, Tree l, Tree r) {
472 	Type ty = inttype;
473 
474 	if (isint(l->type) && isint(r->type)) {
475 		ty = promote(l->type);
476 		l = cast(l, ty);
477 		r = cast(r, inttype);
478 	} else
479 		typeerror(op, l, r);
480 	return simplify(op, ty, l, r);
481 }
482 
483 /* subtree - construct tree for l - r */
subtree(int op,Tree l,Tree r)484 static Tree subtree(int op, Tree l, Tree r) {
485 	long n;
486 	Type ty = inttype;
487 
488 	if (isarith(l->type) && isarith(r->type)) {
489 		ty = binary(l->type, r->type);
490 		l = cast(l, ty);
491 		r = cast(r, ty);
492 	} else if (isptr(l->type) && !isfunc(l->type->type) && isint(r->type)) {
493 		ty = unqual(l->type);
494 		n = unqual(ty->type)->size;
495 		if (n == 0)
496 			error("unknown size for type `%t'\n", ty->type);
497 		r = cast(r, promote(r->type));
498 		if (n > 1)
499 			r = multree(MUL, cnsttree(signedptr, n), r);
500 		if (isunsigned(r->type))
501 			r = cast(r, unsignedptr);
502 		else
503 			r = cast(r, signedptr);
504 		return simplify(SUB+P, ty, l, r);
505 	} else if (compatible(l->type, r->type)) {
506 		ty = unqual(l->type);
507 		n = unqual(ty->type)->size;
508 		if (n == 0)
509 			error("unknown size for type `%t'\n", ty->type);
510 		l = simplify(SUB+U, unsignedptr,
511 			cast(l, unsignedptr), cast(r, unsignedptr));
512 		return simplify(DIV+I, longtype,
513 			cast(l, longtype), cnsttree(longtype, n));
514 	} else
515 		typeerror(op, l, r);
516 	return simplify(op, ty, l, r);
517 }
518 
519 /* typeerror - issue "operands of op have illegal types `l' and `r'" */
typeerror(int op,Tree l,Tree r)520 void typeerror(int op, Tree l, Tree r) {
521 	int i;
522 	static struct { int op; char *name; } ops[] = {
523 		{ASGN, "="},	{INDIR, "*"},	{NEG,  "-"},
524 		{ADD,  "+"},	{SUB,   "-"},	{LSH,  "<<"},
525 		{MOD,  "%"},	{RSH,   ">>"},	{BAND, "&"},
526 		{BCOM, "~"},	{BOR,   "|"},	{BXOR, "^"},
527 		{DIV,  "/"},	{MUL,   "*"},	{EQ,   "=="},
528 		{GE,   ">="},	{GT,    ">"},	{LE,   "<="},
529 		{LT,   "<"},	{NE,    "!="},	{AND,  "&&"},
530 		{NOT,  "!"},	{OR,    "||"},	{COND, "?:"},
531 		{0, 0}
532 	};
533 
534 	op = generic(op);
535 	for (i = 0; ops[i].op; i++)
536 		if (op == ops[i].op)
537 			break;
538 	assert(ops[i].name);
539 	if (r)
540 		error("operands of %s have illegal types `%t' and `%t'\n",
541 			ops[i].name, l->type, r->type);
542 	else
543 		error("operand of unary %s has illegal type `%t'\n", ops[i].name,
544 			l->type);
545 }
546