summaryrefslogtreecommitdiff
path: root/libgo/misc/cgo
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2019-01-18 19:04:36 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2019-01-18 19:04:36 +0000
commit4f4a855d82a889cebcfca150a7a43909bcb6a346 (patch)
treef12bae0781920fa34669fe30b6f4615a86d9fb80 /libgo/misc/cgo
parent225220d668dafb8262db7012bced688acbe63b33 (diff)
libgo: update to Go1.12beta2
Reviewed-on: https://go-review.googlesource.com/c/158019 gotools/: * Makefile.am (go_cmd_vet_files): Update for Go1.12beta2 release. (GOTOOLS_TEST_TIMEOUT): Increase to 600. (check-runtime): Export LD_LIBRARY_PATH before computing GOARCH and GOOS. (check-vet): Copy golang.org/x/tools into check-vet-dir. * Makefile.in: Regenerate. gcc/testsuite/: * go.go-torture/execute/names-1.go: Stop using debug/xcoff, which is no longer externally visible. From-SVN: r268084
Diffstat (limited to 'libgo/misc/cgo')
-rw-r--r--libgo/misc/cgo/errors/errors_test.go9
-rw-r--r--libgo/misc/cgo/errors/ptr_test.go82
-rw-r--r--libgo/misc/cgo/errors/src/issue26745.go17
-rw-r--r--libgo/misc/cgo/errors/src/issue28069.go26
-rw-r--r--libgo/misc/cgo/errors/src/issue28721.go29
-rw-r--r--libgo/misc/cgo/test/callback.go6
-rw-r--r--libgo/misc/cgo/test/cgo_test.go2
-rw-r--r--libgo/misc/cgo/test/issue27054/egl.h7
-rw-r--r--libgo/misc/cgo/test/issue27054/test27054.go17
-rw-r--r--libgo/misc/cgo/test/issue27340.go12
-rw-r--r--libgo/misc/cgo/test/issue27340/a.go42
-rw-r--r--libgo/misc/cgo/test/issue28545.go26
-rw-r--r--libgo/misc/cgo/test/issue28772.go12
-rw-r--r--libgo/misc/cgo/test/issue28896.go83
-rw-r--r--libgo/misc/cgo/test/issue29383.go19
-rw-r--r--libgo/misc/cgo/test/issue4339.go3
-rw-r--r--libgo/misc/cgo/test/issue9026/issue9026.go2
-rw-r--r--libgo/misc/cgo/test/issue9400_linux.go2
-rw-r--r--libgo/misc/cgo/test/test27660.go61
-rw-r--r--libgo/misc/cgo/test/twoargs.go22
-rw-r--r--libgo/misc/cgo/testcshared/cshared_test.go52
-rw-r--r--libgo/misc/cgo/testcshared/src/go2c2go/go/shlib.go12
-rw-r--r--libgo/misc/cgo/testcshared/src/go2c2go/m1/c.c9
-rw-r--r--libgo/misc/cgo/testcshared/src/go2c2go/m1/main.go22
-rw-r--r--libgo/misc/cgo/testcshared/src/go2c2go/m2/main.go22
-rw-r--r--libgo/misc/cgo/testplugin/src/checkdwarf/main.go106
-rw-r--r--libgo/misc/cgo/testplugin/test.bash8
-rw-r--r--libgo/misc/cgo/testplugin/unnamed1/main.go2
-rw-r--r--libgo/misc/cgo/testsanitizers/cc_test.go2
-rw-r--r--libgo/misc/cgo/testshared/shared_test.go10
-rw-r--r--libgo/misc/cgo/testshared/src/issue25065/a.go20
31 files changed, 718 insertions, 26 deletions
diff --git a/libgo/misc/cgo/errors/errors_test.go b/libgo/misc/cgo/errors/errors_test.go
index 118187f23b8..59054f4703a 100644
--- a/libgo/misc/cgo/errors/errors_test.go
+++ b/libgo/misc/cgo/errors/errors_test.go
@@ -121,12 +121,19 @@ func TestReportsTypeErrors(t *testing.T) {
"issue16591.go",
"issue18452.go",
"issue18889.go",
+ "issue26745.go",
+ "issue28721.go",
} {
check(t, file)
}
if sizeofLongDouble(t) > 8 {
- check(t, "err4.go")
+ for _, file := range []string{
+ "err4.go",
+ "issue28069.go",
+ } {
+ check(t, file)
+ }
}
}
diff --git a/libgo/misc/cgo/errors/ptr_test.go b/libgo/misc/cgo/errors/ptr_test.go
index fe8dfff1d89..254671f179e 100644
--- a/libgo/misc/cgo/errors/ptr_test.go
+++ b/libgo/misc/cgo/errors/ptr_test.go
@@ -357,6 +357,73 @@ var ptrTests = []ptrTest{
body: `r, _, _ := os.Pipe(); r.SetDeadline(time.Now().Add(C.US * time.Microsecond))`,
fail: false,
},
+ {
+ // Test for double evaluation of channel receive.
+ name: "chan-recv",
+ c: `void f(char** p) {}`,
+ imports: []string{"time"},
+ body: `c := make(chan []*C.char, 2); c <- make([]*C.char, 1); go func() { time.Sleep(10 * time.Second); panic("received twice from chan") }(); C.f(&(<-c)[0]);`,
+ fail: false,
+ },
+ {
+ // Test that converting the address of a struct field
+ // to unsafe.Pointer still just checks that field.
+ // Issue #25941.
+ name: "struct-field",
+ c: `void f(void* p) {}`,
+ imports: []string{"unsafe"},
+ support: `type S struct { p *int; a [8]byte; u uintptr }`,
+ body: `s := &S{p: new(int)}; C.f(unsafe.Pointer(&s.a))`,
+ fail: false,
+ },
+ {
+ // Test that converting multiple struct field
+ // addresses to unsafe.Pointer still just checks those
+ // fields. Issue #25941.
+ name: "struct-field-2",
+ c: `void f(void* p, int r, void* s) {}`,
+ imports: []string{"unsafe"},
+ support: `type S struct { a [8]byte; p *int; b int64; }`,
+ body: `s := &S{p: new(int)}; C.f(unsafe.Pointer(&s.a), 32, unsafe.Pointer(&s.b))`,
+ fail: false,
+ },
+ {
+ // Test that second argument to cgoCheckPointer is
+ // evaluated when a deferred function is deferred, not
+ // when it is run.
+ name: "defer2",
+ c: `void f(char **pc) {}`,
+ support: `type S1 struct { s []*C.char }; type S2 struct { ps *S1 }`,
+ body: `p := &S2{&S1{[]*C.char{nil}}}; defer C.f(&p.ps.s[0]); p.ps = nil`,
+ fail: false,
+ },
+ {
+ // Test that indexing into a function call still
+ // examines only the slice being indexed.
+ name: "buffer",
+ c: `void f(void *p) {}`,
+ imports: []string{"bytes", "unsafe"},
+ body: `var b bytes.Buffer; b.WriteString("a"); C.f(unsafe.Pointer(&b.Bytes()[0]))`,
+ fail: false,
+ },
+ {
+ // Test that bgsweep releasing a finalizer is OK.
+ name: "finalizer",
+ c: `// Nothing to declare.`,
+ imports: []string{"os"},
+ support: `func open() { os.Open(os.Args[0]) }; var G [][]byte`,
+ body: `for i := 0; i < 10000; i++ { G = append(G, make([]byte, 4096)); if i % 100 == 0 { G = nil; open() } }`,
+ fail: false,
+ },
+ {
+ // Test that converting generated struct to interface is OK.
+ name: "structof",
+ c: `// Nothing to declare.`,
+ imports: []string{"reflect"},
+ support: `type MyInt int; func (i MyInt) Get() int { return int(i) }; type Getter interface { Get() int }`,
+ body: `t := reflect.StructOf([]reflect.StructField{{Name: "MyInt", Type: reflect.TypeOf(MyInt(0)), Anonymous: true}}); v := reflect.New(t).Elem(); v.Interface().(Getter).Get()`,
+ fail: false,
+ },
}
func TestPointerChecks(t *testing.T) {
@@ -429,7 +496,7 @@ func testOne(t *testing.T, pt ptrTest) {
cmd := exec.Command("go", "build")
cmd.Dir = src
- cmd.Env = addEnv("GOPATH", gopath)
+ cmd.Env = append(os.Environ(), "GOPATH="+gopath)
buf, err := cmd.CombinedOutput()
if err != nil {
t.Logf("%#q:\n%s", args(cmd), buf)
@@ -501,16 +568,5 @@ func testOne(t *testing.T, pt ptrTest) {
}
func cgocheckEnv(val string) []string {
- return addEnv("GODEBUG", "cgocheck="+val)
-}
-
-func addEnv(key, val string) []string {
- env := []string{key + "=" + val}
- look := key + "="
- for _, e := range os.Environ() {
- if !strings.HasPrefix(e, look) {
- env = append(env, e)
- }
- }
- return env
+ return append(os.Environ(), "GODEBUG=cgocheck="+val)
}
diff --git a/libgo/misc/cgo/errors/src/issue26745.go b/libgo/misc/cgo/errors/src/issue26745.go
new file mode 100644
index 00000000000..0e224538db6
--- /dev/null
+++ b/libgo/misc/cgo/errors/src/issue26745.go
@@ -0,0 +1,17 @@
+// Copyright 2018 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 main
+
+// int a;
+// void CF(int i) {}
+import "C"
+
+func F1(i int) int {
+ return C.a + 1 // ERROR HERE: :13
+}
+
+func F2(i int) {
+ C.CF(i) // ERROR HERE: :6
+}
diff --git a/libgo/misc/cgo/errors/src/issue28069.go b/libgo/misc/cgo/errors/src/issue28069.go
new file mode 100644
index 00000000000..e19a3b45bd5
--- /dev/null
+++ b/libgo/misc/cgo/errors/src/issue28069.go
@@ -0,0 +1,26 @@
+// Copyright 2018 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.
+
+// Test that the error message for an unrepresentable typedef in a
+// union appears on the right line. This test is only run if the size
+// of long double is larger than 64.
+
+package main
+
+/*
+typedef long double Float128;
+
+typedef struct SV {
+ union {
+ Float128 float128;
+ } value;
+} SV;
+*/
+import "C"
+
+type ts struct {
+ tv *C.SV // ERROR HERE
+}
+
+func main() {}
diff --git a/libgo/misc/cgo/errors/src/issue28721.go b/libgo/misc/cgo/errors/src/issue28721.go
new file mode 100644
index 00000000000..0eb2a9271c2
--- /dev/null
+++ b/libgo/misc/cgo/errors/src/issue28721.go
@@ -0,0 +1,29 @@
+// Copyright 2018 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.
+
+// cgo should reject the use of mangled C names.
+
+package main
+
+/*
+typedef struct a {
+ int i;
+} a;
+void fn(void) {}
+*/
+import "C"
+
+type B _Ctype_struct_a // ERROR HERE
+
+var a _Ctype_struct_a // ERROR HERE
+
+type A struct {
+ a *_Ctype_struct_a // ERROR HERE
+}
+
+var notExist _Ctype_NotExist // ERROR HERE
+
+func main() {
+ _Cfunc_fn() // ERROR HERE
+}
diff --git a/libgo/misc/cgo/test/callback.go b/libgo/misc/cgo/test/callback.go
index b88bf134bc1..4fc6b39ffa6 100644
--- a/libgo/misc/cgo/test/callback.go
+++ b/libgo/misc/cgo/test/callback.go
@@ -179,7 +179,6 @@ func testCallbackCallers(t *testing.T) {
pc := make([]uintptr, 100)
n := 0
name := []string{
- "runtime.call16",
"runtime.cgocallbackg1",
"runtime.cgocallbackg",
"runtime.cgocallback_gofunc",
@@ -193,9 +192,6 @@ func testCallbackCallers(t *testing.T) {
"testing.tRunner",
"runtime.goexit",
}
- if unsafe.Sizeof((*byte)(nil)) == 8 {
- name[0] = "runtime.call32"
- }
nestedCall(func() {
n = runtime.Callers(4, pc)
})
@@ -295,7 +291,7 @@ func goWithString(s string) {
}
func testCallbackStack(t *testing.T) {
- // Make cgo call and callback with different amount of stack stack available.
+ // Make cgo call and callback with different amount of stack available.
// We do not do any explicit checks, just ensure that it does not crash.
for _, f := range splitTests {
f()
diff --git a/libgo/misc/cgo/test/cgo_test.go b/libgo/misc/cgo/test/cgo_test.go
index ccacc50fe1a..242ba6c0e5d 100644
--- a/libgo/misc/cgo/test/cgo_test.go
+++ b/libgo/misc/cgo/test/cgo_test.go
@@ -92,6 +92,8 @@ func Test25143(t *testing.T) { test25143(t) }
func Test23356(t *testing.T) { test23356(t) }
func Test26066(t *testing.T) { test26066(t) }
func Test26213(t *testing.T) { test26213(t) }
+func Test27660(t *testing.T) { test27660(t) }
+func Test28896(t *testing.T) { test28896(t) }
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
func BenchmarkGoString(b *testing.B) { benchGoString(b) }
diff --git a/libgo/misc/cgo/test/issue27054/egl.h b/libgo/misc/cgo/test/issue27054/egl.h
new file mode 100644
index 00000000000..33a759ea2a8
--- /dev/null
+++ b/libgo/misc/cgo/test/issue27054/egl.h
@@ -0,0 +1,7 @@
+// Copyright 2018 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.
+
+// This is the relevant part of EGL/egl.h.
+
+typedef void *EGLDisplay;
diff --git a/libgo/misc/cgo/test/issue27054/test27054.go b/libgo/misc/cgo/test/issue27054/test27054.go
new file mode 100644
index 00000000000..186f5bd6020
--- /dev/null
+++ b/libgo/misc/cgo/test/issue27054/test27054.go
@@ -0,0 +1,17 @@
+// Copyright 2018 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 issue27054
+
+/*
+#include "egl.h"
+*/
+import "C"
+import (
+ "testing"
+)
+
+func Test27054(t *testing.T) {
+ var _ C.EGLDisplay = 0 // Note: 0, not nil. That makes sure we use uintptr for this type.
+}
diff --git a/libgo/misc/cgo/test/issue27340.go b/libgo/misc/cgo/test/issue27340.go
new file mode 100644
index 00000000000..f8c8a87f201
--- /dev/null
+++ b/libgo/misc/cgo/test/issue27340.go
@@ -0,0 +1,12 @@
+// Copyright 2018 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.
+
+// Failed to resolve typedefs consistently.
+// No runtime test; just make sure it compiles.
+
+package cgotest
+
+import "./issue27340"
+
+var issue27340Var = issue27340.Issue27340GoFunc
diff --git a/libgo/misc/cgo/test/issue27340/a.go b/libgo/misc/cgo/test/issue27340/a.go
new file mode 100644
index 00000000000..f5b120c1fd8
--- /dev/null
+++ b/libgo/misc/cgo/test/issue27340/a.go
@@ -0,0 +1,42 @@
+// Copyright 2018 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.
+
+// Failed to resolve typedefs consistently.
+// No runtime test; just make sure it compiles.
+// In separate directory to isolate #pragma GCC diagnostic.
+
+package issue27340
+
+// We use the #pragma to avoid a compiler warning about incompatible
+// pointer types, because we generate code passing a struct ptr rather
+// than using the typedef. This warning is expected and does not break
+// a normal build.
+// We can only disable -Wincompatible-pointer-types starting with GCC 5.
+
+// #if __GNU_MAJOR__ >= 5
+//
+// #pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
+//
+// typedef struct {
+// int a;
+// } issue27340Struct, *issue27340Ptr;
+//
+// static void issue27340CFunc(issue27340Ptr p) {}
+//
+// #else /* _GNU_MAJOR_ < 5 */
+//
+// typedef struct {
+// int a;
+// } issue27340Struct;
+//
+// static issue27340Struct* issue27340Ptr(issue27340Struct* p) { return p; }
+//
+// static void issue27340CFunc(issue27340Struct *p) {}
+// #endif /* _GNU_MAJOR_ < 5 */
+import "C"
+
+func Issue27340GoFunc() {
+ var s C.issue27340Struct
+ C.issue27340CFunc(C.issue27340Ptr(&s))
+}
diff --git a/libgo/misc/cgo/test/issue28545.go b/libgo/misc/cgo/test/issue28545.go
new file mode 100644
index 00000000000..8419b89c0af
--- /dev/null
+++ b/libgo/misc/cgo/test/issue28545.go
@@ -0,0 +1,26 @@
+// Copyright 2018 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.
+
+// Failed to add type conversion for negative constant.
+// Issue 28772: Failed to add type conversion for Go constant set to C constant.
+// No runtime test; just make sure it compiles.
+
+package cgotest
+
+/*
+#include <complex.h>
+
+#define issue28772Constant 1
+
+static void issue28545F(char **p, int n, complex double a) {}
+*/
+import "C"
+
+const issue28772Constant = C.issue28772Constant
+
+func issue28545G(p **C.char) {
+ C.issue28545F(p, -1, (0))
+ C.issue28545F(p, 2+3, complex(1, 1))
+ C.issue28545F(p, issue28772Constant, issue28772Constant2)
+}
diff --git a/libgo/misc/cgo/test/issue28772.go b/libgo/misc/cgo/test/issue28772.go
new file mode 100644
index 00000000000..bed786bf306
--- /dev/null
+++ b/libgo/misc/cgo/test/issue28772.go
@@ -0,0 +1,12 @@
+// Copyright 2018 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
+
+// Constants didn't work if defined in different source file.
+
+// #define issue28772Constant2 2
+import "C"
+
+const issue28772Constant2 = C.issue28772Constant2
diff --git a/libgo/misc/cgo/test/issue28896.go b/libgo/misc/cgo/test/issue28896.go
new file mode 100644
index 00000000000..8796040f18e
--- /dev/null
+++ b/libgo/misc/cgo/test/issue28896.go
@@ -0,0 +1,83 @@
+// Copyright 2018 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.
+
+// cgo was incorrectly adding padding after a packed struct.
+
+package cgotest
+
+/*
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+typedef struct {
+ void *f1;
+ uint32_t f2;
+} __attribute__((__packed__)) innerPacked;
+
+typedef struct {
+ innerPacked g1;
+ uint64_t g2;
+} outerPacked;
+
+typedef struct {
+ void *f1;
+ uint32_t f2;
+} innerUnpacked;
+
+typedef struct {
+ innerUnpacked g1;
+ uint64_t g2;
+} outerUnpacked;
+
+size_t offset(int x) {
+ switch (x) {
+ case 0:
+ return offsetof(innerPacked, f2);
+ case 1:
+ return offsetof(outerPacked, g2);
+ case 2:
+ return offsetof(innerUnpacked, f2);
+ case 3:
+ return offsetof(outerUnpacked, g2);
+ default:
+ abort();
+ }
+}
+*/
+import "C"
+
+import (
+ "testing"
+ "unsafe"
+)
+
+func offset(i int) uintptr {
+ var pi C.innerPacked
+ var po C.outerPacked
+ var ui C.innerUnpacked
+ var uo C.outerUnpacked
+ switch i {
+ case 0:
+ return unsafe.Offsetof(pi.f2)
+ case 1:
+ return unsafe.Offsetof(po.g2)
+ case 2:
+ return unsafe.Offsetof(ui.f2)
+ case 3:
+ return unsafe.Offsetof(uo.g2)
+ default:
+ panic("can't happen")
+ }
+}
+
+func test28896(t *testing.T) {
+ for i := 0; i < 4; i++ {
+ c := uintptr(C.offset(C.int(i)))
+ g := offset(i)
+ if c != g {
+ t.Errorf("%d: C: %d != Go %d", i, c, g)
+ }
+ }
+}
diff --git a/libgo/misc/cgo/test/issue29383.go b/libgo/misc/cgo/test/issue29383.go
new file mode 100644
index 00000000000..462c9a37df2
--- /dev/null
+++ b/libgo/misc/cgo/test/issue29383.go
@@ -0,0 +1,19 @@
+// Copyright 2018 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.
+
+// cgo's /*line*/ comments failed when inserted after '/',
+// because the result looked like a "//" comment.
+// No runtime test; just make sure it compiles.
+
+package cgotest
+
+// #include <stddef.h>
+import "C"
+
+func Issue29383(n, size uint) int {
+ if ^C.size_t(0)/C.size_t(n) < C.size_t(size) {
+ return 0
+ }
+ return 0
+}
diff --git a/libgo/misc/cgo/test/issue4339.go b/libgo/misc/cgo/test/issue4339.go
index 4fa4b2bbd7e..3715fde5757 100644
--- a/libgo/misc/cgo/test/issue4339.go
+++ b/libgo/misc/cgo/test/issue4339.go
@@ -5,7 +5,8 @@
package cgotest
/*
-#include "issue4339.h"
+// We've historically permitted #include <>, so test it here. Issue 29333.
+#include <issue4339.h>
*/
import "C"
diff --git a/libgo/misc/cgo/test/issue9026/issue9026.go b/libgo/misc/cgo/test/issue9026/issue9026.go
index 0af86e64da4..149c26562ad 100644
--- a/libgo/misc/cgo/test/issue9026/issue9026.go
+++ b/libgo/misc/cgo/test/issue9026/issue9026.go
@@ -29,7 +29,7 @@ func Test(t *testing.T) {
// Brittle: the assertion may fail spuriously when the algorithm
// changes, but should remain stable otherwise.
got := fmt.Sprintf("%T %T", in, opts)
- want := "issue9026._Ctype_struct___0 *issue9026._Ctype_struct___1"
+ want := "issue9026._Ctype_struct___0 *issue9026._Ctype_struct___0"
if got != want {
t.Errorf("Non-deterministic type names: got %s, want %s", got, want)
}
diff --git a/libgo/misc/cgo/test/issue9400_linux.go b/libgo/misc/cgo/test/issue9400_linux.go
index 34eb4983a41..7719535d251 100644
--- a/libgo/misc/cgo/test/issue9400_linux.go
+++ b/libgo/misc/cgo/test/issue9400_linux.go
@@ -41,7 +41,7 @@ func test9400(t *testing.T) {
// Grow the stack and put down a test pattern
const pattern = 0x123456789abcdef
- var big [1024]uint64 // len must match assmebly
+ var big [1024]uint64 // len must match assembly
for i := range big {
big[i] = pattern
}
diff --git a/libgo/misc/cgo/test/test27660.go b/libgo/misc/cgo/test/test27660.go
new file mode 100644
index 00000000000..0345aa7312b
--- /dev/null
+++ b/libgo/misc/cgo/test/test27660.go
@@ -0,0 +1,61 @@
+// Copyright 2018 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.
+
+// Stress the interaction between the race detector and cgo in an
+// attempt to reproduce the memory corruption described in #27660.
+// The bug was very timing sensitive; at the time of writing this
+// test would only trigger the bug about once out of every five runs.
+
+package cgotest
+
+// #include <unistd.h>
+import "C"
+
+import (
+ "context"
+ "math/rand"
+ "runtime"
+ "sync"
+ "testing"
+ "time"
+)
+
+func test27660(t *testing.T) {
+ ctx, cancel := context.WithCancel(context.Background())
+ defer cancel()
+ ints := make([]int, 100)
+ locks := make([]sync.Mutex, 100)
+ // Slowly create threads so that ThreadSanitizer is forced to
+ // frequently resize its SyncClocks.
+ for i := 0; i < 100; i++ {
+ go func() {
+ for ctx.Err() == nil {
+ // Sleep in C for long enough that it is likely that the runtime
+ // will retake this goroutine's currently wired P.
+ C.usleep(1000 /* 1ms */)
+ runtime.Gosched() // avoid starvation (see #28701)
+ }
+ }()
+ go func() {
+ // Trigger lots of synchronization and memory reads/writes to
+ // increase the likelihood that the race described in #27660
+ // results in corruption of ThreadSanitizer's internal state
+ // and thus an assertion failure or segfault.
+ i := 0
+ for ctx.Err() == nil {
+ j := rand.Intn(100)
+ locks[j].Lock()
+ ints[j]++
+ locks[j].Unlock()
+ // Avoid making the loop unpreemptible
+ // for gccgo.
+ if i%0x1000000 == 0 {
+ runtime.Gosched()
+ }
+ i++
+ }
+ }()
+ time.Sleep(time.Millisecond)
+ }
+}
diff --git a/libgo/misc/cgo/test/twoargs.go b/libgo/misc/cgo/test/twoargs.go
new file mode 100644
index 00000000000..ca0534ca310
--- /dev/null
+++ b/libgo/misc/cgo/test/twoargs.go
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+// Crash from call with two arguments that need pointer checking.
+// No runtime test; just make sure it compiles.
+
+package cgotest
+
+/*
+static void twoargs1(void *p, int n) {}
+static void *twoargs2() { return 0; }
+static int twoargs3(void * p) { return 0; }
+*/
+import "C"
+
+import "unsafe"
+
+func twoargsF() {
+ v := []string{}
+ C.twoargs1(C.twoargs2(), C.twoargs3(unsafe.Pointer(&v)))
+}
diff --git a/libgo/misc/cgo/testcshared/cshared_test.go b/libgo/misc/cgo/testcshared/cshared_test.go
index 89b19d653a3..e5b90ff194c 100644
--- a/libgo/misc/cgo/testcshared/cshared_test.go
+++ b/libgo/misc/cgo/testcshared/cshared_test.go
@@ -602,3 +602,55 @@ func copyFile(t *testing.T, dst, src string) {
t.Fatal(err)
}
}
+
+func TestGo2C2Go(t *testing.T) {
+ switch GOOS {
+ case "darwin":
+ // Darwin shared libraries don't support the multiple
+ // copies of the runtime package implied by this test.
+ t.Skip("linking c-shared into Go programs not supported on Darwin; issue 29061")
+ case "android":
+ t.Skip("test fails on android; issue 29087")
+ }
+
+ t.Parallel()
+
+ tmpdir, err := ioutil.TempDir("", "cshared-TestGo2C2Go")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(tmpdir)
+
+ shlib := filepath.Join(tmpdir, "libtestgo2c2go."+libSuffix)
+ run(t, gopathEnv, "go", "build", "-buildmode=c-shared", "-o", shlib, "go2c2go/go")
+
+ cgoCflags := os.Getenv("CGO_CFLAGS")
+ if cgoCflags != "" {
+ cgoCflags += " "
+ }
+ cgoCflags += "-I" + tmpdir
+
+ cgoLdflags := os.Getenv("CGO_LDFLAGS")
+ if cgoLdflags != "" {
+ cgoLdflags += " "
+ }
+ cgoLdflags += "-L" + tmpdir + " -ltestgo2c2go"
+
+ goenv := append(gopathEnv[:len(gopathEnv):len(gopathEnv)], "CGO_CFLAGS="+cgoCflags, "CGO_LDFLAGS="+cgoLdflags)
+
+ ldLibPath := os.Getenv("LD_LIBRARY_PATH")
+ if ldLibPath != "" {
+ ldLibPath += ":"
+ }
+ ldLibPath += tmpdir
+
+ runenv := append(gopathEnv[:len(gopathEnv):len(gopathEnv)], "LD_LIBRARY_PATH="+ldLibPath)
+
+ bin := filepath.Join(tmpdir, "m1") + exeSuffix
+ run(t, goenv, "go", "build", "-o", bin, "go2c2go/m1")
+ runExe(t, runenv, bin)
+
+ bin = filepath.Join(tmpdir, "m2") + exeSuffix
+ run(t, goenv, "go", "build", "-o", bin, "go2c2go/m2")
+ runExe(t, runenv, bin)
+}
diff --git a/libgo/misc/cgo/testcshared/src/go2c2go/go/shlib.go b/libgo/misc/cgo/testcshared/src/go2c2go/go/shlib.go
new file mode 100644
index 00000000000..76a5323ad2d
--- /dev/null
+++ b/libgo/misc/cgo/testcshared/src/go2c2go/go/shlib.go
@@ -0,0 +1,12 @@
+// Copyright 2018 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 main
+
+import "C"
+
+//export GoFunc
+func GoFunc() int { return 1 }
+
+func main() {}
diff --git a/libgo/misc/cgo/testcshared/src/go2c2go/m1/c.c b/libgo/misc/cgo/testcshared/src/go2c2go/m1/c.c
new file mode 100644
index 00000000000..0e8fac4cf36
--- /dev/null
+++ b/libgo/misc/cgo/testcshared/src/go2c2go/m1/c.c
@@ -0,0 +1,9 @@
+// Copyright 2018 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.
+
+#include "libtestgo2c2go.h"
+
+int CFunc(void) {
+ return (GoFunc() << 8) + 2;
+}
diff --git a/libgo/misc/cgo/testcshared/src/go2c2go/m1/main.go b/libgo/misc/cgo/testcshared/src/go2c2go/m1/main.go
new file mode 100644
index 00000000000..17ba1eb0a72
--- /dev/null
+++ b/libgo/misc/cgo/testcshared/src/go2c2go/m1/main.go
@@ -0,0 +1,22 @@
+// Copyright 2018 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 main
+
+// extern int CFunc(void);
+import "C"
+
+import (
+ "fmt"
+ "os"
+)
+
+func main() {
+ got := C.CFunc()
+ const want = (1 << 8) | 2
+ if got != want {
+ fmt.Printf("got %#x, want %#x\n", got, want)
+ os.Exit(1)
+ }
+}
diff --git a/libgo/misc/cgo/testcshared/src/go2c2go/m2/main.go b/libgo/misc/cgo/testcshared/src/go2c2go/m2/main.go
new file mode 100644
index 00000000000..91bf308057c
--- /dev/null
+++ b/libgo/misc/cgo/testcshared/src/go2c2go/m2/main.go
@@ -0,0 +1,22 @@
+// Copyright 2018 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 main
+
+// #include "libtestgo2c2go.h"
+import "C"
+
+import (
+ "fmt"
+ "os"
+)
+
+func main() {
+ got := C.GoFunc()
+ const want = 1
+ if got != want {
+ fmt.Printf("got %#x, want %#x\n", got, want)
+ os.Exit(1)
+ }
+}
diff --git a/libgo/misc/cgo/testplugin/src/checkdwarf/main.go b/libgo/misc/cgo/testplugin/src/checkdwarf/main.go
new file mode 100644
index 00000000000..7886c834e7c
--- /dev/null
+++ b/libgo/misc/cgo/testplugin/src/checkdwarf/main.go
@@ -0,0 +1,106 @@
+// Copyright 2018 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.
+
+// Usage:
+//
+// checkdwarf <exe> <suffix>
+//
+// Opens <exe>, which must be an executable or a library and checks that
+// there is an entry in .debug_info whose name ends in <suffix>
+
+package main
+
+import (
+ "debug/dwarf"
+ "debug/elf"
+ "debug/macho"
+ "debug/pe"
+ "fmt"
+ "os"
+ "strings"
+)
+
+func usage() {
+ fmt.Fprintf(os.Stderr, "checkdwarf executable-or-library DIE-suffix\n")
+}
+
+type dwarfer interface {
+ DWARF() (*dwarf.Data, error)
+}
+
+func openElf(path string) dwarfer {
+ exe, err := elf.Open(path)
+ if err != nil {
+ return nil
+ }
+ return exe
+}
+
+func openMacho(path string) dwarfer {
+ exe, err := macho.Open(path)
+ if err != nil {
+ return nil
+ }
+ return exe
+}
+
+func openPE(path string) dwarfer {
+ exe, err := pe.Open(path)
+ if err != nil {
+ return nil
+ }
+ return exe
+}
+
+func main() {
+ if len(os.Args) != 3 {
+ usage()
+ }
+
+ exePath := os.Args[1]
+ dieSuffix := os.Args[2]
+
+ var exe dwarfer
+
+ for _, openfn := range []func(string) dwarfer{openMacho, openPE, openElf} {
+ exe = openfn(exePath)
+ if exe != nil {
+ break
+ }
+ }
+
+ if exe == nil {
+ fmt.Fprintf(os.Stderr, "could not open %s\n", exePath)
+ os.Exit(1)
+ }
+
+ data, err := exe.DWARF()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "%s: error opening DWARF: %v\n", exePath, err)
+ os.Exit(1)
+ }
+
+ rdr := data.Reader()
+ for {
+ e, err := rdr.Next()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "%s: error reading DWARF: %v\n", exePath, err)
+ os.Exit(1)
+ }
+ if e == nil {
+ break
+ }
+ name, hasname := e.Val(dwarf.AttrName).(string)
+ if !hasname {
+ continue
+ }
+ if strings.HasSuffix(name, dieSuffix) {
+ // found
+ os.Exit(0)
+ }
+ }
+
+ fmt.Fprintf(os.Stderr, "%s: no entry with a name ending in %q was found\n", exePath, dieSuffix)
+ os.Exit(1)
+}
diff --git a/libgo/misc/cgo/testplugin/test.bash b/libgo/misc/cgo/testplugin/test.bash
index bf8ed3cd191..1b94bc4badb 100644
--- a/libgo/misc/cgo/testplugin/test.bash
+++ b/libgo/misc/cgo/testplugin/test.bash
@@ -32,6 +32,14 @@ GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o=unnamed1.so u
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" -buildmode=plugin -o=unnamed2.so unnamed2/main.go
GOPATH=$(pwd) go build -gcflags "$GO_GCFLAGS" host
+# test that DWARF sections are emitted for plugins and programs importing "plugin"
+if [ $GOOS != "darwin" ]; then
+ # On macOS, for some reason, the linker doesn't add debug sections to .so,
+ # see issue #27502.
+ go run src/checkdwarf/main.go plugin2.so plugin2.UnexportedNameReuse
+fi
+go run src/checkdwarf/main.go host main.main
+
LD_LIBRARY_PATH=$(pwd) ./host
# Test that types and itabs get properly uniqified.
diff --git a/libgo/misc/cgo/testplugin/unnamed1/main.go b/libgo/misc/cgo/testplugin/unnamed1/main.go
index 5c1df086d76..caf09c9e890 100644
--- a/libgo/misc/cgo/testplugin/unnamed1/main.go
+++ b/libgo/misc/cgo/testplugin/unnamed1/main.go
@@ -9,7 +9,7 @@ import "C"
func FuncInt() int { return 1 }
-// Add a recursive type to to check that type equality across plugins doesn't
+// Add a recursive type to check that type equality across plugins doesn't
// crash. See https://golang.org/issues/19258
func FuncRecursive() X { return X{} }
diff --git a/libgo/misc/cgo/testsanitizers/cc_test.go b/libgo/misc/cgo/testsanitizers/cc_test.go
index f09ad52ceee..218e2254295 100644
--- a/libgo/misc/cgo/testsanitizers/cc_test.go
+++ b/libgo/misc/cgo/testsanitizers/cc_test.go
@@ -374,7 +374,7 @@ func (c *config) checkRuntime() (skip bool, err error) {
}
// libcgo.h sets CGO_TSAN if it detects TSAN support in the C compiler.
- // Dump the preprocessor defines to check that that works.
+ // Dump the preprocessor defines to check that works.
// (Sometimes it doesn't: see https://golang.org/issue/15983.)
cmd, err := cc(c.cFlags...)
if err != nil {
diff --git a/libgo/misc/cgo/testshared/shared_test.go b/libgo/misc/cgo/testshared/shared_test.go
index 846a27173e3..41a24efe22c 100644
--- a/libgo/misc/cgo/testshared/shared_test.go
+++ b/libgo/misc/cgo/testshared/shared_test.go
@@ -560,7 +560,7 @@ func TestNotes(t *testing.T) {
abiHashNoteFound = true
case 3: // ELF_NOTE_GODEPS_TAG
if depsNoteFound {
- t.Error("multiple depedency list notes")
+ t.Error("multiple dependency list notes")
}
testDepsNote(t, f, note)
depsNoteFound = true
@@ -578,7 +578,7 @@ func TestNotes(t *testing.T) {
}
// Build a GOPATH package (depBase) into a shared library that links against the goroot
-// runtime, another package (dep2) that links against the first, and and an
+// runtime, another package (dep2) that links against the first, and an
// executable that links against dep2.
func TestTwoGopathShlibs(t *testing.T) {
goCmd(t, "install", "-buildmode=shared", "-linkshared", "depBase")
@@ -911,3 +911,9 @@ func TestGlobal(t *testing.T) {
func TestTestInstalledShared(t *testing.T) {
goCmd(nil, "test", "-linkshared", "-test.short", "sync/atomic")
}
+
+// Test generated pointer method with -linkshared.
+// Issue 25065.
+func TestGeneratedMethod(t *testing.T) {
+ goCmd(t, "install", "-buildmode=shared", "-linkshared", "issue25065")
+}
diff --git a/libgo/misc/cgo/testshared/src/issue25065/a.go b/libgo/misc/cgo/testshared/src/issue25065/a.go
new file mode 100644
index 00000000000..979350ff24c
--- /dev/null
+++ b/libgo/misc/cgo/testshared/src/issue25065/a.go
@@ -0,0 +1,20 @@
+// Copyright 2018 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 issue25065 has a type with a method that is
+// 1) referenced in a method expression
+// 2) not called
+// 3) not converted to an interface
+// 4) is a value method but the reference is to the pointer method
+// These cases avoid the call to makefuncsym from typecheckfunc, but we
+// still need to call makefuncsym somehow or the symbol will not be defined.
+package issue25065
+
+type T int
+
+func (t T) M() {}
+
+func F() func(*T) {
+ return (*T).M
+}