golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.13k stars 17.68k forks source link

gccgo: assert in "implements_interface", types.cc:9098 with inlinable function #33219

Closed thanm closed 5 years ago

thanm commented 5 years ago

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

$ go version
go version go1.12.2 gccgo (GCC) 10.0.0 20190627 (experimental) linux/amd64

Does this issue reproduce with the latest release?

yes

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

linux/amd64

What did you do?

This bug is a sibling of issue 33013; the failure mode is very similar, but because of the way the type in question is being imported, the fix for 33013 is not effective.

To reproduce, compile these three packages:

Package "a":

package a

type A interface {
    M(i interface{}) interface{}
}

var a1 A
var a2 A

func V(p A, k, v interface{}) A {
    defer func() { a1, a2 = a2, a1 }()
    return a1
}

Package "b":

package b

import "a"

type Service uint64

var q *Service
var r *Service

type f struct{}

var fk f

func No(s a.A, qq uint8) *Service {
    defer func() { q, r = r, q }()
    return q
}

func Yes(s a.A, p *uint64) a.A {
    return a.V(s, fk, p)
}

Package "c":

package c

import (
    "a"
    "b"
)

type BI interface {
    Another(pxp a.A) int32
}

//go:noinline
func BRS(sd a.G, xyz int) *b.Service {
    x := b.Yes(sd, nil)
    return b.No(x, 1)
}

What did you expect to see?

Passing compilation

What did you see instead?

Compiler hits this assert:

go1: internal compiler error: in implements_interface, at go/gofrontend/types.cc:9098
0x76fba0 Interface_type::implements_interface(Type const*, std::__cxx11::basic_string, std::allocator >*) const
    ../../gcc-trunk/gcc/go/gofrontend/types.cc:9098
0x76fe02 Type::are_assignable(Type const*, Type const*, std::__cxx11::basic_string, std::allocator >*)
    ../../gcc-trunk/gcc/go/gofrontend/types.cc:686
0x770759 Type::are_convertible(Type const*, Type const*, std::__cxx11::basic_string, std::allocator >*)
    ../../gcc-trunk/gcc/go/gofrontend/types.cc:762
0x6bd5c5 Type_conversion_expression::do_check_types(Gogo*)
    ../../gcc-trunk/gcc/go/gofrontend/expressions.cc:3921
0x7007a3 Expression::check_types(Gogo*)
    ../../gcc-trunk/gcc/go/gofrontend/expressions.h:957
0x7007a3 Check_types_traverse::expression(Expression**)
    ../../gcc-trunk/gcc/go/gofrontend/gogo.cc:3766
0x6c2e5d Expression::traverse(Expression**, Traverse*)
    ../../gcc-trunk/gcc/go/gofrontend/expressions.cc:45
0x6d0eb8 Expression_list::traverse(Traverse*)
    ../../gcc-trunk/gcc/go/gofrontend/expressions.cc:18499
0x6d0f1e Call_expression::do_traverse(Traverse*)
    ../../gcc-trunk/gcc/go/gofrontend/expressions.cc:10647
0x704601 Block::traverse(Traverse*)
    ../../gcc-trunk/gcc/go/gofrontend/gogo.cc:6832
0x704601 Block::traverse(Traverse*)
    ../../gcc-trunk/gcc/go/gofrontend/gogo.cc:6832
0x704869 Function::traverse(Traverse*)
    ../../gcc-trunk/gcc/go/gofrontend/gogo.cc:5738
0x7097eb Bindings::traverse(Traverse*, bool)
    ../../gcc-trunk/gcc/go/gofrontend/gogo.cc:9053
0x709bca Gogo::traverse(Traverse*)
    ../../gcc-trunk/gcc/go/gofrontend/gogo.cc:2837
0x709e96 Gogo::check_types()

The fix for issue 33013 added a cleanup pass after Import::read_types() that went through the vector of newly imported types looking for interface types -- this works if the type in question is imported eagerly, but doesn't work if the type is only mentioned in a function that gets imported later on.

gopherbot commented 5 years ago

Change https://golang.org/cl/187057 mentions this issue: test: new testcase for gccgo compiler failure

gopherbot commented 5 years ago

Change https://golang.org/cl/187058 mentions this issue: compiler: follow-on fix for finalizing imported methods