cproc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/cproc
Log | Files | Refs | Submodules | README | LICENSE

commit f67a34503489f74fce416ce4447f291534c21f8f
parent 8c3315e5119452b48978abaf955deaabdfd015de
Author: Michael Forney <mforney@mforney.org>
Date:   Mon, 18 Feb 2019 23:25:36 -0800

Pointer operands to + and - must be complete object types

Also clean up a little and give some better error messages.

Diffstat:
Mexpr.c | 37+++++++++++++++++++++++--------------
1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/expr.c b/expr.c @@ -310,28 +310,37 @@ mkbinaryexpr(struct location *loc, enum tokenkind op, struct expression *l, stru case TADD: if (lp & PROPARITH && rp & PROPARITH) { t = commonreal(&l, &r); - } else if (l->type->kind == TYPEPOINTER && rp & PROPINT) { - t = l->type; - r = mkbinaryexpr(loc, TMUL, exprconvert(r, &typeulong), mkconstexpr(&typeulong, t->base->size)); - } else if (lp & PROPINT && r->type->kind == TYPEPOINTER) { - t = r->type; - l = mkbinaryexpr(loc, TMUL, exprconvert(l, &typeulong), mkconstexpr(&typeulong, t->base->size)); - } else { - error(loc, "invalid operands to '+' operator"); + break; } + if (r->type->kind == TYPEPOINTER) + e = l, l = r, r = e; + if (l->type->kind != TYPEPOINTER || !(rp & PROPINT)) + error(loc, "invalid operands to '+' operator"); + t = l->type; + if (t->base->incomplete) + error(loc, "pointer operand to '+' must be to complete object type"); + r = mkbinaryexpr(loc, TMUL, exprconvert(r, &typeulong), mkconstexpr(&typeulong, t->base->size)); break; case TSUB: if (lp & PROPARITH && rp & PROPARITH) { t = commonreal(&l, &r); - } else if (l->type->kind == TYPEPOINTER && rp & PROPINT) { + break; + } + if (l->type->kind != TYPEPOINTER || !(rp & PROPINT) && r->type->kind != TYPEPOINTER) + error(loc, "invalid operands to '-' operator"); + if (l->type->base->incomplete) + error(loc, "pointer operand to '-' must be to complete object type"); + if (rp & PROPINT) { t = l->type; r = mkbinaryexpr(loc, TMUL, exprconvert(r, &typeulong), mkconstexpr(&typeulong, t->base->size)); - } else if (l->type->kind == TYPEPOINTER && r->type->kind == TYPEPOINTER && typecompatible(typeunqual(l->type->base, NULL), typeunqual(r->type->base, NULL))) { - /* XXX: when is the appropriate place to convert to signed integer */ - e = mkbinaryexpr(loc, TSUB, exprconvert(l, &typelong), exprconvert(r, &typelong)); - return mkbinaryexpr(loc, TDIV, e, mkconstexpr(&typelong, l->type->base->size)); } else { - error(loc, "invalid operands to '-' operator"); + if (!typecompatible(typeunqual(l->type->base, NULL), typeunqual(r->type->base, NULL))) + error(&tok.loc, "pointer operands to '-' are to incompatible types"); + op = TDIV; + t = &typelong; + e = mkbinaryexpr(loc, TSUB, exprconvert(l, &typelong), exprconvert(r, &typelong)); + r = mkconstexpr(&typelong, l->type->base->size); + l = e; } break; case TMOD: