]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix isStaticCompositeLiteral
authorJosh Bleecher Snyder <josharian@gmail.com>
Tue, 19 Apr 2016 19:08:33 +0000 (12:08 -0700)
committerJosh Bleecher Snyder <josharian@gmail.com>
Tue, 19 Apr 2016 20:55:41 +0000 (20:55 +0000)
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>
src/cmd/compile/internal/gc/sinit.go
src/cmd/compile/internal/gc/walk.go

index 1021609d3a1f6e460f56a4e7033b70134b8eca37..5a3a4dbe7f93f49430f446aec5b52a826917548e 100644 (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() {
index 1a15bd93d0c2b30b21e309e88c273f19930fd151..e4d93339a923bcd10c3605763755098c5b14009a 100644 (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)