Skip to content

Commit b75e8a2

Browse files
namusyakamdempsky
authored andcommitted
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 <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
1 parent 2c0c68d commit b75e8a2

File tree

2 files changed

+43
-4
lines changed

2 files changed

+43
-4
lines changed

src/cmd/compile/internal/gc/swt.go

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -621,10 +621,23 @@ func checkDupExprCases(exprname *Node, clauses []*Node) {
621621
}
622622
return
623623
}
624-
// s's expression is an interface. This is fairly rare, so keep this simple.
625-
// Duplicates are only duplicates if they have the same type and the same value.
624+
625+
// s's expression is an interface. This is fairly rare, so
626+
// keep this simple. Case expressions are only duplicates if
627+
// they have the same value and identical types.
628+
//
629+
// In general, we have to use eqtype to test type identity,
630+
// because == gives false negatives for anonymous types and
631+
// the byte/uint8 and rune/int32 builtin type aliases.
632+
// However, this is not a problem here, because constant
633+
// expressions are always untyped or have a named type, and we
634+
// explicitly handle the builtin type aliases below.
635+
//
636+
// This approach may need to be revisited though if we fix
637+
// #21866 by treating all type aliases like byte/uint8 and
638+
// rune/int32.
626639
type typeVal struct {
627-
typ string
640+
typ *types.Type
628641
val interface{}
629642
}
630643
seen := make(map[typeVal]*Node)
@@ -634,9 +647,15 @@ func checkDupExprCases(exprname *Node, clauses []*Node) {
634647
continue
635648
}
636649
tv := typeVal{
637-
typ: n.Type.LongString(),
650+
typ: n.Type,
638651
val: n.Val().Interface(),
639652
}
653+
switch tv.typ {
654+
case types.Bytetype:
655+
tv.typ = types.Types[TUINT8]
656+
case types.Runetype:
657+
tv.typ = types.Types[TINT32]
658+
}
640659
prev, dup := seen[tv]
641660
if !dup {
642661
seen[tv] = n

test/fixedbugs/issue24159.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// errorcheck
2+
3+
// Copyright 2018 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package p
8+
9+
type intAlias = int
10+
11+
func f() {
12+
switch interface{}(nil) {
13+
case uint8(0):
14+
case byte(0): // ERROR "duplicate case"
15+
case int32(0):
16+
case rune(0): // ERROR "duplicate case"
17+
case int(0):
18+
case intAlias(0): // ERROR "duplicate case"
19+
}
20+
}

0 commit comments

Comments
 (0)