Also fixes #18687.
Change-Id: I7c6d47c71e632adf4c16937a29074621f771844c
Reviewed-on: https://go-review.googlesource.com/35261
Run-TryBot: Cherry Zhang <cherryyz@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
// cases they are also typically registerizable, so not much harm done.
// And this only applies to the multiple-assignment form.
// We could do a more precise analysis if needed, like in walk.go.
-//
-// Ordermapassign also inserts these temporaries if needed for
-// calling writebarrierfat with a pointer to n->right.
func ordermapassign(n *Node, order *Order) {
switch n.Op {
default:
case OAS:
order.out = append(order.out, n)
- // We call writebarrierfat only for values > 4 pointers long. See walk.go.
- // TODO(mdempsky): writebarrierfat doesn't exist anymore, but removing that
- // logic causes net/http's tests to become flaky; see CL 21242.
- if needwritebarrier(n.Left, n.Right) && n.Left.Type.Width > int64(4*Widthptr) && n.Right != nil && !isaddrokay(n.Right) {
- m := n.Left
- n.Left = ordertemp(m.Type, order, false)
- a := nod(OAS, m, n.Left)
- a = typecheck(a, Etop)
- order.out = append(order.out, a)
- }
-
case OAS2, OAS2DOTTYPE, OAS2MAPR, OAS2FUNC:
var post []*Node
var m *Node
case OAPPEND:
return s.append(n, false)
+ case OSTRUCTLIT, OARRAYLIT:
+ // All literals with nonzero fields have already been
+ // rewritten during walk. Any that remain are just T{}
+ // or equivalents. Use the zero value.
+ if !iszero(n) {
+ Fatalf("literal with nonzero value in SSA: %v", n)
+ }
+ return s.zeroVal(n.Type)
+
default:
s.Fatalf("unhandled expr %v", n.Op)
return nil
n = r
case OARRAYLIT, OSLICELIT, OMAPLIT, OSTRUCTLIT, OPTRLIT:
+ if n.Op == OSTRUCTLIT && iszero(n) && !instrumenting { // TODO: SSA doesn't yet handle ARRAYLIT with length > 1
+ break
+ }
if isStaticCompositeLiteral(n) {
// n can be directly represented in the read-only data section.
// Make direct reference to the static data. See issue 12841.
// Chose not to inline. Call equality function directly.
if !inline {
+ if isvaluelit(cmpl) {
+ var_ := temp(cmpl.Type)
+ anylit(cmpl, var_, init)
+ cmpl = var_
+ }
+ if isvaluelit(cmpr) {
+ var_ := temp(cmpr.Type)
+ anylit(cmpr, var_, init)
+ cmpr = var_
+ }
if !islvalue(cmpl) || !islvalue(cmpr) {
Fatalf("arguments of comparison must be lvalues - %v %v", cmpl, cmpr)
}