]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cc: generate error if #pragma pack off does anything
authorRuss Cox <rsc@golang.org>
Sat, 30 Aug 2014 18:54:09 +0000 (14:54 -0400)
committerRuss Cox <rsc@golang.org>
Sat, 30 Aug 2014 18:54:09 +0000 (14:54 -0400)
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

src/cmd/5c/swt.c
src/cmd/6c/swt.c
src/cmd/8c/swt.c
src/pkg/runtime/defs_linux_amd64.h
src/pkg/runtime/netpoll_epoll.c

index d24a5df9b09130afec1ce688f6f66e598874dc06..f39963b8f27d3790b82d0d119d3b08017ec25e2a 100644 (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;
index d7713648debcc658075f120d782421dcaac3b061..6e918eb109fd8b13a423e6951334011822bab7eb 100644 (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;
index ae36f84eaca12be8b2eeb01be60bef04854569af..d960519e3b5831f76b5c18858acc6709a920698a 100644 (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;
index 73fd9947a72346bd929ca20bafaf99a2c506e823..14616dffed017048e832fcf5020612fafdb83cf6 100644 (file)
@@ -122,7 +122,7 @@ struct Itimerval {
 };
 struct EpollEvent {
        uint32  events;
-       uint64  data;
+       byte    data[8]; // unaligned uintptr
 };
 
 
index a0ae7df310e43bfdc2de3bc1aa393ef7c9ad0eb9..2cf9b3760db5060be3b7d799d5cceef0660e88f2 100644 (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;
 }