Skip to content

Commit 6f5590e

Browse files
wdvxdr1123randall77
authored andcommitted
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 <[email protected]> Run-TryBot: Keith Randall <[email protected]> Auto-Submit: Keith Randall <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: David Chase <[email protected]>
1 parent 5bf6c97 commit 6f5590e

File tree

3 files changed

+64
-8
lines changed

3 files changed

+64
-8
lines changed

src/cmd/compile/internal/reflectdata/reflect.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,21 +1328,21 @@ func writeITab(lsym *obj.LSym, typ, iface *types.Type, allowNonImplement bool) {
13281328
// type itab struct {
13291329
// inter *interfacetype
13301330
// _type *_type
1331-
// hash uint32
1331+
// hash uint32 // copy of _type.hash. Used for type switches.
13321332
// _ [4]byte
1333-
// fun [1]uintptr // variable sized
1333+
// fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
13341334
// }
13351335
o := objw.SymPtr(lsym, 0, writeType(iface), 0)
13361336
o = objw.SymPtr(lsym, o, writeType(typ), 0)
13371337
o = objw.Uint32(lsym, o, types.TypeHash(typ)) // copy of type hash
13381338
o += 4 // skip unused field
1339+
if !completeItab {
1340+
// If typ doesn't implement iface, make method entries be zero.
1341+
o = objw.Uintptr(lsym, o, 0)
1342+
entries = entries[:0]
1343+
}
13391344
for _, fn := range entries {
1340-
if !completeItab {
1341-
// If typ doesn't implement iface, make method entries be zero.
1342-
o = objw.Uintptr(lsym, o, 0)
1343-
} else {
1344-
o = objw.SymPtrWeak(lsym, o, fn, 0) // method pointer for each method
1345-
}
1345+
o = objw.SymPtrWeak(lsym, o, fn, 0) // method pointer for each method
13461346
}
13471347
// Nothing writes static itabs, so they are read only.
13481348
objw.Global(lsym, int32(o), int16(obj.DUPOK|obj.RODATA))

test/typeparam/issue51700.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// run
2+
3+
// Copyright 2022 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package main
8+
9+
func f[B any](b B) {
10+
if b1, ok := any(b).(interface{ m1() }); ok {
11+
panic(1)
12+
_ = b1.(B)
13+
}
14+
if b2, ok := any(b).(interface{ m2() }); ok {
15+
panic(2)
16+
_ = b2.(B)
17+
}
18+
}
19+
20+
type S struct{}
21+
22+
func (S) m3() {}
23+
24+
func main() {
25+
f(S{})
26+
}

test/typeparam/issue52228.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// run
2+
3+
// Copyright 2022 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package main
8+
9+
type SomeInterface interface {
10+
Whatever()
11+
}
12+
13+
func X[T any]() T {
14+
var m T
15+
16+
// for this example, this block should never run
17+
if _, ok := any(m).(SomeInterface); ok {
18+
var dst SomeInterface
19+
_, _ = dst.(T)
20+
return dst.(T)
21+
}
22+
23+
return m
24+
}
25+
26+
type holder struct{}
27+
28+
func main() {
29+
X[holder]()
30+
}

0 commit comments

Comments
 (0)