1
0
mirror of https://github.com/golang/go synced 2024-11-20 00:34:43 -07:00

cmd/compile: fix isStaticCompositeLiteral

Previously, isStaticCompositeLiteral would
return the wrong value for literals like:

[1]struct{ b []byte }{b: []byte{1}}

Note that the outermost component is an array,
but once we recurse into isStaticCompositeLiteral,
we never check again that arrays are actually arrays.

Instead of adding more logic to the guts of
isStaticCompositeLiteral, allow it to accept
any Node and return the correct answer.

Change-Id: I6af7814a9037bbc7043da9a96137fbee067bbe0e
Reviewed-on: https://go-review.googlesource.com/22247
Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
Josh Bleecher Snyder 2016-04-19 12:08:33 -07:00
parent 562d398aef
commit 3c6e60c0e4
2 changed files with 15 additions and 12 deletions

View File

@ -564,8 +564,18 @@ func getdyn(n *Node, top int) initGenType {
}
// isStaticCompositeLiteral reports whether n is a compile-time constant.
// n must be a struct or array literal.
func isStaticCompositeLiteral(n *Node) bool {
switch n.Op {
case OARRAYLIT:
if n.Type.IsSlice() {
return false
}
case OSTRUCTLIT:
case OLITERAL:
return true
default:
return false
}
for _, r := range n.List.Slice() {
if r.Op != OKEY {
Fatalf("isStaticCompositeLiteral: rhs not OKEY: %v", r)
@ -575,15 +585,8 @@ func isStaticCompositeLiteral(n *Node) bool {
return false
}
value := r.Right
switch value.Op {
case OSTRUCTLIT, OARRAYLIT:
if !isStaticCompositeLiteral(value) {
return false
}
default:
if value.Op != OLITERAL {
return false
}
if !isStaticCompositeLiteral(value) {
return false
}
}
return true
@ -1031,7 +1034,7 @@ func anylit(ctxt int, n *Node, var_ *Node, init *Nodes) {
t := n.Type
switch n.Op {
default:
Fatalf("anylit: not lit")
Fatalf("anylit: not lit, op=%v node=%v", opnames[n.Op], n)
case OPTRLIT:
if !t.IsPtr() {

View File

@ -1531,7 +1531,7 @@ opswitch:
n = r
case OARRAYLIT, OMAPLIT, OSTRUCTLIT, OPTRLIT:
if (n.Op == OSTRUCTLIT || (n.Op == OARRAYLIT && !n.Type.IsSlice())) && isStaticCompositeLiteral(n) {
if isStaticCompositeLiteral(n) {
// n can be directly represented in the read-only data section.
// Make direct reference to the static data. See issue 12841.
vstat := staticname(n.Type, 0)