]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/gofmt: don't turn nil slices into empty slices during rewriting
authorDominik Honnef <dominik@honnef.co>
Sun, 28 Jul 2019 13:19:43 +0000 (15:19 +0200)
committerRobert Griesemer <gri@golang.org>
Wed, 11 Sep 2019 20:34:54 +0000 (20:34 +0000)
The go/ast package uses and guarantees nil slices for optional
elements that weren't present in the parsed source code, such as the
list of return values of a function. Packages using go/ast rely on
this attribute and check for nils explicitly.

One such package is go/printer. In the presence of empty slices
instead of nil slices, it generates invalid code, such as "case :"
instead of "default:". The issues that this CL fixes are all
manifestations of that problem, each for a different syntactic
element.

Fixes #33103
Fixes #33104
Fixes #33105

Change-Id: I219f95a7da820eaf697a4ee227d458ab6e4a80bd
Reviewed-on: https://go-review.googlesource.com/c/go/+/187917
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Robert Griesemer <gri@golang.org>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/gofmt/rewrite.go
src/cmd/gofmt/testdata/rewrite10.golden [new file with mode: 0644]
src/cmd/gofmt/testdata/rewrite10.input [new file with mode: 0644]

index 79b7858a5afd06be14152efdc3cf9d12a4fa1887..bab22e04cdac00284170d792fa7a4812ff769e9d 100644 (file)
@@ -271,6 +271,12 @@ func subst(m map[string]reflect.Value, pattern reflect.Value, pos reflect.Value)
        // Otherwise copy.
        switch p := pattern; p.Kind() {
        case reflect.Slice:
+               if p.IsNil() {
+                       // Do not turn nil slices into empty slices. go/ast
+                       // guarantees that certain lists will be nil if not
+                       // populated.
+                       return reflect.Zero(p.Type())
+               }
                v := reflect.MakeSlice(p.Type(), p.Len(), p.Len())
                for i := 0; i < p.Len(); i++ {
                        v.Index(i).Set(subst(m, p.Index(i), pos))
diff --git a/src/cmd/gofmt/testdata/rewrite10.golden b/src/cmd/gofmt/testdata/rewrite10.golden
new file mode 100644 (file)
index 0000000..1dd781f
--- /dev/null
@@ -0,0 +1,19 @@
+//gofmt -r=a->a
+
+// Copyright 2019 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.
+
+// Issue 33103, 33104, and 33105.
+
+package pkg
+
+func fn() {
+       _ = func() {
+               switch {
+               default:
+               }
+       }
+       _ = func() string {}
+       _ = func() { var ptr *string; println(ptr) }
+}
diff --git a/src/cmd/gofmt/testdata/rewrite10.input b/src/cmd/gofmt/testdata/rewrite10.input
new file mode 100644 (file)
index 0000000..1dd781f
--- /dev/null
@@ -0,0 +1,19 @@
+//gofmt -r=a->a
+
+// Copyright 2019 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.
+
+// Issue 33103, 33104, and 33105.
+
+package pkg
+
+func fn() {
+       _ = func() {
+               switch {
+               default:
+               }
+       }
+       _ = func() string {}
+       _ = func() { var ptr *string; println(ptr) }
+}