From 24e9707cbfa6b1ed6abdd4b11f9ddaf3aac5ad88 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 25 May 2021 16:31:41 -0700 Subject: cmd/link, cmd/cgo: support -flto in CFLAGS The linker now accepts unrecognized object files in external linking mode. These objects will simply be passed to the external linker. This permits using -flto which can generate pure byte code objects, whose symbol table the linker does not know how to read. The cgo tool now passes -fno-lto when generating objects whose symbols it needs to read. The cgo tool now emits matching types in different objects, so that the lto linker does not report a mismatch. This is based on https://golang.org/cl/293290 by Derek Parker. For #43505 Fixes #43830 Fixes #46295 Change-Id: I6787de213417466784ddef5af8899e453b4ae1ad Reviewed-on: https://go-review.googlesource.com/c/go/+/322614 Trust: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot Reviewed-by: Michael Hudson-Doyle --- src/cmd/cgo/gcc.go | 2 ++ src/cmd/cgo/out.go | 16 +++++++-- src/cmd/dist/test.go | 29 ++++++++++++---- src/cmd/go/testdata/script/cgo_lto2_issue43830.txt | 33 ++++++++++++++++++ src/cmd/go/testdata/script/cgo_lto_issue43830.txt | 39 ++++++++++++++++++++++ src/cmd/link/internal/ld/ar.go | 4 +++ src/cmd/link/internal/ld/config.go | 6 +++- src/cmd/link/internal/ld/lib.go | 26 ++++++++++++--- 8 files changed, 140 insertions(+), 15 deletions(-) create mode 100644 src/cmd/go/testdata/script/cgo_lto2_issue43830.txt create mode 100644 src/cmd/go/testdata/script/cgo_lto_issue43830.txt (limited to 'src/cmd') diff --git a/src/cmd/cgo/gcc.go b/src/cmd/cgo/gcc.go index ae61725bc7..a73e998877 100644 --- a/src/cmd/cgo/gcc.go +++ b/src/cmd/cgo/gcc.go @@ -1638,6 +1638,8 @@ func (p *Package) gccCmd() []string { c = append(c, "-maix64") c = append(c, "-mcmodel=large") } + // disable LTO so we get an object whose symbols we can read + c = append(c, "-fno-lto") c = append(c, "-") //read input from standard input return c } diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go index 8c31d5b794..94152f4278 100644 --- a/src/cmd/cgo/out.go +++ b/src/cmd/cgo/out.go @@ -168,8 +168,18 @@ func (p *Package) writeDefs() { if *gccgo { fmt.Fprintf(fc, "extern byte *%s;\n", n.C) } else { - fmt.Fprintf(fm, "extern char %s[];\n", n.C) - fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C) + // Force a reference to all symbols so that + // the external linker will add DT_NEEDED + // entries as needed on ELF systems. + // Treat function variables differently + // to avoid type confict errors from LTO + // (Link Time Optimization). + if n.Kind == "fpvar" { + fmt.Fprintf(fm, "extern void %s();\n", n.C) + } else { + fmt.Fprintf(fm, "extern char %s[];\n", n.C) + fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C) + } fmt.Fprintf(fgo2, "//go:linkname __cgo_%s %s\n", n.C, n.C) fmt.Fprintf(fgo2, "//go:cgo_import_static %s\n", n.C) fmt.Fprintf(fgo2, "var __cgo_%s byte\n", n.C) @@ -1042,7 +1052,7 @@ func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) { // This unpacks the argument struct above and calls the Go function. fmt.Fprintf(fgo2, "func _cgoexp%s_%s(a *%s) {\n", cPrefix, exp.ExpName, gotype) - fmt.Fprintf(fm, "int _cgoexp%s_%s;\n", cPrefix, exp.ExpName) + fmt.Fprintf(fm, "void _cgoexp%s_%s(void* p){}\n", cPrefix, exp.ExpName) if gccResult != "void" { // Write results back to frame. diff --git a/src/cmd/dist/test.go b/src/cmd/dist/test.go index 50bf80ba59..bc49c6d804 100644 --- a/src/cmd/dist/test.go +++ b/src/cmd/dist/test.go @@ -722,14 +722,29 @@ func (t *tester) registerTests() { }, }) if t.hasCxx() { - t.tests = append(t.tests, distTest{ - name: "swig_callback", - heading: "../misc/swig/callback", - fn: func(dt *distTest) error { - t.addCmd(dt, "misc/swig/callback", t.goTest()) - return nil + t.tests = append(t.tests, + distTest{ + name: "swig_callback", + heading: "../misc/swig/callback", + fn: func(dt *distTest) error { + t.addCmd(dt, "misc/swig/callback", t.goTest()) + return nil + }, + }, + distTest{ + name: "swig_callback_lto", + heading: "../misc/swig/callback", + fn: func(dt *distTest) error { + cmd := t.addCmd(dt, "misc/swig/callback", t.goTest()) + cmd.Env = append(os.Environ(), + "CGO_CFLAGS=-flto", + "CGO_CXXFLAGS=-flto", + "CGO_LDFLAGS=-flto", + ) + return nil + }, }, - }) + ) } } } diff --git a/src/cmd/go/testdata/script/cgo_lto2_issue43830.txt b/src/cmd/go/testdata/script/cgo_lto2_issue43830.txt new file mode 100644 index 0000000000..e2483ba784 --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_lto2_issue43830.txt @@ -0,0 +1,33 @@ +# 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 new file mode 100644 index 0000000000..06ab2f34c9 --- /dev/null +++ b/src/cmd/go/testdata/script/cgo_lto_issue43830.txt @@ -0,0 +1,39 @@ +# 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 + +/* +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/internal/ld/ar.go b/src/cmd/link/internal/ld/ar.go index 22f53a4df2..23915f9032 100644 --- a/src/cmd/link/internal/ld/ar.go +++ b/src/cmd/link/internal/ld/ar.go @@ -124,6 +124,10 @@ func hostArchive(ctxt *Link, name string) { libgcc := sym.Library{Pkg: "libgcc"} h := ldobj(ctxt, f, &libgcc, l, pname, name) + if h.ld == nil { + Errorf(nil, "%s unrecognized object file at offset %d", name, off) + continue + } f.MustSeek(h.off, 0) h.ld(ctxt, f, h.pkg, h.length, h.pn) } diff --git a/src/cmd/link/internal/ld/config.go b/src/cmd/link/internal/ld/config.go index ae0d7520eb..20f1d0b8c1 100644 --- a/src/cmd/link/internal/ld/config.go +++ b/src/cmd/link/internal/ld/config.go @@ -241,6 +241,10 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) { return true, "dynamically linking with a shared library" } + if unknownObjFormat { + return true, "some input objects have an unrecognized file format" + } + return false, "" } @@ -248,7 +252,7 @@ func mustLinkExternal(ctxt *Link) (res bool, reason string) { // // It is called after flags are processed and inputs are processed, // so the ctxt.LinkMode variable has an initial value from the -linkmode -// flag and the iscgo externalobj variables are set. +// flag and the iscgo, externalobj, and unknownObjFormat variables are set. func determineLinkMode(ctxt *Link) { extNeeded, extReason := mustLinkExternal(ctxt) via := "" diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index e8f001ba8e..644faeb2fb 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -343,10 +343,16 @@ var ( const pkgdef = "__.PKGDEF" var ( - // Set if we see an object compiled by the host compiler that is not - // from a package that is known to support internal linking mode. + // externalobj is set to true if we see an object compiled by + // the host compiler that is not from a package that is known + // to support internal linking mode. externalobj = false - theline string + + // unknownObjFormat is set to true if we see an object whose + // format we don't recognize. + unknownObjFormat = false + + theline string ) func Lflag(ctxt *Link, arg string) { @@ -1065,6 +1071,10 @@ func hostobjs(ctxt *Link) { } f.MustSeek(h.off, 0) + if h.ld == nil { + Errorf(nil, "%s: unrecognized object file format", h.pn) + continue + } h.ld(ctxt, f, h.pkg, h.length, h.pn) f.Close() } @@ -1855,6 +1865,14 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, return ldhostobj(ldxcoff, ctxt.HeadType, f, pkg, length, pn, file) } + if c1 != 'g' || c2 != 'o' || c3 != ' ' || c4 != 'o' { + // An unrecognized object is just passed to the external linker. + // If we try to read symbols from this object, we will + // report an error at that time. + unknownObjFormat = true + return ldhostobj(nil, ctxt.HeadType, f, pkg, length, pn, file) + } + /* check the header */ line, err := f.ReadString('\n') if err != nil { @@ -1874,7 +1892,7 @@ func ldobj(ctxt *Link, f *bio.Reader, lib *sym.Library, length int64, pn string, return nil } - Errorf(nil, "%s: not an object file: @%d %02x%02x%02x%02x", pn, start, c1, c2, c3, c4) + Errorf(nil, "%s: not an object file: @%d %q", pn, start, line) return nil } -- cgit v1.3-5-g9baa From 567ee865f690cde59d5aeadc04bcc926d2316db8 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 1 Jun 2021 13:47:42 -0700 Subject: cmd/go: add declaration to cgo_lto_issue43830 test This permits the test to work in C99 mode. For #43830 Change-Id: Ide54bd62239cfe602e2664300f04e472df5daf43 Reviewed-on: https://go-review.googlesource.com/c/go/+/324009 Trust: Ian Lance Taylor Run-TryBot: Ian Lance Taylor Reviewed-by: Cherry Mui TryBot-Result: Go Bot --- src/cmd/go/testdata/script/cgo_lto_issue43830.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'src/cmd') diff --git a/src/cmd/go/testdata/script/cgo_lto_issue43830.txt b/src/cmd/go/testdata/script/cgo_lto_issue43830.txt index 06ab2f34c9..8bc7d8a540 100644 --- a/src/cmd/go/testdata/script/cgo_lto_issue43830.txt +++ b/src/cmd/go/testdata/script/cgo_lto_issue43830.txt @@ -15,6 +15,7 @@ go build main.go add.go package main /* +extern int myadd(int, int); int c_add(int a, int b) { return myadd(a, b); } -- cgit v1.3-5-g9baa From 84c0e5d47f46f2e1a7ce92341477d9801f0ef777 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 1 Jun 2021 14:58:36 -0700 Subject: 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 --- src/cmd/go/testdata/script/cgo_lto2_issue43830.txt | 33 ----- src/cmd/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 (limited to 'src/cmd') 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 e2483ba784..0000000000 --- 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 8bc7d8a540..0000000000 --- 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 0000000000..09390daeb7 --- /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") + } +} -- cgit v1.3-5-g9baa From ff9f5fb8591c6d3e4cd4881e75f49440a3a875c2 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 2 Jun 2021 07:43:57 -0700 Subject: cmd/link: recognize clang linker error in testCGOLTO Also recognize a case in which GCC does not run (from https://build.golang.org/log/7f6d8b35c905b9829f05906beccca44f208aa569). Fixes #46517 Change-Id: I4fe4164a5df92b2dec08fd767f65a4d5479f3f36 Reviewed-on: https://go-review.googlesource.com/c/go/+/324169 Trust: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot Reviewed-by: Bryan C. Mills Reviewed-by: Tobias Klauser --- src/cmd/link/cgo_test.go | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/cmd') diff --git a/src/cmd/link/cgo_test.go b/src/cmd/link/cgo_test.go index 09390daeb7..26ab802454 100644 --- a/src/cmd/link/cgo_test.go +++ b/src/cmd/link/cgo_test.go @@ -121,11 +121,14 @@ func testCGOLTO(t *testing.T, cc string, test int) { t.Logf("go build failed: %v", err) // Error messages we've seen indicating that LTO is not supported. + // These errors come from GCC or clang, not Go. 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", + "linker command failed with exit code", + "gcc: can't load library", } for _, msg := range noLTO { if bytes.Contains(out, []byte(msg)) { -- cgit v1.3-5-g9baa From 6d9830111402d9bd69893a8ad6074ac92a5ddd0d Mon Sep 17 00:00:00 2001 From: Than McIntosh Date: Thu, 3 Jun 2021 14:50:10 -0400 Subject: cmd/link: use correct alignment in PE DWARF sections Set the correct section flags to insure that .debug_* sections are using 1-byte alignment instead of the default. This seems to be important for later versions of LLVM-mingw on windows (shows up on the windows/arm64 builder). Updates #46406. Change-Id: I023d5208374f867552ba68b45011f7990159868f Reviewed-on: https://go-review.googlesource.com/c/go/+/324763 Trust: Than McIntosh Reviewed-by: Cherry Mui Run-TryBot: Than McIntosh TryBot-Result: Go Bot --- src/cmd/link/internal/ld/pe.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/cmd') diff --git a/src/cmd/link/internal/ld/pe.go b/src/cmd/link/internal/ld/pe.go index 3540c07da1..8eb4231c3a 100644 --- a/src/cmd/link/internal/ld/pe.go +++ b/src/cmd/link/internal/ld/pe.go @@ -475,7 +475,7 @@ func (f *peFile) addDWARFSection(name string, size int) *peSection { off := f.stringTable.add(name) h := f.addSection(name, size, size) h.shortName = fmt.Sprintf("/%d", off) - h.characteristics = IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_CNT_INITIALIZED_DATA + h.characteristics = IMAGE_SCN_ALIGN_1BYTES | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_CNT_INITIALIZED_DATA return h } -- cgit v1.3-5-g9baa From b29b123e079183a05abc1066007a51d4f565cd88 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Thu, 3 Jun 2021 18:00:53 -0700 Subject: cmd/compile: remove spurious ir.Dump This ir.Dump call is a debugging artifact introduced in golang.org/cl/274103, which should never be printed for valid, non-generic code, but evidently can now sometimes appear due to how the parser handles invalid syntax. The parser should probably not recognize "x[2]" as a type expression in non-generics mode, but also probably we shouldn't try noding after reporting syntax errors. Either way, this diagnostic has outlived its usefulness, and noder's days are numbered anyway, so we might as well just remove it to save end users any confusion. Updates #46558. Change-Id: Ib68502ef834d610b883c2f2bb11d9b385bc66e37 Reviewed-on: https://go-review.googlesource.com/c/go/+/324991 Trust: Matthew Dempsky Run-TryBot: Matthew Dempsky Reviewed-by: Robert Griesemer TryBot-Result: Go Bot --- src/cmd/compile/internal/noder/noder.go | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/cmd') diff --git a/src/cmd/compile/internal/noder/noder.go b/src/cmd/compile/internal/noder/noder.go index 4c7c9fc322..5fcad096c2 100644 --- a/src/cmd/compile/internal/noder/noder.go +++ b/src/cmd/compile/internal/noder/noder.go @@ -882,9 +882,6 @@ func (p *noder) typeExpr(typ syntax.Expr) ir.Ntype { if n == nil { return nil } - if _, ok := n.(ir.Ntype); !ok { - ir.Dump("NOT NTYPE", n) - } return n.(ir.Ntype) } -- cgit v1.3-5-g9baa From 962d5c997af450af1de9a38eb6510cdfc86ea689 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Wed, 2 Jun 2021 12:22:50 -0700 Subject: cmd/compile,go/types: restrict use of unsafe.{Add,Slice} to go1.17 or newer This CL updates cmd/compile (including types2) and go/types to report errors about using unsafe.Add and unsafe.Slice when language compatibility is set to Go 1.16 or older. Fixes #46525. Change-Id: I1bfe025a672d9f4b929f443064ad1effd38d0363 Reviewed-on: https://go-review.googlesource.com/c/go/+/324369 Run-TryBot: Matthew Dempsky Reviewed-by: Robert Findley Reviewed-by: Robert Griesemer TryBot-Result: Go Bot Trust: Matthew Dempsky --- src/cmd/compile/internal/typecheck/func.go | 12 ++++++++++++ src/cmd/compile/internal/types2/builtins.go | 10 ++++++++++ src/go/types/builtins.go | 10 ++++++++++ test/fixedbugs/issue46525.go | 14 ++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 test/fixedbugs/issue46525.go (limited to 'src/cmd') diff --git a/src/cmd/compile/internal/typecheck/func.go b/src/cmd/compile/internal/typecheck/func.go index f381e1dbdc..a6dfbbf569 100644 --- a/src/cmd/compile/internal/typecheck/func.go +++ b/src/cmd/compile/internal/typecheck/func.go @@ -981,6 +981,12 @@ func tcRecover(n *ir.CallExpr) ir.Node { // tcUnsafeAdd typechecks an OUNSAFEADD node. func tcUnsafeAdd(n *ir.BinaryExpr) *ir.BinaryExpr { + if !types.AllowsGoVersion(curpkg(), 1, 17) { + base.ErrorfVers("go1.17", "unsafe.Add") + n.SetType(nil) + return n + } + n.X = AssignConv(Expr(n.X), types.Types[types.TUNSAFEPTR], "argument to unsafe.Add") n.Y = DefaultLit(Expr(n.Y), types.Types[types.TINT]) if n.X.Type() == nil || n.Y.Type() == nil { @@ -997,6 +1003,12 @@ func tcUnsafeAdd(n *ir.BinaryExpr) *ir.BinaryExpr { // tcUnsafeSlice typechecks an OUNSAFESLICE node. func tcUnsafeSlice(n *ir.BinaryExpr) *ir.BinaryExpr { + if !types.AllowsGoVersion(curpkg(), 1, 17) { + base.ErrorfVers("go1.17", "unsafe.Slice") + n.SetType(nil) + return n + } + n.X = Expr(n.X) n.Y = Expr(n.Y) if n.X.Type() == nil || n.Y.Type() == nil { diff --git a/src/cmd/compile/internal/types2/builtins.go b/src/cmd/compile/internal/types2/builtins.go index b9e178dd57..f90e06f226 100644 --- a/src/cmd/compile/internal/types2/builtins.go +++ b/src/cmd/compile/internal/types2/builtins.go @@ -579,6 +579,11 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) ( case _Add: // unsafe.Add(ptr unsafe.Pointer, len IntegerType) unsafe.Pointer + if !check.allowVersion(check.pkg, 1, 17) { + check.error(call.Fun, "unsafe.Add requires go1.17 or later") + return + } + check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add") if x.mode == invalid { return @@ -675,6 +680,11 @@ func (check *Checker) builtin(x *operand, call *syntax.CallExpr, id builtinId) ( case _Slice: // unsafe.Slice(ptr *T, len IntegerType) []T + if !check.allowVersion(check.pkg, 1, 17) { + check.error(call.Fun, "unsafe.Slice requires go1.17 or later") + return + } + typ := asPointer(x.typ) if typ == nil { check.errorf(x, invalidArg+"%s is not a pointer", x) diff --git a/src/go/types/builtins.go b/src/go/types/builtins.go index 739051cc61..2a2d54da88 100644 --- a/src/go/types/builtins.go +++ b/src/go/types/builtins.go @@ -588,6 +588,11 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b case _Add: // unsafe.Add(ptr unsafe.Pointer, len IntegerType) unsafe.Pointer + if !check.allowVersion(check.pkg, 1, 17) { + check.errorf(call.Fun, _InvalidUnsafeAdd, "unsafe.Add requires go1.17 or later") + return + } + check.assignment(x, Typ[UnsafePointer], "argument to unsafe.Add") if x.mode == invalid { return @@ -684,6 +689,11 @@ func (check *Checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b case _Slice: // unsafe.Slice(ptr *T, len IntegerType) []T + if !check.allowVersion(check.pkg, 1, 17) { + check.errorf(call.Fun, _InvalidUnsafeSlice, "unsafe.Slice requires go1.17 or later") + return + } + typ := asPointer(x.typ) if typ == nil { check.invalidArg(x, _InvalidUnsafeSlice, "%s is not a pointer", x) diff --git a/test/fixedbugs/issue46525.go b/test/fixedbugs/issue46525.go new file mode 100644 index 0000000000..164e1473ce --- /dev/null +++ b/test/fixedbugs/issue46525.go @@ -0,0 +1,14 @@ +// errorcheck -lang=go1.16 + +// 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 p + +import "unsafe" + +func main() { + _ = unsafe.Add(unsafe.Pointer(nil), 0) // ERROR "unsafe.Add requires go1.17 or later" + _ = unsafe.Slice(new(byte), 1) // ERROR "unsafe.Slice requires go1.17 or later" +} -- cgit v1.3-5-g9baa From 95939e8de71d9e8d8deea3d1605bd34130588292 Mon Sep 17 00:00:00 2001 From: sryoya Date: Sat, 5 Jun 2021 03:12:03 +0900 Subject: cmd/compile/internal/abi: fix typo in comment Change-Id: I196045314b2b0e908d7b31ac0cea5b25404f3ee0 Reviewed-on: https://go-review.googlesource.com/c/go/+/325249 Reviewed-by: Matthew Dempsky Trust: Keith Randall --- src/cmd/compile/internal/abi/abiutils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/cmd') diff --git a/src/cmd/compile/internal/abi/abiutils.go b/src/cmd/compile/internal/abi/abiutils.go index cb8e9d7b0f..b8ea1955d1 100644 --- a/src/cmd/compile/internal/abi/abiutils.go +++ b/src/cmd/compile/internal/abi/abiutils.go @@ -449,7 +449,7 @@ func (config *ABIConfig) ABIAnalyze(t *types.Type, setNname bool) *ABIParamResul // parameterUpdateMu protects the Offset field of function/method parameters (a subset of structure Fields) var parameterUpdateMu sync.Mutex -// FieldOffsetOf returns a concurency-safe version of f.Offset +// FieldOffsetOf returns a concurrency-safe version of f.Offset func FieldOffsetOf(f *types.Field) int64 { parameterUpdateMu.Lock() defer parameterUpdateMu.Unlock() -- cgit v1.3-5-g9baa