Skip to content

Commit 4f4320b

Browse files
committed
compiler: support //go:linknamestd pragma
Go 1.27 introduced the //go:linknamestd directive, a standard-library variant of //go:linkname that does not require importing "unsafe". The iter package switched to it for referencing runtime.newcoro and runtime.coroswitch, which caused "linker could not find symbol iter.newcoro / iter.coroswitch" errors when building with Go 1.27. Handle //go:linknamestd the same as //go:linkname, bypassing the unsafe import requirement, and add test coverage in the pragma compiler test. Signed-off-by: deadprogram <ron@hybridgroup.com>
1 parent 9b154b5 commit 4f4320b

3 files changed

Lines changed: 13 additions & 2 deletions

File tree

compiler/symbol.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -443,15 +443,18 @@ func (c *compilerContext) parsePragmas(info *functionInfo, f *ssa.Function) {
443443
info.inline = inlineHint
444444
case "//go:noinline":
445445
info.inline = inlineNone
446-
case "//go:linkname":
446+
case "//go:linkname", "//go:linknamestd":
447447
if len(parts) != 3 || parts[1] != f.Name() {
448448
continue
449449
}
450450
// Only enable go:linkname when the package imports "unsafe".
451451
// This is a slightly looser requirement than what gc uses: gc
452452
// requires the file to import "unsafe", not the package as a
453453
// whole.
454-
if hasUnsafeImport(f.Pkg.Pkg) {
454+
// //go:linknamestd is a Go 1.27+ variant used inside the standard
455+
// library (for example by the iter package) that does not require
456+
// importing "unsafe".
457+
if parts[0] == "//go:linknamestd" || hasUnsafeImport(f.Pkg.Pkg) {
455458
info.linkName = parts[2]
456459
}
457460
case "//go:section":

compiler/testdata/pragma.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ func withLinkageName1() {
3535
//go:linkname withLinkageName2 somepkg.someFunction2
3636
func withLinkageName2()
3737

38+
// Import a function from a different package using go:linknamestd (the standard
39+
// library variant of go:linkname introduced in Go 1.27).
40+
//
41+
//go:linknamestd withLinkageNameStd somepkg.someFunctionStd
42+
func withLinkageNameStd()
43+
3844
// Function has an 'inline hint', similar to the inline keyword in C.
3945
//
4046
//go:inline

compiler/testdata/pragma.ll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ entry:
3333

3434
declare void @somepkg.someFunction2(ptr) #0
3535

36+
declare void @somepkg.someFunctionStd(ptr) #0
37+
3638
; Function Attrs: inlinehint nounwind
3739
define hidden void @main.inlineFunc(ptr %context) unnamed_addr #3 {
3840
entry:

0 commit comments

Comments
 (0)