diff options
author | Russ Cox <rsc@golang.org> | 2014-08-30 14:54:09 -0400 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2014-08-30 14:54:09 -0400 |
commit | ccedd2e0701037721ce25aee82c316aa3a0ca024 (patch) | |
tree | 9865ff3c7217c983a04913d24ddb35a85f3da670 | |
parent | 0b422687591afd295d84e751206c3c6e5d1422af (diff) | |
download | go-ccedd2e0701037721ce25aee82c316aa3a0ca024.tar.gz |
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://codereview.appspot.com/137020043
-rw-r--r-- | src/cmd/5c/swt.c | 9 | ||||
-rw-r--r-- | src/cmd/6c/swt.c | 9 | ||||
-rw-r--r-- | src/cmd/8c/swt.c | 9 | ||||
-rw-r--r-- | src/pkg/runtime/defs_linux_amd64.h | 2 | ||||
-rw-r--r-- | src/pkg/runtime/netpoll_epoll.c | 2 |
5 files changed, 20 insertions, 11 deletions
diff --git a/src/cmd/5c/swt.c b/src/cmd/5c/swt.c index d24a5df9b..f39963b8f 100644 --- a/src/cmd/5c/swt.c +++ b/src/cmd/5c/swt.c @@ -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; diff --git a/src/cmd/6c/swt.c b/src/cmd/6c/swt.c index d7713648d..6e918eb10 100644 --- a/src/cmd/6c/swt.c +++ b/src/cmd/6c/swt.c @@ -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; diff --git a/src/cmd/8c/swt.c b/src/cmd/8c/swt.c index ae36f84ea..d960519e3 100644 --- a/src/cmd/8c/swt.c +++ b/src/cmd/8c/swt.c @@ -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; diff --git a/src/pkg/runtime/defs_linux_amd64.h b/src/pkg/runtime/defs_linux_amd64.h index 73fd9947a..14616dffe 100644 --- a/src/pkg/runtime/defs_linux_amd64.h +++ b/src/pkg/runtime/defs_linux_amd64.h @@ -122,7 +122,7 @@ struct Itimerval { }; struct EpollEvent { uint32 events; - uint64 data; + byte data[8]; // unaligned uintptr }; diff --git a/src/pkg/runtime/netpoll_epoll.c b/src/pkg/runtime/netpoll_epoll.c index a0ae7df31..2cf9b3760 100644 --- a/src/pkg/runtime/netpoll_epoll.c +++ b/src/pkg/runtime/netpoll_epoll.c @@ -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; } |