Skip to content

Commit 2375a68

Browse files
randall77heschi
authored andcommitted
[release-branch.go1.18] cmd/compile: always write fun[0] in incomplete itab
runtime.getitab need filled fun[0] to identify whether implemented the interface. Fixes #51738 Fixes #52244 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]> Reviewed-on: https://go-review.googlesource.com/c/go/+/399974 Reviewed-by: Austin Clements <[email protected]>
1 parent 4f45424 commit 2375a68

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
@@ -1321,21 +1321,21 @@ func writeITab(lsym *obj.LSym, typ, iface *types.Type, allowNonImplement bool) {
13211321
// type itab struct {
13221322
// inter *interfacetype
13231323
// _type *_type
1324-
// hash uint32
1324+
// hash uint32 // copy of _type.hash. Used for type switches.
13251325
// _ [4]byte
1326-
// fun [1]uintptr // variable sized
1326+
// fun [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
13271327
// }
13281328
o := objw.SymPtr(lsym, 0, writeType(iface), 0)
13291329
o = objw.SymPtr(lsym, o, writeType(typ), 0)
13301330
o = objw.Uint32(lsym, o, types.TypeHash(typ)) // copy of type hash
13311331
o += 4 // skip unused field
1332+
if !completeItab {
1333+
// If typ doesn't implement iface, make method entries be zero.
1334+
o = objw.Uintptr(lsym, o, 0)
1335+
entries = entries[:0]
1336+
}
13321337
for _, fn := range entries {
1333-
if !completeItab {
1334-
// If typ doesn't implement iface, make method entries be zero.
1335-
o = objw.Uintptr(lsym, o, 0)
1336-
} else {
1337-
o = objw.SymPtrWeak(lsym, o, fn, 0) // method pointer for each method
1338-
}
1338+
o = objw.SymPtrWeak(lsym, o, fn, 0) // method pointer for each method
13391339
}
13401340
// Nothing writes static itabs, so they are read only.
13411341
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 -gcflags=-G=3
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 -gcflags=-G=3
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)