aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDan Scales <danscales@google.com>2022-01-06 12:39:37 -0800
committerDan Scales <danscales@google.com>2022-01-07 18:40:16 +0000
commitf1596d76f488e4d82d217418df4191f34b71d117 (patch)
tree1771b8b19ecd2dd2588330fe92c88600045dc631 /src
parentade5488d75fefc4afd72f2f6090f4c823c93d083 (diff)
downloadgo-f1596d76f488e4d82d217418df4191f34b71d117.tar.gz
go-f1596d76f488e4d82d217418df4191f34b71d117.zip
cmd/compile: fix conv of slice of user-define byte type to string
types2 allows the conversion of a slice of a user-defined byte type B (not builtin uint8 or byte) to string. But runtime.slicebytetostring requires a []byte argument, so add in a CONVNOP from []B to []byte if needed. Same for the conversion of a slice of user-defined rune types to string. I made the same change in the transformations of the old typechecker, so as to keep tcConv() and transformConv() in sync. That fixes the bug for -G=0 mode as well. Fixes #23536 Change-Id: Ic79364427f27489187f3f8015bdfbf0769a70d69 Reviewed-on: https://go-review.googlesource.com/c/go/+/376056 Reviewed-by: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/noder/transform.go25
-rw-r--r--src/cmd/compile/internal/typecheck/expr.go21
2 files changed, 46 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/noder/transform.go b/src/cmd/compile/internal/noder/transform.go
index a673484821..6f49106f5e 100644
--- a/src/cmd/compile/internal/noder/transform.go
+++ b/src/cmd/compile/internal/noder/transform.go
@@ -115,6 +115,31 @@ func transformConv(n *ir.ConvExpr) ir.Node {
if n.X.Op() == ir.OLITERAL {
return stringtoruneslit(n)
}
+
+ case ir.OBYTES2STR:
+ assert(t.IsSlice())
+ assert(t.Elem().Kind() == types.TUINT8)
+ if t.Elem() != types.ByteType && t.Elem() != types.Types[types.TUINT8] {
+ // If t is a slice of a user-defined byte type B (not uint8
+ // or byte), then add an extra CONVNOP from []B to []byte, so
+ // that the call to slicebytetostring() added in walk will
+ // typecheck correctly.
+ n.X = ir.NewConvExpr(n.X.Pos(), ir.OCONVNOP, types.NewSlice(types.ByteType), n.X)
+ n.X.SetTypecheck(1)
+ }
+
+ case ir.ORUNES2STR:
+ assert(t.IsSlice())
+ assert(t.Elem().Kind() == types.TINT32)
+ if t.Elem() != types.RuneType && t.Elem() != types.Types[types.TINT32] {
+ // If t is a slice of a user-defined rune type B (not uint32
+ // or rune), then add an extra CONVNOP from []B to []rune, so
+ // that the call to slicerunetostring() added in walk will
+ // typecheck correctly.
+ n.X = ir.NewConvExpr(n.X.Pos(), ir.OCONVNOP, types.NewSlice(types.RuneType), n.X)
+ n.X.SetTypecheck(1)
+ }
+
}
return n
}
diff --git a/src/cmd/compile/internal/typecheck/expr.go b/src/cmd/compile/internal/typecheck/expr.go
index 9b74bf7a9d..eb316d33db 100644
--- a/src/cmd/compile/internal/typecheck/expr.go
+++ b/src/cmd/compile/internal/typecheck/expr.go
@@ -466,6 +466,27 @@ func tcConv(n *ir.ConvExpr) ir.Node {
if n.X.Op() == ir.OLITERAL {
return stringtoruneslit(n)
}
+
+ case ir.OBYTES2STR:
+ if t.Elem() != types.ByteType && t.Elem() != types.Types[types.TUINT8] {
+ // If t is a slice of a user-defined byte type B (not uint8
+ // or byte), then add an extra CONVNOP from []B to []byte, so
+ // that the call to slicebytetostring() added in walk will
+ // typecheck correctly.
+ n.X = ir.NewConvExpr(n.X.Pos(), ir.OCONVNOP, types.NewSlice(types.ByteType), n.X)
+ n.X.SetTypecheck(1)
+ }
+
+ case ir.ORUNES2STR:
+ if t.Elem() != types.RuneType && t.Elem() != types.Types[types.TINT32] {
+ // If t is a slice of a user-defined rune type B (not uint32
+ // or rune), then add an extra CONVNOP from []B to []rune, so
+ // that the call to slicerunetostring() added in walk will
+ // typecheck correctly.
+ n.X = ir.NewConvExpr(n.X.Pos(), ir.OCONVNOP, types.NewSlice(types.RuneType), n.X)
+ n.X.SetTypecheck(1)
+ }
+
}
return n
}