mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: fix unified IR's pointer-shaping
In CL 424734, I implemented pointer shaping for unified IR. Evidently though, we didn't have any test cases that check that uses of pointer-shaped expressions were handled correctly. In the reported test case, the struct field "children items[*node[T]]" gets shaped to "children items[go.shape.*uint8]" (underlying type "[]go.shape.*uint8"); and so the expression "n.children[i]" has type "go.shape.*uint8" and the ".items" field selection expression fails. The fix implemented in this CL is that any expression of derived type now gets an explicit "reshape" operation applied to it, to ensure it has the appropriate type for its context. E.g., the "n.children[i]" OINDEX expression above gets "reshaped" from "go.shape.*uint8" to "*node[go.shape.int]", allowing the field selection to succeed. This CL also adds a "-d=reshape" compiler debugging flag, because I anticipate debugging reshaping operations will be something to come up again in the future. Fixes #54535. Change-Id: Id847bd8f51300d2491d679505ee4d2e974ca972a Reviewed-on: https://go-review.googlesource.com/c/go/+/424936 Reviewed-by: David Chase <drchase@google.com> Reviewed-by: hopehook <hopehook@qq.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
parent
0a6e1fa986
commit
6985ab27df
5 changed files with 90 additions and 1 deletions
|
|
@ -89,7 +89,7 @@ func (pr *pkgReader) newReader(k pkgbits.RelocKind, idx pkgbits.Index, marker pk
|
|||
}
|
||||
}
|
||||
|
||||
// A writer provides APIs for reading an individual element.
|
||||
// A reader provides APIs for reading an individual element.
|
||||
type reader struct {
|
||||
pkgbits.Decoder
|
||||
|
||||
|
|
@ -2367,6 +2367,41 @@ func (r *reader) expr() (res ir.Node) {
|
|||
typ := r.exprType()
|
||||
return typecheck.Expr(ir.NewUnaryExpr(pos, ir.ONEW, typ))
|
||||
|
||||
case exprReshape:
|
||||
typ := r.typ()
|
||||
x := r.expr()
|
||||
|
||||
if types.IdenticalStrict(x.Type(), typ) {
|
||||
return x
|
||||
}
|
||||
|
||||
// Comparison expressions are constructed as "untyped bool" still.
|
||||
//
|
||||
// TODO(mdempsky): It should be safe to reshape them here too, but
|
||||
// maybe it's better to construct them with the proper type
|
||||
// instead.
|
||||
if x.Type() == types.UntypedBool && typ.IsBoolean() {
|
||||
return x
|
||||
}
|
||||
|
||||
base.AssertfAt(x.Type().HasShape() || typ.HasShape(), x.Pos(), "%L and %v are not shape types", x, typ)
|
||||
base.AssertfAt(types.Identical(x.Type(), typ), x.Pos(), "%L is not shape-identical to %v", x, typ)
|
||||
|
||||
// We use ir.HasUniquePos here as a check that x only appears once
|
||||
// in the AST, so it's okay for us to call SetType without
|
||||
// breaking any other uses of it.
|
||||
//
|
||||
// Notably, any ONAMEs should already have the exactly right shape
|
||||
// type and been caught by types.IdenticalStrict above.
|
||||
base.AssertfAt(ir.HasUniquePos(x), x.Pos(), "cannot call SetType(%v) on %L", typ, x)
|
||||
|
||||
if base.Debug.Reshape != 0 {
|
||||
base.WarnfAt(x.Pos(), "reshaping %L to %v", x, typ)
|
||||
}
|
||||
|
||||
x.SetType(typ)
|
||||
return x
|
||||
|
||||
case exprConvert:
|
||||
implicit := r.Bool()
|
||||
typ := r.typ()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue