-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/compile: short-circuiting interface-to-concrete comparisons misses panics #32187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
UPD: package main
import (
"errors"
)
type SomeType struct{}
func (SomeType) Error() string {
return ""
}
func main() {
var x error
x = errors.New("aa")
switch x {
case x.(SomeType):
println("SomeType")
case x:
println("x")
}
} if i cast to |
Definitely weird. That should panic. I suspect something in the compiler is getting mixed up between expression switches (which this is) and type switches. Is this derived from some real code? It looks bizarre to me. The reason I ask is because it affects priority - if this happens in the real world we should probably get a fix in for 1.13; if not it can wait for 1.14. Go gets this right up to and including 1.4. The bug starts in 1.5. |
I got something similar while reviewing a pull request where the code works fine. |
It just seems weird to compare an interface against a concrete type that's type-casted from an interface. You might as well compare them directly. In other words, if x and y are interfaces, then |
Simpler repros:
The problem is for interface-to-concrete comparisons, we're short circuiting on the interface value's dynamic type before evaluating the concrete expression for side effects. The problem doesn't happen for go/src/cmd/compile/internal/gc/order.go Lines 1206 to 1213 in b84e0bc
|
Change https://golang.org/cl/178817 mentions this issue: |
…hould 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 golang#32187 Change-Id: I15b58a523491b7fd1856b8fdb9ba0cba5d11ebb4 Reviewed-on: https://go-review.googlesource.com/c/go/+/178817 Run-TryBot: Cuong Manh Le <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
…hould 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 golang#32187 Change-Id: I15b58a523491b7fd1856b8fdb9ba0cba5d11ebb4 Reviewed-on: https://go-review.googlesource.com/c/go/+/178817 Run-TryBot: Cuong Manh Le <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Matthew Dempsky <[email protected]>
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Here is the code + play.golang.org link on it :
What did you expect to see?
I was expecting to see panic at the line
case x.(*SomeType):
because of the bad type casting.For example if i uncomment the line
// println(x.(*SomeType))
(which castsx
the same way as incase
) i get the panicWhat did you see instead?
This code successfully compiles and prints "x" when running.
The text was updated successfully, but these errors were encountered: