cmd/cc: generate error if #pragma pack off does anything

We can't translate misaligned things to Go, so start rejecting them in C.

The only one in any build appears to be EpollEvent on linux/amd64.
Fix that.

LGTM=r
R=golang-codereviews, r, dvyukov
CC=golang-codereviews, iant
https://golang.org/cl/137020043
This commit is contained in:
Russ Cox 2014-08-30 14:54:09 -04:00
parent 50199d7b35
commit 86c4c4f00c
5 changed files with 20 additions and 11 deletions

View File

@ -374,10 +374,11 @@ align(int32 i, Type *t, int op, int32 *maxalign)
{
int32 o;
Type *v;
int w;
int w, packw;
o = i;
w = 1;
packw = 0;
switch(op) {
default:
diag(Z, "unknown align opcode %d", op);
@ -388,7 +389,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
if(w < 1)
w = 1;
if(packflg)
w = packflg;
packw = packflg;
break;
case Ael1: /* initial align of struct element */
@ -404,7 +405,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
if(w < 1 || w > SZ_LONG)
fatal(Z, "align");
if(packflg)
w = packflg;
packw = packflg;
break;
case Ael2: /* width of a struct element */
@ -440,6 +441,8 @@ align(int32 i, Type *t, int op, int32 *maxalign)
w = SZ_LONG; /* because of a pun in cc/dcl.c:contig() */
break;
}
if(packw != 0 && xround(o, w) != xround(o, packw))
diag(Z, "#pragma pack changes offset of %T", t);
o = xround(o, w);
if(maxalign != nil && *maxalign < w)
*maxalign = w;

View File

@ -250,10 +250,11 @@ align(int32 i, Type *t, int op, int32 *maxalign)
{
int32 o;
Type *v;
int w;
int w, packw;
o = i;
w = 1;
packw = 0;
switch(op) {
default:
diag(Z, "unknown align opcode %d", op);
@ -264,7 +265,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
if(w < 1)
w = 1;
if(packflg)
w = packflg;
packw = packflg;
break;
case Ael1: /* initial align of struct element */
@ -277,7 +278,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
if(w < 1 || w > SZ_VLONG)
fatal(Z, "align");
if(packflg)
w = packflg;
packw = packflg;
break;
case Ael2: /* width of a struct element */
@ -331,6 +332,8 @@ align(int32 i, Type *t, int op, int32 *maxalign)
o = align(o, t, Ael2, nil);
break;
}
if(packw != 0 && xround(o, w) != xround(o, packw))
diag(Z, "#pragma pack changes offset of %T", t);
o = xround(o, w);
if(maxalign && *maxalign < w)
*maxalign = w;

View File

@ -255,10 +255,11 @@ align(int32 i, Type *t, int op, int32 *maxalign)
{
int32 o;
Type *v;
int w;
int w, packw;
o = i;
w = 1;
packw = 0;
switch(op) {
default:
diag(Z, "unknown align opcode %d", op);
@ -269,7 +270,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
if(w < 1)
w = 1;
if(packflg)
w = packflg;
packw = packflg;
break;
case Ael1: /* initial align of struct element */
@ -285,7 +286,7 @@ align(int32 i, Type *t, int op, int32 *maxalign)
if(w < 1 || w > SZ_LONG)
fatal(Z, "align");
if(packflg)
w = packflg;
packw = packflg;
break;
case Ael2: /* width of a struct element */
@ -320,6 +321,8 @@ align(int32 i, Type *t, int op, int32 *maxalign)
o = align(o, t, Ael2, nil);
break;
}
if(packw != 0 && xround(o, w) != xround(o, packw))
diag(Z, "#pragma pack changes offset of %T", t);
o = xround(o, w);
if(maxalign && *maxalign < w)
*maxalign = w;

View File

@ -122,7 +122,7 @@ struct Itimerval {
};
struct EpollEvent {
uint32 events;
uint64 data;
byte data[8]; // unaligned uintptr
};

View File

@ -37,7 +37,7 @@ runtime·netpollopen(uintptr fd, PollDesc *pd)
int32 res;
ev.events = EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET;
ev.data = (uint64)pd;
*(uintptr*)ev.data = (uintptr)pd;
res = runtime·epollctl(epfd, EPOLL_CTL_ADD, (int32)fd, &ev);
return -res;
}