Skip to content

Commit

Permalink
cmd/compile: allow bodyless function if it is linkname'd
Browse files Browse the repository at this point in the history
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 <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
  • Loading branch information
randall77 committed Nov 26, 2018
1 parent 9ab2ffe commit ca37492
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 3 deletions.
13 changes: 12 additions & 1 deletion src/cmd/compile/internal/gc/noder.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()
}
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit ca37492

Please sign in to comment.