]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix delay transformation in *subster.node()
authorkorzhao <korzhao95@gmail.com>
Sun, 29 Aug 2021 06:36:20 +0000 (14:36 +0800)
committerDan Scales <danscales@google.com>
Mon, 6 Sep 2021 14:02:24 +0000 (14:02 +0000)
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 <khr@golang.org>
Trust: Dan Scales <danscales@google.com>
Reviewed-by: Dan Scales <danscales@google.com>
src/cmd/compile/internal/noder/stencil.go
test/typeparam/issue48042.go [new file with mode: 0644]

index 7ba266a150515c049aa2315aa3e81b22120b7d6f..3b15ac2c970c88ee8f9ffadbe7050480e51dd703 100644 (file)
@@ -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 (file)
index 0000000..db5de3d
--- /dev/null
@@ -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