shithub: scc

Download patch

ref: 7d89b20305ce03b51b7a7b03f2456d20e08b177a
parent: 46f2a2aceba13f0e4e8679e607aebb13b2efc225
author: Roberto E. Vargas Caballero <k0ga@shike2.com>
date: Tue Aug 9 09:36:20 EDT 2016

[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.

--- a/cc1/cc1.h
+++ b/cc1/cc1.h
@@ -349,7 +349,7 @@
 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);
--- a/cc1/decl.c
+++ b/cc1/decl.c
@@ -662,7 +662,7 @@
 	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;
 	}
--- a/cc1/expr.c
+++ b/cc1/expr.c
@@ -151,7 +151,7 @@
 	 * 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 @@
 			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 @@
 {
 	Type *oldtp = np->type;
 
-	if (eqtype(newtp, oldtp))
+	if (eqtype(newtp, oldtp, 0))
 		return np;
 
 	switch (oldtp->op) {
@@ -368,7 +368,7 @@
 			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;
--- a/cc1/init.c
+++ b/cc1/init.c
@@ -134,7 +134,7 @@
 
 		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;
--- a/cc1/types.c
+++ b/cc1/types.c
@@ -296,7 +296,7 @@
 	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 @@
 }
 
 int
-eqtype(Type *tp1, Type *tp2)
+eqtype(Type *tp1, Type *tp2, int equiv)
 {
 	TINT n;
 	Type **p1, **p2;
@@ -333,16 +333,18 @@
 			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;