shithub: scc

Download patch

ref: 0681c99653ef080b235082875a2b6e5490ec4ff8
parent: 27b3c745a4bbdf3c0e6ed5d482b2fd673ba0fd83
author: Roberto E. Vargas Caballero <[email protected]>
date: Mon Apr 21 03:04:14 EDT 2014

Allow comparision between 0 and pointers

This comparision is allowed in ANSI standard and it is necessary
in expressions where pointers act as conditions.

--- a/cc1.h
+++ b/cc1.h
@@ -12,6 +12,7 @@
 	unsigned char npromote;
 	unsigned char useless;
 	unsigned char charsign;
+	unsigned char pcompare;
 };
 
 extern  struct user_opt options;
@@ -237,7 +238,6 @@
 #define SYM(s) ((union unode) {.sym = s})
 #define OP(s) ((union unode) {.op = s})
 #define TYP(s) ((union unode) {.type = s})
-#define ISNODESYM(n) ((n)->code == emitsym)
 #define ISNODEBIN(n) ((n)->code == emitbin)
 #define ISNODECMP(n) (ISNODEBIN(n) && (n)->u.op & 0x40)
 
--- a/expr.c
+++ b/expr.c
@@ -175,42 +175,47 @@
 }
 
 static Node *
-compare(char op, Node *np1, Node *np2)
+pcompare(char op, Node *np1, Node *np2)
 {
-	Type *tp1, *tp2;
-	uint8_t t1, t2;
+	if (np2->typeop == INT && np2->b.symbol && np2->u.sym->u.i == 0) {
+		np2 = castcode(np2, pvoidtype);
+	} else if (np2->typeop != PTR) {
+		error("incompatibles type in comparision");
+	} else {
+		warn(options.pcompare,
+		     "comparision between different pointer types");
+	}
 
-	np1 = promote(np1);
-	np2 = promote(np2);
-	GETBTYPE(np1, tp1, t1);
-	GETBTYPE(np2, tp2, t2);
+	return bincode(op, inttype, np1, np2);
+}
 
-	switch (t1) {
+static Node *
+compare(char op, Node *np1, Node *np2)
+{
+	switch (np1->typeop) {
 	case INT: case FLOAT:
-		switch (t2) {
+		switch (np1->typeop) {
 		case INT: case FLOAT:
-			if (tp1 != tp2)
-				typeconv(&np1, &np2);
+			typeconv(&np1, &np2);
 			break;
+		case ARY: case FTN:
+			np2 = addr2ptr(np2);
+		case PTR:
+			return pcompare(op, np2, np1);
 		default:
-			goto incompatibles;
+			goto nocompat;
 		}
 		break;
 	case ARY: case FTN:
 		np1 = addr2ptr(np1);
-		tp1 = UNQUAL(np1->type);
 	case PTR:
-		if (tp1 != tp2)
-			goto incompatibles;
-		break;
+		return pcompare(op, np1, np2);
 	default:
-		goto incompatibles;
+	nocompat:
+		error("incompatibles type in comparision");
 	}
 
 	return bincode(op, inttype, np1, np2);
-
-incompatibles:
-	error("incompatibles type in comparision");
 }
 
 static Node *
@@ -451,7 +456,7 @@
 			op = OADDR;
 			if (!np->b.lvalue)
 				goto no_lvalue;
-			if (ISNODESYM(np) && np->u.sym->s.isregister)
+			if (np->b.symbol && np->u.sym->s.isregister)
 				goto reg_address;
 			tp = mktype(tp, PTR, NULL, 0);
 			break;