]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: allow bodyless function if it is linkname'd
authorKeith Randall <khr@google.com>
Mon, 26 Nov 2018 18:48:56 +0000 (10:48 -0800)
committerKeith Randall <khr@golang.org>
Mon, 26 Nov 2018 20:00:59 +0000 (20:00 +0000)
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>
src/cmd/compile/internal/gc/noder.go
test/fixedbugs/issue23311.dir/main.go [moved from src/runtime/testdata/testprog/empty.s with 59% similarity]
test/fixedbugs/issue23311.go [moved from src/internal/syscall/unix/empty.s with 70% similarity]

index b9849e7a8491b8370c29d7f7c97bdc5e379227d2..23c9539b0a1ae5fed245f2ccf88f62563379439e 100644 (file)
@@ -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")
+                       }
                }
        }
 
similarity index 59%
rename from src/runtime/testdata/testprog/empty.s
rename to test/fixedbugs/issue23311.dir/main.go
index c5aa6f8a54661f840d41ffb1602a101a42009e82..fa4cf76b89a7a07faff2bdc5b0506625ca607344 100644 (file)
@@ -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()
+}
similarity index 70%
rename from src/internal/syscall/unix/empty.s
rename to test/fixedbugs/issue23311.go
index 717189c6585128458f33454e3030f7a9dda5c7d1..128cf9d06ad6ed5c0d03c3889cf3ea483ad289af 100644 (file)
@@ -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