From 84c0e5d47f46f2e1a7ce92341477d9801f0ef777 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 1 Jun 2021 14:58:36 -0700 Subject: [PATCH] cmd/link: move issue 43830 tests out of TestScript These tests pass or fail depending on the exact compiler version, which the TestScript tests don't support. Rewrite into Go. For #43830 For #46295 Change-Id: I91b61dfe329d518e461ee56f186f0e9b42858e77 Reviewed-on: https://go-review.googlesource.com/c/go/+/324049 Trust: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot Reviewed-by: Cherry Mui --- .../testdata/script/cgo_lto2_issue43830.txt | 33 ----- .../go/testdata/script/cgo_lto_issue43830.txt | 40 ----- src/cmd/link/cgo_test.go | 138 ++++++++++++++++++ 3 files changed, 138 insertions(+), 73 deletions(-) delete mode 100644 src/cmd/go/testdata/script/cgo_lto2_issue43830.txt delete mode 100644 src/cmd/go/testdata/script/cgo_lto_issue43830.txt create mode 100644 src/cmd/link/cgo_test.go diff --git a/src/cmd/go/testdata/script/cgo_lto2_issue43830.txt b/src/cmd/go/testdata/script/cgo_lto2_issue43830.txt deleted file mode 100644 index e2483ba784d..00000000000 --- a/src/cmd/go/testdata/script/cgo_lto2_issue43830.txt +++ /dev/null @@ -1,33 +0,0 @@ -# tests golang.org/issue/43830 - -[!cgo] skip 'skipping test without cgo' -[openbsd] env CC='clang' -[openbsd] [!exec:clang] skip 'skipping test without clang present' -[!openbsd] env CC='gcc' -[!openbsd] [!exec:gcc] skip 'skipping test without gcc present' - -env CGO_CFLAGS='-Wno-ignored-optimization-argument -flto -ffat-lto-objects' - -go build main.go - --- main.go -- - -package main - -import "fmt" - -// #include "hello.h" -import "C" - -func main() { - hello := C.hello - fmt.Printf("%v\n", hello) -} - --- hello.h -- - -#include - -void hello(void) { - printf("hello\n"); -} diff --git a/src/cmd/go/testdata/script/cgo_lto_issue43830.txt b/src/cmd/go/testdata/script/cgo_lto_issue43830.txt deleted file mode 100644 index 8bc7d8a540f..00000000000 --- a/src/cmd/go/testdata/script/cgo_lto_issue43830.txt +++ /dev/null @@ -1,40 +0,0 @@ -# tests golang.org/issue/43830 - -[!cgo] skip 'skipping test without cgo' -[openbsd] env CC='clang' -[openbsd] [!exec:clang] skip 'skipping test without clang present' -[!openbsd] env CC='gcc' -[!openbsd] [!exec:gcc] skip 'skipping test without gcc present' - -env CGO_CFLAGS='-Wno-ignored-optimization-argument -flto -ffat-lto-objects' - -go build main.go add.go - --- main.go -- - -package main - -/* -extern int myadd(int, int); -int c_add(int a, int b) { - return myadd(a, b); -} -*/ -import "C" - -func main() { - println(C.c_add(1, 2)) -} - --- add.go -- - -package main - -import "C" - -/* test */ - -//export myadd -func myadd(a C.int, b C.int) C.int { - return a + b -} diff --git a/src/cmd/link/cgo_test.go b/src/cmd/link/cgo_test.go new file mode 100644 index 00000000000..09390daeb7e --- /dev/null +++ b/src/cmd/link/cgo_test.go @@ -0,0 +1,138 @@ +// Copyright 2021 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 ( + "bytes" + "fmt" + "internal/testenv" + "os" + "os/exec" + "path/filepath" + "testing" +) + +// Issues 43830, 46295 +func TestCGOLTO(t *testing.T) { + testenv.MustHaveCGO(t) + testenv.MustHaveGoBuild(t) + + t.Parallel() + + for _, cc := range []string{"gcc", "clang"} { + for test := 0; test < 2; test++ { + t.Run(fmt.Sprintf("%s-%d", cc, test), func(t *testing.T) { + testCGOLTO(t, cc, test) + }) + } + } +} + +const test1_main = ` +package main + +/* +extern int myadd(int, int); +int c_add(int a, int b) { + return myadd(a, b); +} +*/ +import "C" + +func main() { + println(C.c_add(1, 2)) +} +` + +const test1_add = ` +package main + +import "C" + +/* test */ + +//export myadd +func myadd(a C.int, b C.int) C.int { + return a + b +} +` + +const test2_main = ` +package main + +import "fmt" + +/* +#include + +void hello(void) { + printf("hello\n"); +} +*/ +import "C" + +func main() { + hello := C.hello + fmt.Printf("%v\n", hello) +} +` + +func testCGOLTO(t *testing.T, cc string, test int) { + t.Parallel() + + if _, err := exec.LookPath(cc); err != nil { + t.Skipf("no %s compiler", cc) + } + + dir := t.TempDir() + + writeTempFile := func(name, contents string) { + if err := os.WriteFile(filepath.Join(dir, name), []byte(contents), 0644); err != nil { + t.Fatal(err) + } + } + + writeTempFile("go.mod", "module cgolto\n") + + switch test { + case 0: + writeTempFile("main.go", test1_main) + writeTempFile("add.go", test1_add) + case 1: + writeTempFile("main.go", test2_main) + default: + t.Fatalf("bad case %d", test) + } + + cmd := exec.Command(testenv.GoToolPath(t), "build") + cmd.Dir = dir + cmd.Env = append(os.Environ(), + "CC="+cc, + "CGO_CFLAGS=-flto", + ) + + t.Log("go build") + out, err := cmd.CombinedOutput() + t.Logf("%s", out) + + if err != nil { + t.Logf("go build failed: %v", err) + + // Error messages we've seen indicating that LTO is not supported. + var noLTO = []string{ + `unrecognized command line option "-flto"`, + "unable to pass LLVM bit-code files to linker", + "file not recognized: File format not recognized", + "LTO support has not been enabled", + } + for _, msg := range noLTO { + if bytes.Contains(out, []byte(msg)) { + t.Skipf("C compiler %v does not support LTO", cc) + } + } + + t.Error("failed") + } +}