Skip to content

Commit ca37492

Browse files
committed
cmd/compile: allow bodyless function if it is linkname'd
In assembly free packages (aka "complete" or "pure go"), allow bodyless functions if they are linkname'd to something else. Presumably the thing the function is linkname'd to has a definition. If not, the linker will complain. And linkname is unsafe, so we expect users to know what they are doing. Note this handles only one direction, where the linkname directive is in the local package. If the linkname directive is in the remote package, this CL won't help. (See os/signal/sig.s for an example.) Fixes #23311 Change-Id: I824361b4b582ee05976d94812e5b0e8b0f7a18a6 Reviewed-on: https://go-review.googlesource.com/c/151318 Run-TryBot: Keith Randall <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
1 parent 9ab2ffe commit ca37492

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

src/cmd/compile/internal/gc/noder.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,18 @@ func (p *noder) funcDecl(fun *syntax.FuncDecl) *Node {
497497
}
498498
} else {
499499
if pure_go || strings.HasPrefix(f.funcname(), "init.") {
500-
yyerrorl(f.Pos, "missing function body")
500+
// Linknamed functions are allowed to have no body. Hopefully
501+
// the linkname target has a body. See issue 23311.
502+
isLinknamed := false
503+
for _, n := range p.linknames {
504+
if f.funcname() == n.local {
505+
isLinknamed = true
506+
break
507+
}
508+
}
509+
if !isLinknamed {
510+
yyerrorl(f.Pos, "missing function body")
511+
}
501512
}
502513
}
503514

src/runtime/testdata/testprog/empty.s renamed to test/fixedbugs/issue23311.dir/main.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,13 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
// This exists solely so we can linkname in symbols from runtime.
5+
package main
6+
7+
import _ "unsafe" // for linkname
8+
9+
//go:linkname f runtime.GC
10+
func f()
11+
12+
func main() {
13+
f()
14+
}
Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
// compiledir
2+
13
// Copyright 2018 The Go Authors. All rights reserved.
24
// Use of this source code is governed by a BSD-style
35
// license that can be found in the LICENSE file.
46

5-
// This exists solely so we can linkname in symbols from syscall.
7+
package ignored

0 commit comments

Comments
 (0)