}
return true
- case OCONV:
+ case OCONV, OCONVNOP:
if okforconst[n.Type.Etype] && n.Left.isGoConst() {
return true
}
seen := make(map[typeVal]*Node)
for _, ncase := range clauses {
for _, n := range ncase.List.Slice() {
- if ct := consttype(n); ct == 0 || ct == CTBOOL {
+ if ct := consttype(n); ct == 0 || ct == CTBOOL || ct == CTNIL {
continue
}
tv := typeVal{
switch n.Op {
case OCONVNOP:
- if n.Left.Op == OLITERAL {
- n.Op = OCONV
- setconst(n, n.Left.Val())
+ if n.Left.Op == OLITERAL && n.isGoConst() {
+ n.Op = OCONV // set so n.Orig gets OCONV instead of OCONVNOP
+ setconst(n, n.Left.Val()) // convert n to OLITERAL with the given value
} else if t.Etype == n.Type.Etype {
switch t.Etype {
case TFLOAT32, TFLOAT64, TCOMPLEX64, TCOMPLEX128:
--- /dev/null
+// compile
+
+// Copyright 2018 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.
+
+// Non-constant duplicate keys/cases should not be reported
+// as errors by the compiler.
+
+package p
+
+import "unsafe"
+
+func f() {
+ _ = map[uintptr]int{
+ 0: 0,
+ uintptr(unsafe.Pointer(nil)): 0,
+ }
+
+ switch uintptr(0) {
+ case 0:
+ case uintptr(unsafe.Pointer(nil)):
+ }
+
+ switch interface{}(nil) {
+ case nil:
+ case nil:
+ }
+
+ _ = map[interface{}]int{
+ nil: 0,
+ nil: 0,
+ }
+}
--- /dev/null
+// compile
+
+// Copyright 2018 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.
+
+// Non-Go-constant but constant indexes are ok at compile time.
+
+package p
+
+import "unsafe"
+
+func f() {
+ var x [0]int
+ x[uintptr(unsafe.Pointer(nil))] = 0
+}
+func g() {
+ var x [10]int
+ _ = x[3:uintptr(unsafe.Pointer(nil))]
+}
--- /dev/null
+// errorcheck
+
+// Copyright 2018 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.
+
+// Non-Go-constant but constant values aren't ok for array sizes.
+
+package p
+
+import "unsafe"
+
+type T [uintptr(unsafe.Pointer(nil))]int // ERROR "non-constant array bound"
+
+func f() {
+ _ = complex(1<<uintptr(unsafe.Pointer(nil)), 0)
+}
--- /dev/null
+// errorcheck
+
+// Copyright 2018 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.
+
+// Non-Go-constant but constant values aren't ok for shifts.
+
+package p
+
+import "unsafe"
+
+func f() {
+ _ = complex(1<<uintptr(unsafe.Pointer(nil)), 0) // ERROR "invalid operation: .*shift of type float64.*"
+}