diff --git a/src/cmd/compile/internal/gc/noder.go b/src/cmd/compile/internal/gc/noder.go index b9849e7a849..23c9539b0a1 100644 --- a/src/cmd/compile/internal/gc/noder.go +++ b/src/cmd/compile/internal/gc/noder.go @@ -497,7 +497,18 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node { } } else { if pure_go || strings.HasPrefix(f.funcname(), "init.") { - yyerrorl(f.Pos, "missing function body") + // Linknamed functions are allowed to have no body. Hopefully + // the linkname target has a body. See issue 23311. + isLinknamed := false + for _, n := range p.linknames { + if f.funcname() == n.local { + isLinknamed = true + break + } + } + if !isLinknamed { + yyerrorl(f.Pos, "missing function body") + } } } diff --git a/src/runtime/testdata/testprog/empty.s b/test/fixedbugs/issue23311.dir/main.go similarity index 59% rename from src/runtime/testdata/testprog/empty.s rename to test/fixedbugs/issue23311.dir/main.go index c5aa6f8a546..fa4cf76b89a 100644 --- a/src/runtime/testdata/testprog/empty.s +++ b/test/fixedbugs/issue23311.dir/main.go @@ -2,4 +2,13 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// This exists solely so we can linkname in symbols from runtime. +package main + +import _ "unsafe" // for linkname + +//go:linkname f runtime.GC +func f() + +func main() { + f() +} diff --git a/src/internal/syscall/unix/empty.s b/test/fixedbugs/issue23311.go similarity index 70% rename from src/internal/syscall/unix/empty.s rename to test/fixedbugs/issue23311.go index 717189c6585..128cf9d06ad 100644 --- a/src/internal/syscall/unix/empty.s +++ b/test/fixedbugs/issue23311.go @@ -1,5 +1,7 @@ +// compiledir + // 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 exists solely so we can linkname in symbols from syscall. +package ignored