]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gc: synthesize zeroed value for non-assignment context
authorRuss Cox <rsc@golang.org>
Fri, 24 Oct 2014 14:27:39 +0000 (10:27 -0400)
committerRuss Cox <rsc@golang.org>
Fri, 24 Oct 2014 14:27:39 +0000 (10:27 -0400)
CL 157910047 introduced code to turn a node representing
a zeroed composite literal into N, the nil Node* pointer
(which represents any zero, not the Go literal nil).

That's great for assignments like x = T{}, but it doesn't work
when T{} is used in a value context like T{}.v or x == T{}.
Fix those.

Should have no effect on performance; confirmed.
The deltas below are noise (compare ns/op):

benchmark                          old ns/op      new ns/op      delta
BenchmarkBinaryTree17              2902919192     2915228424     +0.42%
BenchmarkFannkuch11                2597417605     2630363685     +1.27%
BenchmarkFmtFprintfEmpty           73.7           74.8           +1.49%
BenchmarkFmtFprintfString          196            199            +1.53%
BenchmarkFmtFprintfInt             213            217            +1.88%
BenchmarkFmtFprintfIntInt          336            356            +5.95%
BenchmarkFmtFprintfPrefixedInt     289            294            +1.73%
BenchmarkFmtFprintfFloat           415            416            +0.24%
BenchmarkFmtManyArgs               1281           1271           -0.78%
BenchmarkGobDecode                 10271734       10307978       +0.35%
BenchmarkGobEncode                 8985021        9079442        +1.05%
BenchmarkGzip                      410233227      412266944      +0.50%
BenchmarkGunzip                    102114554      103272443      +1.13%
BenchmarkHTTPClientServer          45297          44993          -0.67%
BenchmarkJSONEncode                19499741       19498489       -0.01%
BenchmarkJSONDecode                76436733       74247497       -2.86%
BenchmarkMandelbrot200             4273814        4307292        +0.78%
BenchmarkGoParse                   4024594        4028937        +0.11%
BenchmarkRegexpMatchEasy0_32       131            135            +3.05%
BenchmarkRegexpMatchEasy0_1K       328            333            +1.52%
BenchmarkRegexpMatchEasy1_32       115            117            +1.74%
BenchmarkRegexpMatchEasy1_1K       931            948            +1.83%
BenchmarkRegexpMatchMedium_32      216            217            +0.46%
BenchmarkRegexpMatchMedium_1K      72669          72857          +0.26%
BenchmarkRegexpMatchHard_32        3818           3809           -0.24%
BenchmarkRegexpMatchHard_1K        121398         121945         +0.45%
BenchmarkRevcomp                   613996550      615145436      +0.19%
BenchmarkTemplate                  93678525       93267391       -0.44%
BenchmarkTimeParse                 414            411            -0.72%
BenchmarkTimeFormat                396            399            +0.76%

Fixes #8947.

LGTM=r
R=r, dave
CC=golang-codereviews
https://golang.org/cl/162130043

src/cmd/gc/walk.c
test/fixedbugs/issue8947.go [new file with mode: 0644]

index 7649728d37ed5b642692d980f1f483635f8b9e5c..b761662d143551db25b7aaffee0b09e36dc7bd1d 100644 (file)
@@ -614,7 +614,7 @@ walkexpr(Node **np, NodeList **init)
                if(oaslit(n, init))
                        goto ret;
 
-               if(n->right == N)
+               if(n->right == N || iszero(n->right) && !flag_race)
                        goto ret;
 
                switch(n->right->op) {
@@ -1390,12 +1390,6 @@ walkexpr(Node **np, NodeList **init)
        case OMAPLIT:
        case OSTRUCTLIT:
        case OPTRLIT:
-               // NOTE(rsc): Race detector cannot handle seeing
-               // a STRUCTLIT or ARRAYLIT representing a zero value,
-               // so make a temporary for those always in race mode.
-               // Otherwise, leave zero values in place.
-               if(iszero(n) && !flag_race)
-                       goto ret;
                var = temp(n->type);
                anylit(0, n, var, init);
                n = var;
diff --git a/test/fixedbugs/issue8947.go b/test/fixedbugs/issue8947.go
new file mode 100644 (file)
index 0000000..f40c02e
--- /dev/null
@@ -0,0 +1,53 @@
+// run
+
+// Copyright 2014 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.
+
+// Some uses of zeroed constants in non-assignment
+// expressions broke with our more aggressive zeroing
+// of assignments (internal compiler errors).
+
+package main
+
+func f1() {
+       type T [2]int
+       p := T{0, 1}
+       switch p {
+       case T{0, 0}:
+               panic("wrong1")
+       case T{0, 1}:
+               // ok
+       default:
+               panic("wrong2")
+       }
+
+       if p == (T{0, 0}) {
+               panic("wrong3")
+       } else if p == (T{0, 1}) {
+               // ok
+       } else {
+               panic("wrong4")
+       }
+}
+
+type T struct {
+       V int
+}
+
+var X = T{}.V
+
+func f2() {
+       var x = T{}.V
+       if x != 0 {
+               panic("wrongx")
+       }
+       if X != 0 {
+               panic("wrongX")
+       }
+}
+
+func main() {
+       f1()
+       f2()
+}