]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/cgo: use gcc_struct attribute for packed structs to work around GCC PR52991.
authorShenghou Ma <minux.ma@gmail.com>
Sun, 9 Jun 2013 14:06:29 +0000 (22:06 +0800)
committerShenghou Ma <minux.ma@gmail.com>
Sun, 9 Jun 2013 14:06:29 +0000 (22:06 +0800)
Fixes #5603.

R=iant, dave
CC=gobot, golang-dev
https://golang.org/cl/9895043

misc/cgo/test/cgo_test.go
misc/cgo/test/issue5603.go [new file with mode: 0644]
src/cmd/cgo/doc.go
src/cmd/cgo/out.go

index 66c454f8e37f3c4a3fdb400063c5b14484c59dd6..f0b31c589d15473a9cf8d0f9328b5dbf47ab37f5 100644 (file)
@@ -41,5 +41,6 @@ func Test5227(t *testing.T)                { test5227(t) }
 func TestCflags(t *testing.T)              { testCflags(t) }
 func Test5337(t *testing.T)                { test5337(t) }
 func Test5548(t *testing.T)                { test5548(t) }
+func Test5603(t *testing.T)                { test5603(t) }
 
 func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
diff --git a/misc/cgo/test/issue5603.go b/misc/cgo/test/issue5603.go
new file mode 100644 (file)
index 0000000..ecb2aa3
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright 2013 The Go Authors.  All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cgotest
+
+/*
+const long long issue5603exp = 0x12345678;
+long long issue5603foo0() { return issue5603exp; }
+long long issue5603foo1(void *p) { return issue5603exp; }
+long long issue5603foo2(void *p, void *q) { return issue5603exp; }
+long long issue5603foo3(void *p, void *q, void *r) { return issue5603exp; }
+long long issue5603foo4(void *p, void *q, void *r, void *s) { return issue5603exp; }
+*/
+import "C"
+
+import "testing"
+
+func test5603(t *testing.T) {
+       var x [5]int64
+       exp := int64(C.issue5603exp)
+       x[0] = int64(C.issue5603foo0())
+       x[1] = int64(C.issue5603foo1(nil))
+       x[2] = int64(C.issue5603foo2(nil, nil))
+       x[3] = int64(C.issue5603foo3(nil, nil, nil))
+       x[4] = int64(C.issue5603foo4(nil, nil, nil, nil))
+       for i, v := range x {
+               if v != exp {
+                       t.Errorf("issue5603foo%d() returns %v, expected %v", i, v, exp)
+               }
+       }
+}
index d9b50cf5c25ce7d0c26a78e76b58894e07632712..701ac6f8d919a00c07b6d3f81cc8856803da3899 100644 (file)
@@ -310,7 +310,7 @@ file compiled by gcc, the file x.cgo2.c:
                        char* p0;
                        int r;
                        char __pad12[4];
-               } __attribute__((__packed__)) *a = v;
+               } __attribute__((__packed__, __gcc_struct__)) *a = v;
                a->r = puts((void*)a->p0);
        }
 
index 29f7020930c0a43c823cf9603b39025d69c28b5a..eee71864cf8254bf7c42095a6b7a2c82442ac779 100644 (file)
@@ -485,7 +485,13 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
        // Use packed attribute to force no padding in this struct in case
        // gcc has different packing requirements.  For example,
        // on 386 Windows, gcc wants to 8-align int64s, but 8c does not.
-       fmt.Fprintf(fgcc, "\t%s __attribute__((__packed__)) *a = v;\n", ctype)
+       // Use __gcc_struct__ to work around http://gcc.gnu.org/PR52991 on x86,
+       // and http://golang.org/issue/5603.
+       extraAttr := ""
+       if goarch == "amd64" || goarch == "386" {
+               extraAttr = ", __gcc_struct__"
+       }
+       fmt.Fprintf(fgcc, "\t%s __attribute__((__packed__%v)) *a = v;\n", ctype, extraAttr)
        fmt.Fprintf(fgcc, "\t")
        if t := n.FuncType.Result; t != nil {
                fmt.Fprintf(fgcc, "a->r = ")