9front - general discussion about 9front
 help / color / mirror / Atom feed
* Allow address expressions in ?c, even after casting to int.
@ 2019-08-31  7:10 ori
  0 siblings, 0 replies; only message in thread
From: ori @ 2019-08-31  7:10 UTC (permalink / raw)
  To: 9front; +Cc: Charles, Forsyth, charles.forsyth

This turns address expressions into constant expressions, even if they're
cast to integers. This fixes ocaml on non-x86 architectures, where this
code (paraphrased):

	#define Fl_head ((uintptr_t)(&sentinel.first_field))

produces an error because we don't have TIND, so we error on the OADD:

	'initializer is not constant: %s'

This fix takes the checks for pointers and applies them to other expressions
as well. It also makes us stricter, turning the following code from a miscompilation
into an error:

	int x;
	int y = 42;
	int *p = &x + y;

There are two concerns with this change:

	1. I may be overly strict. The OS builds on amd64, arm, mips, and arm64, but
	   there may still be operators I should allow.

	2. I'm not sure why we're doing a->left in case of OADDR; It seems that we're
       forcing it to a D_ADDR on it regardless in gextern(), so it seems like it
	   shouldn't make a difference. Is there a reason for it, or is it historical?

Thanks,

diff -r 474fd55e8a13 sys/src/cmd/cc/dcl.c
--- a/sys/src/cmd/cc/dcl.c	Fri Aug 30 20:17:19 2019 +0200
+++ b/sys/src/cmd/cc/dcl.c	Fri Aug 30 23:22:44 2019 -0700
@@ -381,27 +381,30 @@
 				diag(a, "initialization of incompatible pointers: %s\n%T and %T",
 					s->name, t, a->type);
 			}
-			switch(a->op) {
-			case OADDR:
-				a = a->left;
-				break;
-			case ONAME:
-			case OIND:
-				diag(a, "initializer is not a constant: %s", s->name);
-				return Z;
-			}
-			goto gext;
 		}
 
 		while(a->op == OCAST)
 			a = a->left;
-		if(a->op == OADDR) {
-			warn(a, "initialize pointer to an integer: %s", s->name);
+
+		switch(a->op) {
+		case OADDR:
+			if(t->etype != TIND)
+				warn(a, "initialize pointer to an integer: %s", s->name);
 			a = a->left;
-			goto gext;
+			break;
+		case OADD:
+			/*
+			 * Constants will be folded before this point, which just leaves offsets
+			 * from names.
+			 */
+			l = a->left;
+			r = a->right;
+			if(l->op == OADDR && r->op == OCONST || r->op == OADDR && l->op == OCONST)
+				break;
+		default:
+			diag(a, "initializer is not a constant: %s", s->name);
+			return Z;
 		}
-		diag(a, "initializer is not a constant: %s", s->name);
-		return Z;
 
 	gext:
 		gextern(s, a, o, t->width);



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-08-31  7:10 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-31  7:10 Allow address expressions in ?c, even after casting to int ori

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).