1
0
mirror of https://github.com/golang/go synced 2024-07-08 12:18:55 +00:00

cmd/compile: mark type descriptors as always dupok

The types of the two interfaces should be equal, but they aren't.
We end up with multiple descriptors for a type when we need type
descriptors to be unique.

Fixes #49241

Change-Id: I8a6c70da541c6088a92a01392bc83b61cc130eba
Reviewed-on: https://go-review.googlesource.com/c/go/+/360134
Trust: Keith Randall <khr@golang.org>
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Keith Randall 2021-10-30 14:39:29 -07:00
parent f7a95d2c17
commit 79c5240799
6 changed files with 78 additions and 6 deletions

View File

@ -959,11 +959,6 @@ func writeType(t *types.Type) *obj.LSym {
base.Fatalf("unresolved defined type: %v", tbase)
}
dupok := 0
if tbase.Sym() == nil || tbase.HasShape() { // TODO(mdempsky): Probably need DUPOK for instantiated types too.
dupok = obj.DUPOK
}
if !NeedEmit(tbase) {
if i := typecheck.BaseTypeIndex(t); i >= 0 {
lsym.Pkg = tbase.Sym().Pkg.Prefix
@ -1196,7 +1191,9 @@ func writeType(t *types.Type) *obj.LSym {
}
ot = dextratypeData(lsym, ot, t)
objw.Global(lsym, int32(ot), int16(dupok|obj.RODATA))
objw.Global(lsym, int32(ot), int16(obj.DUPOK|obj.RODATA))
// Note: DUPOK is required to ensure that we don't end up with more
// than one type descriptor for a given type.
// The linker will leave a table of all the typelinks for
// types in the binary, so the runtime can find them.

View 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 a
type T[P any] struct {
x P
}
type U struct {
a,b int
}

View File

@ -0,0 +1,17 @@
// 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
import "a"
//go:noinline
func F() interface {} {
return a.T[int]{}
}
//go:noinline
func G() interface{} {
return struct{X,Y a.U}{}
}

View File

@ -0,0 +1,17 @@
// 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"
//go:noinline
func F() interface {} {
return a.T[int]{}
}
//go:noinline
func G() interface{} {
return struct{X,Y a.U}{}
}

View File

@ -0,0 +1,21 @@
// 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 main
import (
"b"
"c"
)
func main() {
if b.G() != c.G() {
println(b.G(), c.G())
panic("bad")
}
if b.F() != c.F() {
println(b.F(), c.F())
panic("bad")
}
}

View File

@ -0,0 +1,7 @@
// rundir -G=3
// 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