Skip to content

cmd/link: multiple function bodies accepted, one in a .go, one in a .s #15297

@nigeltao

Description

@nigeltao
$ pwd
/tmp/scratch
$ ls
main.go  x_amd64.s  x_other.go
$ cat main.go 
package main

func main() {
    println(foo())
}
$ cat x_amd64.s 
TEXT ·foo(SB), 7, $0
    MOVQ $43, ret+0(FP)
    RET

$ cat x_other.go 
package main

func foo() int { return 42 }

Note that foo has two bodies defined: one returns 42, the other returns 43. Surely this should be a compile or asm or link error, yet "go build" seems happy:

$ go build -x && ./scratch && rm ./scratch 
WORK=/tmp/go-build115513716
mkdir -p $WORK/_/tmp/scratch/_obj/
mkdir -p $WORK/_/tmp/scratch/_obj/exe/
cd /tmp/scratch
/home/nt/go/pkg/tool/linux_amd64/compile -o $WORK/_/tmp/scratch.a -trimpath $WORK -p main -buildid acfccd74ae478f8fecc64195dd5e90e7757cec11 -D _/tmp/scratch -I $WORK -pack -asmhdr $WORK/_/tmp/scratch/_obj/go_asm.h ./main.go ./x_other.go
/home/nt/go/pkg/tool/linux_amd64/asm -o $WORK/_/tmp/scratch/_obj/x_amd64.o -trimpath $WORK -I $WORK/_/tmp/scratch/_obj/ -I /home/nt/go/pkg/include -D GOOS_linux -D GOARCH_amd64 ./x_amd64.s
pack r $WORK/_/tmp/scratch.a $WORK/_/tmp/scratch/_obj/x_amd64.o # internal
cd .
/home/nt/go/pkg/tool/linux_amd64/link -o $WORK/_/tmp/scratch/_obj/exe/a.out -L $WORK -extld=gcc -buildmode=exe -buildid=acfccd74ae478f8fecc64195dd5e90e7757cec11 $WORK/_/tmp/scratch.a
mv $WORK/_/tmp/scratch/_obj/exe/a.out scratch
42

Changing the

func foo() int { return 42 }

to be

func foo() int

in x_other.go now has "go build" picking up the other definition:

$ vim x_other.go 
$ cat x_other.go 
package main

func foo() int
$ go build -x && ./scratch && rm ./scratch 
WORK=/tmp/go-build732255335
mkdir -p $WORK/_/tmp/scratch/_obj/
mkdir -p $WORK/_/tmp/scratch/_obj/exe/
cd /tmp/scratch
/home/nt/go/pkg/tool/linux_amd64/compile -o $WORK/_/tmp/scratch.a -trimpath $WORK -p main -buildid acfccd74ae478f8fecc64195dd5e90e7757cec11 -D _/tmp/scratch -I $WORK -pack -asmhdr $WORK/_/tmp/scratch/_obj/go_asm.h ./main.go ./x_other.go
/home/nt/go/pkg/tool/linux_amd64/asm -o $WORK/_/tmp/scratch/_obj/x_amd64.o -trimpath $WORK -I $WORK/_/tmp/scratch/_obj/ -I /home/nt/go/pkg/include -D GOOS_linux -D GOARCH_amd64 ./x_amd64.s
pack r $WORK/_/tmp/scratch.a $WORK/_/tmp/scratch/_obj/x_amd64.o # internal
cd .
/home/nt/go/pkg/tool/linux_amd64/link -o $WORK/_/tmp/scratch/_obj/exe/a.out -L $WORK -extld=gcc -buildmode=exe -buildid=acfccd74ae478f8fecc64195dd5e90e7757cec11 $WORK/_/tmp/scratch.a
mv $WORK/_/tmp/scratch/_obj/exe/a.out scratch
43

Still, something ain't right. Re-inserting that

{ return 42 }

into the x_other.go file gives:

$ vim x_other.go 
$ cat x_other.go 
package main

func foo() int { return 42 }
$ go vet
: x_amd64.s:1: [amd64] foo: function foo missing Go declaration
exit status 1

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions