]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: disallow typed non-integer constant len and cap make arguments
authorMartin Möhrmann <martisch@uos.de>
Thu, 1 Sep 2016 06:31:37 +0000 (08:31 +0200)
committerMartin Möhrmann <martisch@uos.de>
Thu, 1 Sep 2016 20:29:03 +0000 (20:29 +0000)
make(T, n, m) returns a slice of type T with length n and capacity m
where "The size arguments n and m must be of integer type or untyped."
https://tip.golang.org/ref/spec#Making_slices_maps_and_channels

The failure to reject typed non-integer size arguments in make
during compile time was uncovered after https://golang.org/cl/27851
changed the generation of makeslice calls.

Fixes   #16940
Updates #16949

Change-Id: Ib1e3576f0e6ad199c9b16b7a50c2db81290c63b4
Reviewed-on: https://go-review.googlesource.com/28301
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
src/cmd/compile/internal/gc/typecheck.go
test/fixedbugs/issue16949.go [new file with mode: 0644]

index d08f52e5c542113446873ea16e05c45bf841f797..df527a5036946b6a4c42b3890718f1e358aeb503 100644 (file)
@@ -3754,6 +3754,11 @@ ret:
 }
 
 func checkmake(t *Type, arg string, n *Node) bool {
+       if !n.Type.IsInteger() && n.Type.Etype != TIDEAL {
+               Yyerror("non-integer %s argument in make(%v) - %v", arg, t, n.Type)
+               return false
+       }
+
        if n.Op == OLITERAL {
                switch n.Val().Ctype() {
                case CTINT, CTRUNE, CTFLT, CTCPLX:
@@ -3779,11 +3784,6 @@ func checkmake(t *Type, arg string, n *Node) bool {
                }
        }
 
-       if !n.Type.IsInteger() && n.Type.Etype != TIDEAL {
-               Yyerror("non-integer %s argument in make(%v) - %v", arg, t, n.Type)
-               return false
-       }
-
        // Defaultlit still necessary for non-constant: n might be 1<<k.
        n = defaultlit(n, Types[TINT])
 
diff --git a/test/fixedbugs/issue16949.go b/test/fixedbugs/issue16949.go
new file mode 100644 (file)
index 0000000..9ee3387
--- /dev/null
@@ -0,0 +1,30 @@
+// errorcheck
+
+// Copyright 2016 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.
+
+// Ensure that typed non-integer len and cap make arguments are not accepted.
+
+package main
+
+var sink []byte
+
+func main() {
+       sink = make([]byte, 1.0)
+       sink = make([]byte, float32(1.0)) // ERROR "non-integer.*len"
+       sink = make([]byte, float64(1.0)) // ERROR "non-integer.*len"
+
+       sink = make([]byte, 0, 1.0)
+       sink = make([]byte, 0, float32(1.0)) // ERROR "non-integer.*cap"
+       sink = make([]byte, 0, float64(1.0)) // ERROR "non-integer.*cap"
+
+       sink = make([]byte, 1+0i)
+       sink = make([]byte, complex64(1+0i))  // ERROR "non-integer.*len"
+       sink = make([]byte, complex128(1+0i)) // ERROR "non-integer.*len"
+
+       sink = make([]byte, 0, 1+0i)
+       sink = make([]byte, 0, complex64(1+0i))  // ERROR "non-integer.*cap"
+       sink = make([]byte, 0, complex128(1+0i)) // ERROR "non-integer.*cap"
+
+}