return m
}
+// isnil reports whether n represents the universal untyped zero value "nil".
func isnil(n *Node) bool {
- if n == nil {
- return false
- }
- if n.Op != OLITERAL {
- return false
- }
- if n.Val().Ctype() != CTNIL {
- return false
- }
- return true
+ // Check n.Orig because constant propagation may produce typed nil constants,
+ // which don't exist in the Go spec.
+ return Isconst(n.Orig, CTNIL)
}
func isptrto(t *Type, et EType) bool {
} else {
Yyerror("invalid case %v in switch (mismatched types %v and bool)", ll.N, ll.N.Type)
}
- case nilonly != "" && !Isconst(ll.N, CTNIL):
+ case nilonly != "" && !isnil(ll.N):
Yyerror("invalid case %v in switch (can only compare %s %v to nil)", ll.N, nilonly, n.Left)
}
--- /dev/null
+// errorcheck
+
+// Copyright 2015 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.
+
+// Verify that comparisons of slice/map/func values against converted nil
+// values are properly rejected.
+
+package p
+
+func bug() {
+ type S []byte
+ type M map[int]int
+ type F func()
+
+ var s S
+ var m M
+ var f F
+
+ _ = s == S(nil) // ERROR "compare.*to nil"
+ _ = S(nil) == s // ERROR "compare.*to nil"
+ switch s {
+ case S(nil): // ERROR "compare.*to nil"
+ }
+
+ _ = m == M(nil) // ERROR "compare.*to nil"
+ _ = M(nil) == m // ERROR "compare.*to nil"
+ switch m {
+ case M(nil): // ERROR "compare.*to nil"
+ }
+
+ _ = f == F(nil) // ERROR "compare.*to nil"
+ _ = F(nil) == f // ERROR "compare.*to nil"
+ switch f {
+ case F(nil): // ERROR "compare.*to nil"
+ }
+}