1
0
mirror of https://github.com/golang/go synced 2024-09-23 17:20:13 -06:00

[dev.regabi] cmd/compile: address some ir TODOs

Previously, ODOTTYPE/ODOTTYPE2 were forced to reuse some available
Node fields for storing pointers to runtime type descriptors. This
resulted in awkward field types for TypeAssertExpr and AddrExpr.

This CL gives TypeAssertExpr proper fields for the runtime type
descriptors, and also tightens the field types as
possible/appropriate.

Passes toolstash -cmp.

Change-Id: I521ee7a1462affc5459de33a0de6c68a7d6416ba
Reviewed-on: https://go-review.googlesource.com/c/go/+/280637
Trust: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dan Scales <danscales@google.com>
This commit is contained in:
Matthew Dempsky 2020-12-28 17:06:43 -08:00
parent 4629f6a51d
commit 6acbae4fcc
5 changed files with 18 additions and 17 deletions

View File

@ -109,7 +109,7 @@ func NewAddStringExpr(pos src.XPos, list []Node) *AddStringExpr {
type AddrExpr struct { type AddrExpr struct {
miniExpr miniExpr
X Node X Node
Alloc Node // preallocated storage if any Alloc *Name // preallocated storage if any
} }
func NewAddrExpr(pos src.XPos, x Node) *AddrExpr { func NewAddrExpr(pos src.XPos, x Node) *AddrExpr {
@ -660,8 +660,13 @@ func (n *StarExpr) SetOTYPE(t *types.Type) {
type TypeAssertExpr struct { type TypeAssertExpr struct {
miniExpr miniExpr
X Node X Node
Ntype Node // TODO: Should be Ntype, but reused as address of type structure Ntype Ntype
Itab Nodes // Itab[0] is itab
// Runtime type information provided by walkDotType.
// Caution: These aren't always populated; see walkDotType.
SrcType *AddrExpr // *runtime._type for X's type
DstType *AddrExpr // *runtime._type for Type
Itab *AddrExpr // *runtime.itab for Type implementing X's type
} }
func NewTypeAssertExpr(pos src.XPos, x Node, typ Ntype) *TypeAssertExpr { func NewTypeAssertExpr(pos src.XPos, x Node, typ Ntype) *TypeAssertExpr {

View File

@ -32,13 +32,11 @@ func (n *AddrExpr) doChildren(do func(Node) error) error {
var err error var err error
err = maybeDoList(n.init, err, do) err = maybeDoList(n.init, err, do)
err = maybeDo(n.X, err, do) err = maybeDo(n.X, err, do)
err = maybeDo(n.Alloc, err, do)
return err return err
} }
func (n *AddrExpr) editChildren(edit func(Node) Node) { func (n *AddrExpr) editChildren(edit func(Node) Node) {
editList(n.init, edit) editList(n.init, edit)
n.X = maybeEdit(n.X, edit) n.X = maybeEdit(n.X, edit)
n.Alloc = maybeEdit(n.Alloc, edit)
} }
func (n *ArrayType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) } func (n *ArrayType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
@ -954,7 +952,6 @@ func (n *TypeAssertExpr) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
func (n *TypeAssertExpr) copy() Node { func (n *TypeAssertExpr) copy() Node {
c := *n c := *n
c.init = c.init.Copy() c.init = c.init.Copy()
c.Itab = c.Itab.Copy()
return &c return &c
} }
func (n *TypeAssertExpr) doChildren(do func(Node) error) error { func (n *TypeAssertExpr) doChildren(do func(Node) error) error {
@ -962,14 +959,12 @@ func (n *TypeAssertExpr) doChildren(do func(Node) error) error {
err = maybeDoList(n.init, err, do) err = maybeDoList(n.init, err, do)
err = maybeDo(n.X, err, do) err = maybeDo(n.X, err, do)
err = maybeDo(n.Ntype, err, do) err = maybeDo(n.Ntype, err, do)
err = maybeDoList(n.Itab, err, do)
return err return err
} }
func (n *TypeAssertExpr) editChildren(edit func(Node) Node) { func (n *TypeAssertExpr) editChildren(edit func(Node) Node) {
editList(n.init, edit) editList(n.init, edit)
n.X = maybeEdit(n.X, edit) n.X = maybeEdit(n.X, edit)
n.Ntype = maybeEdit(n.Ntype, edit) n.Ntype = toNtype(maybeEdit(n.Ntype, edit))
editList(n.Itab, edit)
} }
func (n *TypeSwitchGuard) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) } func (n *TypeSwitchGuard) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }

View File

@ -5978,8 +5978,8 @@ func (s *state) floatToUint(cvttab *f2uCvtTab, n ir.Node, x *ssa.Value, ft, tt *
// commaok indicates whether to panic or return a bool. // commaok indicates whether to panic or return a bool.
// If commaok is false, resok will be nil. // If commaok is false, resok will be nil.
func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res, resok *ssa.Value) { func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res, resok *ssa.Value) {
iface := s.expr(n.X) // input interface iface := s.expr(n.X) // input interface
target := s.expr(n.Ntype) // target type target := s.expr(n.DstType) // target type
byteptr := s.f.Config.Types.BytePtr byteptr := s.f.Config.Types.BytePtr
if n.Type().IsInterface() { if n.Type().IsInterface() {
@ -6086,7 +6086,7 @@ func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res, resok *ssa.Val
targetITab = target targetITab = target
} else { } else {
// Looking for pointer to itab for target type and source interface. // Looking for pointer to itab for target type and source interface.
targetITab = s.expr(n.Itab[0]) targetITab = s.expr(n.Itab)
} }
var tmp ir.Node // temporary for use with large types var tmp ir.Node // temporary for use with large types
@ -6113,7 +6113,7 @@ func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res, resok *ssa.Val
if !commaok { if !commaok {
// on failure, panic by calling panicdottype // on failure, panic by calling panicdottype
s.startBlock(bFail) s.startBlock(bFail)
taddr := s.expr(n.Ntype.(*ir.AddrExpr).Alloc) taddr := s.expr(n.SrcType)
if n.X.Type().IsEmptyInterface() { if n.X.Type().IsEmptyInterface() {
s.rtcall(ir.Syms.PanicdottypeE, false, nil, itab, target, taddr) s.rtcall(ir.Syms.PanicdottypeE, false, nil, itab, target, taddr)
} else { } else {

View File

@ -649,7 +649,7 @@ func tcDotType(n *ir.TypeAssertExpr) ir.Node {
} }
if n.Ntype != nil { if n.Ntype != nil {
n.Ntype = typecheck(n.Ntype, ctxType) n.Ntype = typecheckNtype(n.Ntype)
n.SetType(n.Ntype.Type()) n.SetType(n.Ntype.Type())
n.Ntype = nil n.Ntype = nil
if n.Type() == nil { if n.Type() == nil {

View File

@ -639,12 +639,13 @@ func walkDot(n *ir.SelectorExpr, init *ir.Nodes) ir.Node {
func walkDotType(n *ir.TypeAssertExpr, init *ir.Nodes) ir.Node { func walkDotType(n *ir.TypeAssertExpr, init *ir.Nodes) ir.Node {
n.X = walkExpr(n.X, init) n.X = walkExpr(n.X, init)
// Set up interface type addresses for back end. // Set up interface type addresses for back end.
n.Ntype = reflectdata.TypePtr(n.Type())
n.DstType = reflectdata.TypePtr(n.Type())
if n.Op() == ir.ODOTTYPE { if n.Op() == ir.ODOTTYPE {
n.Ntype.(*ir.AddrExpr).Alloc = reflectdata.TypePtr(n.X.Type()) n.SrcType = reflectdata.TypePtr(n.X.Type())
} }
if !n.Type().IsInterface() && !n.X.Type().IsEmptyInterface() { if !n.Type().IsInterface() && !n.X.Type().IsEmptyInterface() {
n.Itab = []ir.Node{reflectdata.ITabAddr(n.Type(), n.X.Type())} n.Itab = reflectdata.ITabAddr(n.Type(), n.X.Type())
} }
return n return n
} }