From 61ae2b734cdbc0db342036a2a026fe1fccdccde3 Mon Sep 17 00:00:00 2001 From: Matthew Dempsky Date: Tue, 21 Jun 2022 02:30:21 -0700 Subject: [dev.unified] cmd/compile: plumb rtype through OSWITCH/OCASE clauses For (value) switch statements, we may generate OEQ comparisons between values of interface and concrete type, which in turn may require access to the concrete type's RType. To plumb this through, this CL adds CaseClause.RTypes to hold the rtype values, updates the GOEXPERIMENT=unified frontend to set it, and updates walk to plumb rtypes through into generated OEQ nodes. Change-Id: I6f1de2a1167ce54f5770147498a0a591efb3f012 Reviewed-on: https://go-review.googlesource.com/c/go/+/413361 Reviewed-by: Keith Randall Reviewed-by: David Chase Run-TryBot: Matthew Dempsky TryBot-Result: Gopher Robot --- src/cmd/compile/internal/noder/reader.go | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'src/cmd/compile/internal/noder/reader.go') diff --git a/src/cmd/compile/internal/noder/reader.go b/src/cmd/compile/internal/noder/reader.go index 32276e7553..aa2cccf86b 100644 --- a/src/cmd/compile/internal/noder/reader.go +++ b/src/cmd/compile/internal/noder/reader.go @@ -1487,7 +1487,7 @@ func (r *reader) switchStmt(label *types.Sym) ir.Node { r.openScope() pos := r.pos() - var cases []ir.Node + var cases, rtypes []ir.Node if iface != nil { cases = make([]ir.Node, r.Len()) if len(cases) == 0 { @@ -1498,9 +1498,30 @@ func (r *reader) switchStmt(label *types.Sym) ir.Node { } } else { cases = r.exprList() + + tagType := types.Types[types.TBOOL] + if tag != nil { + tagType = tag.Type() + } + for i, cas := range cases { + if cas.Op() == ir.ONIL { + continue // never needs rtype + } + if tagType.IsInterface() != cas.Type().IsInterface() { + typ := tagType + if typ.IsInterface() { + typ = cas.Type() + } + for len(rtypes) < i { + rtypes = append(rtypes, nil) + } + rtypes = append(rtypes, reflectdata.TypePtr(typ)) + } + } } clause := ir.NewCaseStmt(pos, cases, nil) + clause.RTypes = rtypes if ident != nil { pos := r.pos() -- cgit v1.3