mirror of
https://github.com/golang/go
synced 2024-10-14 20:05:36 +00:00
cmd/compile: don't convert non-Go-constants to OLITERALs
Don't convert values that aren't Go constants, like uintptr(unsafe.Pointer(nil)), to a literal constant. This avoids assuming they are constants for things like indexing, array sizes, case duplication, etc. Also, nil is an allowed duplicate in switches. CTNILs aren't Go constants. Fixes #28078 Fixes #28079 Change-Id: I9ab8af47098651ea09ef10481787eae2ae2fb445 Reviewed-on: https://go-review.googlesource.com/c/151320 Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
3f9efe7500
commit
eb6c433eb3
|
@ -1327,7 +1327,7 @@ func (n *Node) isGoConst() bool {
|
|||
}
|
||||
return true
|
||||
|
||||
case OCONV:
|
||||
case OCONV, OCONVNOP:
|
||||
if okforconst[n.Type.Etype] && n.Left.isGoConst() {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -679,7 +679,7 @@ func checkDupExprCases(exprname *Node, clauses []*Node) {
|
|||
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{
|
||||
|
|
|
@ -1818,9 +1818,9 @@ func typecheck1(n *Node, top int) (res *Node) {
|
|||
|
||||
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:
|
||||
|
|
34
test/fixedbugs/issue28078.go
Normal file
34
test/fixedbugs/issue28078.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
// 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,
|
||||
}
|
||||
}
|
20
test/fixedbugs/issue28079a.go
Normal file
20
test/fixedbugs/issue28079a.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
// 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))]
|
||||
}
|
17
test/fixedbugs/issue28079b.go
Normal file
17
test/fixedbugs/issue28079b.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
// 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)
|
||||
}
|
15
test/fixedbugs/issue28079c.go
Normal file
15
test/fixedbugs/issue28079c.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
// 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.*"
|
||||
}
|
Loading…
Reference in a new issue