Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gccgo: undefined reference when linking #40252

Closed
zhsj opened this issue Jul 16, 2020 · 8 comments
Closed

gccgo: undefined reference when linking #40252

zhsj opened this issue Jul 16, 2020 · 8 comments
Milestone

Comments

@zhsj
Copy link

@zhsj zhsj commented Jul 16, 2020

What version of Go are you using (go version)?

$ go version
go version go1.14.4 gccgo (Debian 20200715-1) 11.0.0 20200715 (experimental) [master revision fff15bad1ab:53319423ecb:7a9fd18598e638b55c591624e753fb7a88abe1ab] linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/zhsj/.cache/go-build"
GOENV="/home/zhsj/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/zhsj/go"
GOPRIVATE=""
GOPROXY="https://goproxy.io"
GOROOT="/usr"
GOSUMDB="sum.golang.google.cn"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/gcc/x86_64-linux-gnu/10"
GCCGO="/usr/lib/gcc-snapshot/bin/gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/tmp/t/tt/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build400584759=/tmp/go-build -gno-record-gcc-switches -funwind-tables"

What did you do?

I don't know how to describe the problem. I just find it when building elvish.

I have reproduced the problem with following code.

==> ./pkgb/pkgb.go <==
package pkgb

import "bugtest/pkga"

type B interface{
        GetA() pkga.A
}



==> ./test.go <==
package main

import (
        "bugtest/pkga"
        "bugtest/pkgc"
)

type testA struct {
}

func (testA) Func() {
}

type testB struct {
        a pkga.A
}

func (b testB) GetA() pkga.A {
        return b.a
}
func main() {
        b := testB{testA{}}
        pkgc.Test(b)
}

==> ./pkgc/pkgc.go <==
package pkgc

import (
        "bugtest/pkga"
        "bugtest/pkgb"
)

func test(b pkgb.B, f func(pkga.A)) {
        f(b.GetA())
}

func Test(b pkgb.B) {
        test(b, pkga.A.Func)
}

==> ./pkga/pkga.go <==
package pkga

type A interface {
        Func()
}

==> ./go.mod <==
module bugtest

go 1.14

What did you expect to see?

Build without error.

What did you see instead?

# bugtest
/usr/bin/ld: /home/zhsj/.cache/go-build/ea/ea4b9775947f0eae0848aa6de3b1dd2e84c3f5cbb5d5164df059bb4d2099acaa-d(_go_.o): in function `bugtest..z2fpkgc.Test':
/tmp/t/tt/ /tmp/t/tt/pkgc/pkgc.go:13: undefined reference to `bugtest..z2fpkgc.bugtest..z2fpkgc..thunk0..f'
collect2: error: ld returned 1 exit status
@gopherbot gopherbot added this to the Gccgo milestone Jul 16, 2020
@mdempsky
Copy link
Member

@mdempsky mdempsky commented Aug 12, 2020

Here's a more minimal reproducer:

$ cat go.mod
module bug

go 1.14

$ cat a/a.go
package a

type I interface {
	Func()
}

func Call() {
	f := I.Func
	f(nil)
}

$ cat main.go
package main

import "bug/a"

func main() {
	a.Call()
}

$ go build .
# bug
/usr/bin/ld: $WORK/b001/_pkg_.a(_go_.o): in function `bug..z2fa.Call':
/tmp/tt/ /tmp/tt/a/a.go:9: undefined reference to `bug..z2fa.bug..z2fa..thunk0..f'
/usr/bin/ld: /tmp/tt/ /tmp/tt/a/a.go:9: undefined reference to `bug..z2fa.bug..z2fa..thunk0..f'
collect2: error: ld returned 1 exit status

$ go version
go version go1.14.4 gccgo (GCC) 10.2.1 20200723 (Red Hat 10.2.1-1) linux/amd64
@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Aug 12, 2020

Thanks for the reduced test case.

The inlinable version of a.Call is

func Call () <inl:91>
 // /tmp/x/src/a/a.go:7
 var f <type 2> = a..thunk0 //8
 (f)($convert(<type 1>, $nil)) //9

Here the reference to I.Func has changed to a reference to a..thunk0. The bug is that we don't generate a function descriptor for that thunk function. Probably we need to generate the inlinable version differently here.

@gopherbot
Copy link

@gopherbot gopherbot commented Aug 14, 2020

Change https://golang.org/cl/248637 mentions this issue: test: add test case that caused gccgo undefined symbol reference

1 similar comment
@gopherbot
Copy link

@gopherbot gopherbot commented Aug 14, 2020

Change https://golang.org/cl/248637 mentions this issue: test: add test case that caused gccgo undefined symbol reference

@gopherbot
Copy link

@gopherbot gopherbot commented Aug 14, 2020

Change https://golang.org/cl/248638 mentions this issue: compiler: export thunks referenced by inline functions

gopherbot pushed a commit that referenced this issue Aug 15, 2020
For #40252

Change-Id: Ie23d2789ca9b4b9081adb39ab64c80c412ad58ce
Reviewed-on: https://go-review.googlesource.com/c/go/+/248637
Run-TryBot: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
@zhsj
Copy link
Author

@zhsj zhsj commented Sep 19, 2020

Hi,

Could this be backported to gcc10? It seems that Debian will use gcc10 for its next stable release.

@ianlancetaylor
Copy link
Contributor

@ianlancetaylor ianlancetaylor commented Sep 21, 2020

@zhsj The change was already backport to GCC 10 branch on August 14. GCC repository commit 1925bff7f21e5aaffb9a7fcf1356e67472d64b03.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.