1
0
mirror of https://github.com/golang/go synced 2024-11-26 04:37:59 -07:00

cmd/compile: another fix initializing blank fields in struct literal

CL 230121 fixed the bug that struct literal blank fields type array/struct
can not be initialized. But it still misses some cases when an expression
causes "candiscard(value)" return false. When these happen, we recursively
call fixedlit with "var_" set to "_", and hit the bug again.

To fix it, just making splitnode return "nblank" whenever "var_" is "nblank".

Fixes #38905

Change-Id: I281941b388acbd551a4d8ca1a235477f8d26fb6e
Reviewed-on: https://go-review.googlesource.com/c/go/+/232617
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Cuong Manh Le 2020-05-07 00:35:28 +07:00
parent 441b52f566
commit 0031fa80a3
2 changed files with 23 additions and 1 deletions

View File

@ -506,6 +506,7 @@ const (
// fixedlit handles struct, array, and slice literals.
// TODO: expand documentation.
func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes) {
isBlank := var_ == nblank
var splitnode func(*Node) (a *Node, value *Node)
switch n.Op {
case OARRAYLIT, OSLICELIT:
@ -520,6 +521,9 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes)
}
a := nod(OINDEX, var_, nodintconst(k))
k++
if isBlank {
a = nblank
}
return a, r
}
case OSTRUCTLIT:
@ -527,7 +531,7 @@ func fixedlit(ctxt initContext, kind initKind, n *Node, var_ *Node, init *Nodes)
if r.Op != OSTRUCTKEY {
Fatalf("fixedlit: rhs not OSTRUCTKEY: %v", r)
}
if r.Sym.IsBlank() {
if r.Sym.IsBlank() || isBlank {
return nblank, r.Left
}
setlineno(r)

View File

@ -0,0 +1,18 @@
// compile
// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Make sure that literal value can be passed to struct
// blank field with expressions where candiscard(value)
// returns false, see #38905.
package p
type t struct{ _ u }
type u [10]struct{ f int }
func f(x int) t { return t{u{{1 / x}, {1 % x}}} }
func g(p *int) t { return t{u{{*p}}} }
func h(s []int) t { return t{u{{s[0]}}} }