diff options
| author | Matthew Dempsky <mdempsky@google.com> | 2022-06-21 02:30:21 -0700 |
|---|---|---|
| committer | Matthew Dempsky <mdempsky@google.com> | 2022-06-23 21:53:09 +0000 |
| commit | 61ae2b734cdbc0db342036a2a026fe1fccdccde3 (patch) | |
| tree | f84dc5dc6bc118472573f53d0ac276ec04320f8f /src/cmd/compile/internal/noder | |
| parent | 3d432b6c4b86a5fcd1ccce0f914193b8e0e9e79e (diff) | |
| download | go-61ae2b734cdbc0db342036a2a026fe1fccdccde3.tar.xz | |
[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 <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Diffstat (limited to 'src/cmd/compile/internal/noder')
| -rw-r--r-- | src/cmd/compile/internal/noder/reader.go | 23 |
1 files changed, 22 insertions, 1 deletions
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() |
