Type assign(Type xty, Tree e) { Type yty = unqual(e->type); xty = unqual(xty); if (isenum(xty)) xty = xty->type; if (xty->size == 0 || yty->size == 0) return NULL; if ( isarith(xty) && isarith(yty) || isstruct(xty) && xty == yty) return xty; if (isptr(xty) && isnullptr(e)) return xty; if ((isvoidptr(xty) && isptr(yty) || isptr(xty) && isvoidptr(yty)) && ( (isconst(xty->type) || !isconst(yty->type)) && (isvolatile(xty->type) || !isvolatile(yty->type)))) return xty; if ((isptr(xty) && isptr(yty) && eqtype(unqual(xty->type), unqual(yty->type), 1)) && ( (isconst(xty->type) || !isconst(yty->type)) && (isvolatile(xty->type) || !isvolatile(yty->type)))) return xty; if (isptr(xty) && isptr(yty) && ( (isconst(xty->type) || !isconst(yty->type)) && (isvolatile(xty->type) || !isvolatile(yty->type)))) { Type lty = unqual(xty->type), rty = unqual(yty->type); if (isenum(lty) && rty == inttype || isenum(rty) && lty == inttype) { if (Aflag >= 1) warning("assignment between `%t' and `%t' is compiler-dependent\n", xty, yty); return xty; } } return NULL; }
Tree unary(void) { Tree p; switch (t) { case '*': t = gettok(); p = unary(); p = pointer(p); if (isptr(p->type) && (isfunc(p->type->type) || isarray(p->type->type))) p = retype(p, p->type->type); else { if (YYnull) p = nullcheck(p); p = rvalue(p); } break; case '&': t = gettok(); p = unary(); if (isarray(p->type) || isfunc(p->type)) p = retype(p, ptr(p->type)); else p = lvalue(p); if (isaddrop(p->op) && p->u.sym->sclass == REGISTER) error("invalid operand of unary &; `%s' is declared register\n", p->u.sym->name); else if (isaddrop(p->op)) p->u.sym->addressed = 1; break; case '+': t = gettok(); p = unary(); p = pointer(p); if (isarith(p->type)) p = cast(p, promote(p->type)); else typeerror(ADD, p, NULL); break; case '-': t = gettok(); p = unary(); p = pointer(p); if (isarith(p->type)) { Type ty = promote(p->type); p = cast(p, ty); if (isunsigned(ty)) { warning("unsigned operand of unary -\n"); p = simplify(ADD, ty, simplify(BCOM, ty, p, NULL), cnsttree(ty, 1UL)); } else p = simplify(NEG, ty, p, NULL); } else typeerror(SUB, p, NULL); break; case '~': t = gettok(); p = unary(); p = pointer(p); if (isint(p->type)) { Type ty = promote(p->type); p = simplify(BCOM, ty, cast(p, ty), NULL); } else typeerror(BCOM, p, NULL); break; case '!': t = gettok(); p = unary(); p = pointer(p); if (isscalar(p->type)) p = simplify(NOT, inttype, cond(p), NULL); else typeerror(NOT, p, NULL); break; case INCR: t = gettok(); p = unary(); p = incr(INCR, pointer(p), consttree(1, inttype)); break; case DECR: t = gettok(); p = unary(); p = incr(DECR, pointer(p), consttree(1, inttype)); break; case TYPECODE: case SIZEOF: { int op = t; Type ty; p = NULL; t = gettok(); if (t == '(') { t = gettok(); if (istypename(t, tsym)) { ty = typename(); expect(')'); } else { p = postfix(expr(')')); ty = p->type; } } else {