]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: treat constants to type parameter conversion as non-constant in Unified IR
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Sat, 6 Aug 2022 13:56:39 +0000 (20:56 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Mon, 8 Aug 2022 16:07:39 +0000 (16:07 +0000)
Fixes #54307

Change-Id: Idcbdb3b1cf7c7fd147cc079659f29a9b5d17e6e0
Reviewed-on: https://go-review.googlesource.com/c/go/+/421874
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Reviewed-by: David Chase <drchase@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/noder/helpers.go
src/cmd/compile/internal/noder/reader.go
src/cmd/compile/internal/noder/writer.go
test/fixedbugs/issue54307.go [new file with mode: 0644]

index 40f80ab528d247a353d997bde58be8edca906253..4c9c6f6cc9c397dba35cc737a89090691635107e 100644 (file)
@@ -251,3 +251,8 @@ func idealType(tv types2.TypeAndValue) types2.Type {
        }
        return typ
 }
+
+func isTypeParam(t types2.Type) bool {
+       _, ok := t.(*types2.TypeParam)
+       return ok
+}
index d02d05bc5d212d3ea62dd928ffccea2aa7079134..668aa201a91cb3a90af2a9cf5e9059ab3f1138f1 100644 (file)
@@ -2019,6 +2019,7 @@ func (r *reader) expr() (res ir.Node) {
                typ := r.typ()
                pos := r.pos()
                typeWord, srcRType := r.convRTTI(pos)
+               dstTypeParam := r.Bool()
                x := r.expr()
 
                // TODO(mdempsky): Stop constructing expressions of untyped type.
@@ -2034,12 +2035,21 @@ func (r *reader) expr() (res ir.Node) {
                        base.ErrorExit() // harsh, but prevents constructing invalid IR
                }
 
-               n := ir.NewConvExpr(pos, ir.OCONV, typ, x)
-               n.TypeWord, n.SrcRType = typeWord, srcRType
+               ce := ir.NewConvExpr(pos, ir.OCONV, typ, x)
+               ce.TypeWord, ce.SrcRType = typeWord, srcRType
                if implicit {
-                       n.SetImplicit(true)
+                       ce.SetImplicit(true)
                }
-               return typecheck.Expr(n)
+               n := typecheck.Expr(ce)
+
+               // spec: "If the type is a type parameter, the constant is converted
+               // into a non-constant value of the type parameter."
+               if dstTypeParam && ir.IsConstNode(n) {
+                       // Wrap in an OCONVNOP node to ensure result is non-constant.
+                       n = Implicit(ir.NewConvExpr(pos, ir.OCONVNOP, n.Type(), n))
+                       n.SetTypecheck(1)
+               }
+               return n
        }
 }
 
index 5f8767bf833d834864c5ab4b5a77508e7c93118a..deee2887e223c7dc225c99a32bce8e8b1d343fb4 100644 (file)
@@ -1692,6 +1692,7 @@ func (w *writer) expr(expr syntax.Expr) {
                        w.typ(tv.Type)
                        w.pos(expr)
                        w.convRTTI(w.p.typeOf(expr.ArgList[0]), tv.Type)
+                       w.Bool(isTypeParam(tv.Type))
                        w.expr(expr.ArgList[0])
                        break
                }
@@ -1854,6 +1855,7 @@ func (w *writer) implicitConvExpr(pos poser, dst types2.Type, expr syntax.Expr)
                w.typ(dst)
                w.pos(pos)
                w.convRTTI(src, dst)
+               w.Bool(isTypeParam(dst))
                // fallthrough
        }
        w.expr(expr)
diff --git a/test/fixedbugs/issue54307.go b/test/fixedbugs/issue54307.go
new file mode 100644 (file)
index 0000000..342a53a
--- /dev/null
@@ -0,0 +1,19 @@
+// compile
+
+// Copyright 2022 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 p
+
+func f[Int int, Uint uint]() {
+       _ = uint(Int(-1))
+       _ = uint(Uint(0) - 1)
+}
+
+func g[String string]() {
+       _ = String("")[100]
+}
+
+var _ = f[int, uint]
+var _ = g[string]