mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-04 19:17:47 +00:00
compiler: pass interface typecode through defer frames
Previously, the typecode was passed via a direct reference, which results in invalid IR when the defer is not reached in all return paths. It also results in incorrect behavior if the defer is in a loop, causing all defers to use the typecode of the last iteration.
This commit is contained in:
Vendored
+36
@@ -61,6 +61,9 @@ func main() {
|
||||
thingFunctionalArgs1.Print("functional args 1")
|
||||
thingFunctionalArgs2 := NewThing(WithName("named thing"))
|
||||
thingFunctionalArgs2.Print("functional args 2")
|
||||
|
||||
// regression testing
|
||||
regression1033()
|
||||
}
|
||||
|
||||
func runFunc(f func(int), arg int) {
|
||||
@@ -108,3 +111,36 @@ func exportedDefer() {
|
||||
func testBound(f func() string) {
|
||||
println("bound method:", f())
|
||||
}
|
||||
|
||||
// regression1033 is a regression test for https://github.com/tinygo-org/tinygo/issues/1033.
|
||||
// In previous versions of the compiler, a deferred call to an interface would create an instruction that did not dominate its uses.
|
||||
func regression1033() {
|
||||
foo(&Bar{})
|
||||
}
|
||||
|
||||
type Bar struct {
|
||||
empty bool
|
||||
}
|
||||
|
||||
func (b *Bar) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type Closer interface {
|
||||
Close() error
|
||||
}
|
||||
|
||||
func foo(bar *Bar) error {
|
||||
var a int
|
||||
if !bar.empty {
|
||||
a = 10
|
||||
if a != 5 {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
var c Closer = bar
|
||||
defer c.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user