shithub: riscv

Download patch

ref: ff344562dbefe0e53adc900b6e7cd962ae555e94
parent: f360729664eb91e8ee692bdabbf3b5b655cd8959
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Jun 18 18:17:19 EDT 2019

Import compiler warnings and bugfixes from Charles.

This change imports a few warnings and minor fixes from Charles branch
here: https://bitbucket.org/plan9-from-bell-labs/plan9.

The changes included here:


	changeset:   1374:9185dc017be0
	summary:     declare castucom; move a declaration into order;
	             use cast instead of ULL suffix
	changeset:   1353:5fe8380b1818
	summary:     supporting functions:
	             1. castucom to match unlikely mask operation;
  	             2. be sure to snap both sides of pointer subtraction completely;
	             3. add extra operators as side-effect free
	changeset:   1352:90058c092d66
	summary:     1. correct result type for mixed-mode assignment operators
	             2. detect divide by zero (erik);
	             3. detect masks misformed by sign-extension;
	             4. diagnose mixed old/new prototypes

--- a/sys/src/cmd/cc/cc.h
+++ b/sys/src/cmd/cc/cc.h
@@ -662,6 +662,7 @@
  * sub.c
  */
 void	arith(Node*, int);
+int	castucom(Node*);
 int	deadheads(Node*);
 Type*	dotsearch(Sym*, Type*, Node*, long*);
 long	dotoffset(Type*, Type*, Node*);
--- a/sys/src/cmd/cc/com.c
+++ b/sys/src/cmd/cc/com.c
@@ -266,12 +266,15 @@
 		arith(n, 0);
 		while(n->left->op == OCAST)
 			n->left = n->left->left;
-		if(!sametype(t, n->type) && !mixedasop(t, n->type)) {
-			r = new1(OCAST, n->right, Z);
-			r->type = t;
-			n->right = r;
+		if(!mixedasop(t, n->type)) {
+			if(!sametype(t, n->type)) {
+				r = new1(OCAST, n->right, Z);
+				r->type = t;
+				n->right = r;
+				n->type = t;
+			}
+		}else
 			n->type = t;
-		}
 		if(typeu[n->type->etype]) {
 			if(n->op == OASMOD)
 				n->op = OASLMOD;
@@ -1044,6 +1047,23 @@
 	case OASADD:
 		ccom(l);
 		ccom(r);
+		if(n->op == OASMOD || n->op == OASLMOD || n->op == OASDIV || n->op == OASLDIV)
+		if(r->op == OCONST){
+			if(!typefd[r->type->etype] && r->vconst == 0) {
+				if(n->op == OASMOD || n->op == OASLMOD)
+					diag(n, "modulo by zero");
+				else
+					diag(n, "divide by zero");
+				r->vconst = ~0;
+			}
+			if(typefd[r->type->etype] && r->fconst == 0.) {
+				if(n->op == OASMOD || n->op == OASLMOD)
+					diag(n, "modulo by zero");
+				else
+					diag(n, "divide by zero");
+				r->fconst = 1e10;
+			}
+		}
 		if(n->op == OASLSHR || n->op == OASASHR || n->op == OASASHL)
 		if(r->op == OCONST) {
 			t = n->type->width * 8;	/* bits per byte */
@@ -1053,6 +1073,8 @@
 		break;
 
 	case OCAST:
+		if(castucom(n))
+			warn(n, "32-bit unsigned complement zero-extended to 64 bits");
 		ccom(l);
 		if(l->op == OCONST) {
 			evconst(n);
--- a/sys/src/cmd/cc/sub.c
+++ b/sys/src/cmd/cc/sub.c
@@ -659,7 +659,7 @@
 	Type *t1, *t2;
 	int i, j, k;
 	Node *n1;
-	long w;
+	long w, x;
 
 	t1 = n->left->type;
 	if(n->right == Z)
@@ -689,7 +689,19 @@
 	if(n->op == OSUB)
 	if(i == TIND && j == TIND) {
 		w = n->right->type->link->width;
-		if(w < 1 || n->left->type->link == T || n->left->type->link->width < 1)
+		if(w < 1) {
+			snap(n->right->type->link);
+			w = n->right->type->link->width;
+		}
+		x = 0;
+		if(n->left->type->link != T) {
+			x = n->left->type->link->width;
+			if(x < 1) {
+				snap(n->left->type->link);
+				x = n->left->type->link->width;
+			}
+		}
+		if(w < 1 || x < 1)
 			goto bad;
 		n->type = types[ewidth[TIND] <= ewidth[TLONG]? TLONG: TVLONG];
 		if(w > 1) {
@@ -991,6 +1003,8 @@
 	case OOROR:
 	case OCOMMA:
 	case ODOT:
+	case OFAS:
+	case OINDEX:
 		if(side(n->left))
 			break;
 		n = n->right;
@@ -2073,4 +2087,22 @@
 mixedasop(Type *l, Type *r)
 {
 	return !typefd[l->etype] && typefd[r->etype];
+}
+
+
+/*
+ * (uvlong)~ul creates a ul mask with top bits zero, which is usually wrong
+ * an explicit cast to ulong after ~ suppresses the diagnostic
+ */
+int
+castucom(Node *r)
+{
+	Node *rl;
+
+	if(r->op == OCAST &&
+	   (rl = r->left)->op == OCOM &&
+	   (r->type->etype == TVLONG || r->type->etype == TUVLONG) &&
+	   typeu[rl->type->etype] && typechl[rl->type->etype])
+		return 1;
+	return 0;
 }