changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: Allow address expressions in ?c after int casts.

changeset 7374: b8660f06b4bb
parent 7373: c16364593cbe
child 7377: f6b32f6f4b93
author: Ori Bernstein <ori@eigenstate.org>
date: Sat, 07 Sep 2019 18:25:04 -0700
files: sys/src/cmd/cc/dcl.c
description: Allow address expressions in ?c after int casts.

This fixes ocaml on non-x86 architectures, where we have code
that looks like:

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

Without this change, we get an error about a non-constant
initializer. This change takes the checks for pointers and
makes them apply to all expressions. It also makes the checks
stricter, preventing the following from compiling to junk:

int x;
int y = 42;
int *p = &x + y
     1.1--- a/sys/src/cmd/cc/dcl.c
     1.2+++ b/sys/src/cmd/cc/dcl.c
     1.3@@ -373,35 +373,35 @@ init1(Sym *s, Type *t, long o, int exfla
     1.4 			goto gext;
     1.5 		}
     1.6 		if(t->etype == TIND) {
     1.7-			while(a->op == OCAST) {
     1.8+			if(a->op == OCAST)
     1.9 				warn(a, "CAST in initialization ignored");
    1.10-				a = a->left;
    1.11-			}
    1.12-			if(!sametype(t, a->type)) {
    1.13+			if(!sametype(t, a->type))
    1.14 				diag(a, "initialization of incompatible pointers: %s\n%T and %T",
    1.15 					s->name, t, a->type);
    1.16-			}
    1.17-			switch(a->op) {
    1.18-			case OADDR:
    1.19-				a = a->left;
    1.20-				break;
    1.21-			case ONAME:
    1.22-			case OIND:
    1.23-				diag(a, "initializer is not a constant: %s", s->name);
    1.24-				return Z;
    1.25-			}
    1.26-			goto gext;
    1.27 		}
    1.28 
    1.29 		while(a->op == OCAST)
    1.30 			a = a->left;
    1.31-		if(a->op == OADDR) {
    1.32-			warn(a, "initialize pointer to an integer: %s", s->name);
    1.33+
    1.34+		switch(a->op) {
    1.35+		case OADDR:
    1.36+			if(t->etype != TIND)
    1.37+				warn(a, "initialize pointer to an integer: %s", s->name);
    1.38 			a = a->left;
    1.39-			goto gext;
    1.40+			break;
    1.41+		case OADD:
    1.42+			/*
    1.43+			 * Constants will be folded before this point, which just leaves offsets
    1.44+			 * from names.
    1.45+			 */
    1.46+			l = a->left;
    1.47+			r = a->right;
    1.48+			if(l->op == OADDR && r->op == OCONST || r->op == OADDR && l->op == OCONST)
    1.49+				break;
    1.50+		default:
    1.51+			diag(a, "initializer is not a constant: %s", s->name);
    1.52+			return Z;
    1.53 		}
    1.54-		diag(a, "initializer is not a constant: %s", s->name);
    1.55-		return Z;
    1.56 
    1.57 	gext:
    1.58 		gextern(s, a, o, t->width);