* 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).