mirror of
https://github.com/golang/go
synced 2024-11-24 01:30:10 -07:00
25ebf015f6
In interface-to-concrete comparisons, we are short circuiting on the interface value's dynamic type before evaluating the concrete expression for side effects, causing concrete expression won't panic at runtime, while it should. To fix it, evaluating the RHS of comparison before we do the short-circuit. We also want to prioritize panics in the LHS over the RHS, so evaluating the LHS too. Fixes #32187 Change-Id: I15b58a523491b7fd1856b8fdb9ba0cba5d11ebb4 Reviewed-on: https://go-review.googlesource.com/c/go/+/178817 Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
61 lines
1.2 KiB
Go
61 lines
1.2 KiB
Go
// run
|
|
|
|
// Copyright 2019 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.
|
|
|
|
// short-circuiting interface-to-concrete comparisons
|
|
// will not miss panics
|
|
|
|
package main
|
|
|
|
import (
|
|
"log"
|
|
"strings"
|
|
)
|
|
|
|
func main() {
|
|
var (
|
|
x interface{}
|
|
p *int
|
|
s []int
|
|
l *interface{}
|
|
r []*int
|
|
)
|
|
tests := []struct {
|
|
name string
|
|
errStr string
|
|
f func()
|
|
}{
|
|
{"switch case", "", func() {
|
|
switch x {
|
|
case x.(*int):
|
|
}
|
|
}},
|
|
{"interface conversion", "", func() { _ = x == x.(error) }},
|
|
{"type assertion", "", func() { _ = x == x.(*int) }},
|
|
{"out of bounds", "", func() { _ = x == s[1] }},
|
|
{"nil pointer dereference #1", "", func() { _ = x == *p }},
|
|
{"nil pointer dereference #2", "nil pointer dereference", func() { _ = *l == r[0] }},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
testFuncShouldPanic(tc.name, tc.errStr, tc.f)
|
|
}
|
|
}
|
|
|
|
func testFuncShouldPanic(name, errStr string, f func()) {
|
|
defer func() {
|
|
e := recover()
|
|
if e == nil {
|
|
log.Fatalf("%s: comparison did not panic\n", name)
|
|
}
|
|
if errStr != "" {
|
|
if !strings.Contains(e.(error).Error(), errStr) {
|
|
log.Fatalf("%s: wrong panic message\n", name)
|
|
}
|
|
}
|
|
}()
|
|
f()
|
|
}
|