components/golang/patches/0032-release-branch.go1.5-cmd-compile-internal-gc-handle-.patch
changeset 5331 9c955076ffe3
equal deleted inserted replaced
5330:c36e3195e3e9 5331:9c955076ffe3
       
     1 From 095710b39ec15e4df62eab0781a9d685dbe575a5 Mon Sep 17 00:00:00 2001
       
     2 From: Keith Randall <[email protected]>
       
     3 Date: Tue, 8 Sep 2015 13:41:51 -0700
       
     4 Subject: [PATCH 32/63] [release-branch.go1.5] cmd/compile/internal/gc: handle
       
     5  weird map literals in key dedup
       
     6 
       
     7 We compute whether two keys k1 and k2 in a map literal are duplicates by
       
     8 constructing the expression OEQ(k1, k2) and calling the constant
       
     9 expression evaluator on that expression, then extracting the boolean
       
    10 result.
       
    11 
       
    12 Unfortunately, the constant expression evaluator can fail for various
       
    13 reasons.  I'm not really sure why it is dying in the case of 12536, but
       
    14 to be safe we should use the result only if we get a constant back (if
       
    15 we get a constant back, it must be boolean).  This probably isn't a
       
    16 permanent fix, but it should be good enough for 1.5.2.
       
    17 
       
    18 A permanent fix would be to ensure that the constant expression
       
    19 evaluator can always work for map literal keys, and if not the compiler
       
    20 should generate an error saying that the key isn't a constant (or isn't
       
    21 comparable to some specific other key).
       
    22 
       
    23 This patch has the effect of allowing the map literal to compile when
       
    24 constant eval of the OEQ fails.  If the keys are really equal (which the
       
    25 map impl will notice at runtime), one will overwrite the other in the
       
    26 resulting map.  Not great, but better than a compiler crash.
       
    27 
       
    28 Fixes #12536
       
    29 
       
    30 Change-Id: Ic151a5e3f131c2e8efa0c25c9218b431c55c1b30
       
    31 Reviewed-on: https://go-review.googlesource.com/14400
       
    32 Reviewed-by: Ian Lance Taylor <[email protected]>
       
    33 Reviewed-on: https://go-review.googlesource.com/16965
       
    34 Run-TryBot: Austin Clements <[email protected]>
       
    35 Reviewed-by: Russ Cox <[email protected]>
       
    36 ---
       
    37  src/cmd/compile/internal/gc/typecheck.go | 9 +++++++--
       
    38  1 file changed, 7 insertions(+), 2 deletions(-)
       
    39 
       
    40 diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go
       
    41 index befe3b2..e5ae967 100644
       
    42 --- a/src/cmd/compile/internal/gc/typecheck.go
       
    43 +++ b/src/cmd/compile/internal/gc/typecheck.go
       
    44 @@ -2874,12 +2874,17 @@ func keydup(n *Node, hash map[uint32][]*Node) {
       
    45  			if Eqtype(a.Left.Type, n.Type) {
       
    46  				cmp.Right = a.Left
       
    47  				evconst(&cmp)
       
    48 -				b = uint32(obj.Bool2int(cmp.Val().U.(bool)))
       
    49 +				if cmp.Op == OLITERAL {
       
    50 +					// Sometimes evconst fails.  See issue 12536.
       
    51 +					b = uint32(obj.Bool2int(cmp.Val().U.(bool)))
       
    52 +				}
       
    53  			}
       
    54  		} else if Eqtype(a.Type, n.Type) {
       
    55  			cmp.Right = a
       
    56  			evconst(&cmp)
       
    57 -			b = uint32(obj.Bool2int(cmp.Val().U.(bool)))
       
    58 +			if cmp.Op == OLITERAL {
       
    59 +				b = uint32(obj.Bool2int(cmp.Val().U.(bool)))
       
    60 +			}
       
    61  		}
       
    62  
       
    63  		if b != 0 {
       
    64 -- 
       
    65 2.6.1
       
    66