mirror of
https://github.com/golang/go.git
synced 2025-05-05 23:53:05 +00:00
cmd/compile: fix crawling of embeddable types during inline
In CL 327872, there's a fix for crawling of embeddable types directly reached by the user, so all of its methods need to be re-exported. But we missed the cased when an un-exported type may be reachable by embedding in exported type. Example: type t struct {} func (t) M() {} func F() interface{} { return struct{ t }{} } We generate the wrapper for "struct{ t }".M, and when inlining call to "struct{ t }".M makes "t.M" reachable. It works well, and only be revealed in CL 327871, when we changed methodWrapper to always call inline.InlineCalls, thus causes the crash in #49016, which involve dot type in inlined function. Fixes #49016 Change-Id: If174fa5575132da5cf60e4bd052f7011c4e76c5d Reviewed-on: https://go-review.googlesource.com/c/go/+/356254 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
27a1454ee0
commit
4e565f7372
@ -195,18 +195,35 @@ func (p *crawler) markInlBody(n *ir.Name) {
|
|||||||
var doFlood func(n ir.Node)
|
var doFlood func(n ir.Node)
|
||||||
doFlood = func(n ir.Node) {
|
doFlood = func(n ir.Node) {
|
||||||
t := n.Type()
|
t := n.Type()
|
||||||
if t != nil && (t.HasTParam() || t.IsFullyInstantiated()) {
|
if t != nil {
|
||||||
// Ensure that we call markType() on any base generic type
|
if t.HasTParam() || t.IsFullyInstantiated() {
|
||||||
// that is written to the export file (even if not explicitly
|
// Ensure that we call markType() on any base generic type
|
||||||
// marked for export), so we will call markInlBody on its
|
// that is written to the export file (even if not explicitly
|
||||||
// methods, and the methods will be available for
|
// marked for export), so we will call markInlBody on its
|
||||||
// instantiation if needed.
|
// methods, and the methods will be available for
|
||||||
p.markType(t)
|
// instantiation if needed.
|
||||||
|
p.markType(t)
|
||||||
|
}
|
||||||
|
if base.Debug.Unified == 0 {
|
||||||
|
// If a method of un-exported type is promoted and accessible by
|
||||||
|
// embedding in an exported type, it makes that type reachable.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
//
|
||||||
|
// type t struct {}
|
||||||
|
// func (t) M() {}
|
||||||
|
//
|
||||||
|
// func F() interface{} { return struct{ t }{} }
|
||||||
|
//
|
||||||
|
// We generate the wrapper for "struct{ t }".M, and inline call
|
||||||
|
// to "struct{ t }".M, which makes "t.M" reachable.
|
||||||
|
p.markEmbed(t)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch n.Op() {
|
switch n.Op() {
|
||||||
case ir.OMETHEXPR, ir.ODOTMETH:
|
case ir.OMETHEXPR, ir.ODOTMETH:
|
||||||
p.markInlBody(ir.MethodExprName(n))
|
p.markInlBody(ir.MethodExprName(n))
|
||||||
|
|
||||||
case ir.ONAME:
|
case ir.ONAME:
|
||||||
n := n.(*ir.Name)
|
n := n.(*ir.Name)
|
||||||
switch n.Class {
|
switch n.Class {
|
||||||
|
36
test/fixedbugs/issue49016.dir/a.go
Normal file
36
test/fixedbugs/issue49016.dir/a.go
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2021 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.
|
||||||
|
|
||||||
|
package a
|
||||||
|
|
||||||
|
type Node interface {
|
||||||
|
Position()
|
||||||
|
}
|
||||||
|
|
||||||
|
type noder struct{}
|
||||||
|
|
||||||
|
func (noder) Position() {}
|
||||||
|
|
||||||
|
type Scope map[int][]Node
|
||||||
|
|
||||||
|
func (s Scope) M1() Scope {
|
||||||
|
if x, ok := s[0]; ok {
|
||||||
|
return x[0].(struct {
|
||||||
|
noder
|
||||||
|
Scope
|
||||||
|
}).Scope
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Scope) M2() Scope {
|
||||||
|
if x, ok := s[0]; ok {
|
||||||
|
st, _ := x[0].(struct {
|
||||||
|
noder
|
||||||
|
Scope
|
||||||
|
})
|
||||||
|
return st.Scope
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
13
test/fixedbugs/issue49016.dir/b.go
Normal file
13
test/fixedbugs/issue49016.dir/b.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Copyright 2021 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.
|
||||||
|
|
||||||
|
package b
|
||||||
|
|
||||||
|
type t int
|
||||||
|
|
||||||
|
func (t) m() {}
|
||||||
|
|
||||||
|
func F1() interface{} { return struct{ t }{} }
|
||||||
|
func F2() interface{} { return *new(struct{ t }) }
|
||||||
|
func F3() interface{} { var x [1]struct{ t }; return x[0] }
|
9
test/fixedbugs/issue49016.dir/c.go
Normal file
9
test/fixedbugs/issue49016.dir/c.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2021 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.
|
||||||
|
|
||||||
|
package c
|
||||||
|
|
||||||
|
import "./a"
|
||||||
|
|
||||||
|
var _ = (&a.Scope{}).M1()
|
9
test/fixedbugs/issue49016.dir/d.go
Normal file
9
test/fixedbugs/issue49016.dir/d.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2021 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.
|
||||||
|
|
||||||
|
package d
|
||||||
|
|
||||||
|
import "./a"
|
||||||
|
|
||||||
|
var _ = (&a.Scope{}).M2()
|
11
test/fixedbugs/issue49016.dir/e.go
Normal file
11
test/fixedbugs/issue49016.dir/e.go
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright 2021 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.
|
||||||
|
|
||||||
|
package e
|
||||||
|
|
||||||
|
import (
|
||||||
|
"./b"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ = b.F1()
|
9
test/fixedbugs/issue49016.dir/f.go
Normal file
9
test/fixedbugs/issue49016.dir/f.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2021 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.
|
||||||
|
|
||||||
|
package f
|
||||||
|
|
||||||
|
import "./b"
|
||||||
|
|
||||||
|
var _ = b.F2()
|
9
test/fixedbugs/issue49016.dir/g.go
Normal file
9
test/fixedbugs/issue49016.dir/g.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Copyright 2021 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.
|
||||||
|
|
||||||
|
package g
|
||||||
|
|
||||||
|
import "./b"
|
||||||
|
|
||||||
|
var _ = b.F3()
|
7
test/fixedbugs/issue49016.go
Normal file
7
test/fixedbugs/issue49016.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// compiledir
|
||||||
|
|
||||||
|
// Copyright 2021 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.
|
||||||
|
|
||||||
|
package ignored
|
Loading…
x
Reference in New Issue
Block a user