scc

simple C compiler
git clone git://git.2f30.org/scc
Log | Files | Refs | README | LICENSE

commit 7090df164ce7ae97854a3b991427160d2d79dac6
parent a95ef32db1f0d1b14b094edfd7d9c3fc002929e2
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Tue,  9 Aug 2016 13:36:20 +0200

[cc1] Add equiv parameter to eqtype()

Eqtype() compare two types, but it was checking always that
the types were exactly the same, and in some situations is
needed to check that two types are equivalent. Both
situations shared almost all the code, so the best option
is to add a new parameter to control what behaviour
the caller expects.

Diffstat:
Mcc1/cc1.h | 2+-
Mcc1/decl.c | 2+-
Mcc1/expr.c | 8++++----
Mcc1/init.c | 2+-
Mcc1/types.c | 10++++++----
5 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/cc1/cc1.h b/cc1/cc1.h @@ -349,7 +349,7 @@ extern void errorp(char *fmt, ...); extern void cpperror(char *fmt, ...); /* types.c */ -extern int eqtype(Type *tp1, Type *tp2); +extern int eqtype(Type *tp1, Type *tp2, int eqflag); extern Type *ctype(unsigned type, unsigned sign, unsigned size); extern Type *mktype(Type *tp, int op, TINT nelem, Type *data[]); extern Type *duptype(Type *base); diff --git a/cc1/decl.c b/cc1/decl.c @@ -662,7 +662,7 @@ redcl(Symbol *sym, Type *tp, Symbol **pars, int sclass) int flags; char *name = sym->name; - if (!eqtype(sym->type, tp)) { + if (!eqtype(sym->type, tp, 1)) { errorp("conflicting types for '%s'", name); return sym; } diff --git a/cc1/expr.c b/cc1/expr.c @@ -151,7 +151,7 @@ chkternary(Node *yes, Node *no) * take a look to 6.5.15 */ - if (!eqtype(yes->type, no->type)) { + if (!eqtype(yes->type, no->type, 1)) { if ((yes->type->prop & TARITH) && (no->type->prop & TARITH)) { arithconv(&yes, &no); } else if (yes->type->op != PTR && no->type->op != PTR) { @@ -178,7 +178,7 @@ chkternary(Node *yes, Node *no) if (null(no)) no = convert(no, yes->type, 0); - if (!eqtype(yes->type, no->type)) + if (!eqtype(yes->type, no->type, 1)) goto wrong_type; } } @@ -263,7 +263,7 @@ convert(Node *np, Type *newtp, char iscast) { Type *oldtp = np->type; - if (eqtype(newtp, oldtp)) + if (eqtype(newtp, oldtp, 0)) return np; switch (oldtp->op) { @@ -368,7 +368,7 @@ pcompare(char op, Node *lp, Node *rp) err = 1; rp = convert(rp, pvoidtype, 1); } else if (rp->type->op == PTR) { - if (!eqtype(lp->type, rp->type)) + if (!eqtype(lp->type, rp->type, 1)) err = 1; } else { err = 1; diff --git a/cc1/init.c b/cc1/init.c @@ -134,7 +134,7 @@ initialize(Type *tp) return np; } - if (eqtype(tp, np->type)) + if (eqtype(tp, np->type, 1)) return np; if ((aux = convert(decay(np), tp, 0)) != NULL) return aux; diff --git a/cc1/types.c b/cc1/types.c @@ -296,7 +296,7 @@ mktype(Type *tp, int op, TINT nelem, Type *pars[]) t = (op ^ (uintptr_t) tp >> 3) & NR_TYPE_HASH-1; tbl = &typetab[t]; for (bp = *tbl; bp; bp = bp->next) { - if (eqtype(bp, &type) && op != STRUCT && op != UNION) { + if (eqtype(bp, &type, 0) && op != STRUCT && op != UNION) { /* * pars was allocated by the caller * but the type already exists, so @@ -314,7 +314,7 @@ mktype(Type *tp, int op, TINT nelem, Type *pars[]) } int -eqtype(Type *tp1, Type *tp2) +eqtype(Type *tp1, Type *tp2, int equiv) { TINT n; Type **p1, **p2; @@ -333,16 +333,18 @@ eqtype(Type *tp1, Type *tp2) return 0; p1 = tp1->p.pars, p2 = tp2->p.pars; for (n = tp1->n.elem; n > 0; --n) { - if (!eqtype(*p1++, *p2++)) + if (!eqtype(*p1++, *p2++, equiv)) return 0; } goto check_base; case ARY: + if (equiv && (tp1->n.elem == 0 || tp2->n.elem == 0)) + goto check_base; if (tp1->n.elem != tp2->n.elem) return 0; case PTR: check_base: - return eqtype(tp1->type, tp2->type); + return eqtype(tp1->type, tp2->type, equiv); case VOID: case ENUM: return 0;