mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/compile: prevent detection of wrong duplicates
by including *types.Type in typeVal. Updates #21866 Fixes #24159 Change-Id: I2f8cac252d88d43e723124f2867b1410b7abab7b Reviewed-on: https://go-review.googlesource.com/98476 Run-TryBot: Kunpei Sakai <namusyaka@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
2c0c68d621
commit
b75e8a2a3b
2 changed files with 43 additions and 4 deletions
|
|
@ -621,10 +621,23 @@ func checkDupExprCases(exprname *Node, clauses []*Node) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// s's expression is an interface. This is fairly rare, so keep this simple.
|
|
||||||
// Duplicates are only duplicates if they have the same type and the same value.
|
// s's expression is an interface. This is fairly rare, so
|
||||||
|
// keep this simple. Case expressions are only duplicates if
|
||||||
|
// they have the same value and identical types.
|
||||||
|
//
|
||||||
|
// In general, we have to use eqtype to test type identity,
|
||||||
|
// because == gives false negatives for anonymous types and
|
||||||
|
// the byte/uint8 and rune/int32 builtin type aliases.
|
||||||
|
// However, this is not a problem here, because constant
|
||||||
|
// expressions are always untyped or have a named type, and we
|
||||||
|
// explicitly handle the builtin type aliases below.
|
||||||
|
//
|
||||||
|
// This approach may need to be revisited though if we fix
|
||||||
|
// #21866 by treating all type aliases like byte/uint8 and
|
||||||
|
// rune/int32.
|
||||||
type typeVal struct {
|
type typeVal struct {
|
||||||
typ string
|
typ *types.Type
|
||||||
val interface{}
|
val interface{}
|
||||||
}
|
}
|
||||||
seen := make(map[typeVal]*Node)
|
seen := make(map[typeVal]*Node)
|
||||||
|
|
@ -634,9 +647,15 @@ func checkDupExprCases(exprname *Node, clauses []*Node) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
tv := typeVal{
|
tv := typeVal{
|
||||||
typ: n.Type.LongString(),
|
typ: n.Type,
|
||||||
val: n.Val().Interface(),
|
val: n.Val().Interface(),
|
||||||
}
|
}
|
||||||
|
switch tv.typ {
|
||||||
|
case types.Bytetype:
|
||||||
|
tv.typ = types.Types[TUINT8]
|
||||||
|
case types.Runetype:
|
||||||
|
tv.typ = types.Types[TINT32]
|
||||||
|
}
|
||||||
prev, dup := seen[tv]
|
prev, dup := seen[tv]
|
||||||
if !dup {
|
if !dup {
|
||||||
seen[tv] = n
|
seen[tv] = n
|
||||||
|
|
|
||||||
20
test/fixedbugs/issue24159.go
Normal file
20
test/fixedbugs/issue24159.go
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
package p
|
||||||
|
|
||||||
|
type intAlias = int
|
||||||
|
|
||||||
|
func f() {
|
||||||
|
switch interface{}(nil) {
|
||||||
|
case uint8(0):
|
||||||
|
case byte(0): // ERROR "duplicate case"
|
||||||
|
case int32(0):
|
||||||
|
case rune(0): // ERROR "duplicate case"
|
||||||
|
case int(0):
|
||||||
|
case intAlias(0): // ERROR "duplicate case"
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue