mirror of
https://github.com/golang/go
synced 2024-11-11 18:51:37 -07:00
cmd/compile: always write fun[0] in incomplete itab
runtime.getitab need filled fun[0] to identify whether implemented the interface. Fixes #51700 Fixes #52228 Change-Id: I0173b98f4e1b45e3a0183a5b60229d289140d1e6 Reviewed-on: https://go-review.googlesource.com/c/go/+/399058 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Keith Randall <khr@golang.org> Auto-Submit: Keith Randall <khr@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
5bf6c97e76
commit
6f5590edf6
@ -1328,21 +1328,21 @@ func writeITab(lsym *obj.LSym, typ, iface *types.Type, allowNonImplement bool) {
|
||||
// type itab struct {
|
||||
// inter *interfacetype
|
||||
// _type *_type
|
||||
// hash uint32
|
||||
// hash uint32 // copy of _type.hash. Used for type switches.
|
||||
// _ [4]byte
|
||||
// fun [1]uintptr // variable sized
|
||||
// fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
|
||||
// }
|
||||
o := objw.SymPtr(lsym, 0, writeType(iface), 0)
|
||||
o = objw.SymPtr(lsym, o, writeType(typ), 0)
|
||||
o = objw.Uint32(lsym, o, types.TypeHash(typ)) // copy of type hash
|
||||
o += 4 // skip unused field
|
||||
for _, fn := range entries {
|
||||
if !completeItab {
|
||||
// If typ doesn't implement iface, make method entries be zero.
|
||||
o = objw.Uintptr(lsym, o, 0)
|
||||
} else {
|
||||
o = objw.SymPtrWeak(lsym, o, fn, 0) // method pointer for each method
|
||||
entries = entries[:0]
|
||||
}
|
||||
for _, fn := range entries {
|
||||
o = objw.SymPtrWeak(lsym, o, fn, 0) // method pointer for each method
|
||||
}
|
||||
// Nothing writes static itabs, so they are read only.
|
||||
objw.Global(lsym, int32(o), int16(obj.DUPOK|obj.RODATA))
|
||||
|
26
test/typeparam/issue51700.go
Normal file
26
test/typeparam/issue51700.go
Normal file
@ -0,0 +1,26 @@
|
||||
// run
|
||||
|
||||
// Copyright 2022 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 main
|
||||
|
||||
func f[B any](b B) {
|
||||
if b1, ok := any(b).(interface{ m1() }); ok {
|
||||
panic(1)
|
||||
_ = b1.(B)
|
||||
}
|
||||
if b2, ok := any(b).(interface{ m2() }); ok {
|
||||
panic(2)
|
||||
_ = b2.(B)
|
||||
}
|
||||
}
|
||||
|
||||
type S struct{}
|
||||
|
||||
func (S) m3() {}
|
||||
|
||||
func main() {
|
||||
f(S{})
|
||||
}
|
30
test/typeparam/issue52228.go
Normal file
30
test/typeparam/issue52228.go
Normal file
@ -0,0 +1,30 @@
|
||||
// run
|
||||
|
||||
// Copyright 2022 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 main
|
||||
|
||||
type SomeInterface interface {
|
||||
Whatever()
|
||||
}
|
||||
|
||||
func X[T any]() T {
|
||||
var m T
|
||||
|
||||
// for this example, this block should never run
|
||||
if _, ok := any(m).(SomeInterface); ok {
|
||||
var dst SomeInterface
|
||||
_, _ = dst.(T)
|
||||
return dst.(T)
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
type holder struct{}
|
||||
|
||||
func main() {
|
||||
X[holder]()
|
||||
}
|
Loading…
Reference in New Issue
Block a user