diff options
author | Ian Lance Taylor <iant@golang.org> | 2019-01-18 19:04:36 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-01-18 19:04:36 +0000 |
commit | 4f4a855d82a889cebcfca150a7a43909bcb6a346 (patch) | |
tree | f12bae0781920fa34669fe30b6f4615a86d9fb80 /libgo/misc | |
parent | 225220d668dafb8262db7012bced688acbe63b33 (diff) | |
download | gcc-4f4a855d82a889cebcfca150a7a43909bcb6a346.tar.gz |
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')
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 +} |