From: korzhao Date: Sun, 29 Aug 2021 06:36:20 +0000 (+0800) Subject: cmd/compile: fix delay transformation in *subster.node() X-Git-Tag: go1.18beta1~1470 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=ecfff58fb8c3aabbce7b15c850210485c1f09d61;p=gostls13.git cmd/compile: fix delay transformation in *subster.node() Add OCALL, OCALLFUNC, OCALLMETH, OCALLINTER, ODYNAMICDOTTYPE transformations to the CALL check switch statement. Fixes #48042 Change-Id: Ied93efd979c5b2c56b72fad26fccfd9f887361d3 Reviewed-on: https://go-review.googlesource.com/c/go/+/345949 Trust: Keith Randall Trust: Dan Scales Reviewed-by: Dan Scales --- diff --git a/src/cmd/compile/internal/noder/stencil.go b/src/cmd/compile/internal/noder/stencil.go index 7ba266a150..3b15ac2c97 100644 --- a/src/cmd/compile/internal/noder/stencil.go +++ b/src/cmd/compile/internal/noder/stencil.go @@ -1095,6 +1095,9 @@ func (subst *subster) node(n ir.Node) ir.Node { // or channel receive to compute function value. transformCall(call) + case ir.OCALL, ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER, ir.ODYNAMICDOTTYPE: + transformCall(call) + case ir.OFUNCINST: // A call with an OFUNCINST will get transformed // in stencil() once we have created & attached the diff --git a/test/typeparam/issue48042.go b/test/typeparam/issue48042.go new file mode 100644 index 0000000000..db5de3d8fa --- /dev/null +++ b/test/typeparam/issue48042.go @@ -0,0 +1,77 @@ +// run -gcflags=-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 main + +import ( + "fmt" + "reflect" +) + +type G[T any] interface { + g() func()(*T) +} +type Foo[T any] struct { + +} +// OCALL +func (l *Foo[T]) f1() (*T) { + return g[T]()() +} +// OCALLFUNC +func (l *Foo[T]) f2() (*T) { + var f = g[T] + return f()() +} +// OCALLMETH +func (l *Foo[T]) f3() (*T) { + return l.g()() +} +// OCALLINTER +func (l *Foo[T]) f4() (*T) { + var g G[T] = l + return g.g()() +} +// ODYNAMICDOTTYPE +func (l *Foo[T]) f5() (*T) { + var x interface{} + x = g[T] + return x.(func()func()(*T))()() +} +func (l *Foo[T]) g() func() (*T) { + return func() (*T) { + t := new(T) + reflect.ValueOf(t).Elem().SetInt(100) + return t + } +} +func g[T any]() func() (*T) { + return func() (*T) { + t := new(T) + reflect.ValueOf(t).Elem().SetInt(100) + return t + } +} + +func main() { + foo := Foo[int]{} + // Make sure the function conversion is correct + if n := *(foo.f1()) ; n != 100{ + panic(fmt.Sprintf("%v",n)) + } + if n := *(foo.f2()) ; n != 100{ + panic(fmt.Sprintf("%v",n)) + } + if n := *(foo.f3()) ; n != 100{ + panic(fmt.Sprintf("%v",n)) + } + if n := *(foo.f4()) ; n != 100{ + panic(fmt.Sprintf("%v",n)) + } + if n := *(foo.f5()) ; n != 100{ + panic(fmt.Sprintf("%v",n)) + } +} \ No newline at end of file