cgen: defer was broken in presence of anon fn. fixed #7171

pull/7204/head
joe-conigliaro 2020-12-08 14:21:19 +11:00
parent 3386526610
commit 805da2325f
No known key found for this signature in database
GPG Key ID: C12F7136C08206F1
2 changed files with 32 additions and 1 deletions

View File

@ -149,11 +149,19 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) {
if g.pref.is_prof { if g.pref.is_prof {
g.profile_fn(it) g.profile_fn(it)
} }
// we could be in an anon fn so save outer fn defer stmts
prev_defer_stmts := g.defer_stmts
g.defer_stmts = []
g.stmts(it.stmts) g.stmts(it.stmts)
// //
if it.return_type == table.void_type { if it.return_type == table.void_type {
g.write_defer_stmts_when_needed() g.write_defer_stmts_when_needed()
} }
if it.is_anon {
g.defer_stmts = prev_defer_stmts
} else {
g.defer_stmts = []
}
if it.return_type != table.void_type && it.stmts.len > 0 && it.stmts.last() !is ast.Return { if it.return_type != table.void_type && it.stmts.len > 0 && it.stmts.last() !is ast.Return {
default_expr := g.type_default(it.return_type) default_expr := g.type_default(it.return_type)
// TODO: perf? // TODO: perf?
@ -164,7 +172,6 @@ fn (mut g Gen) gen_fn_decl(it ast.FnDecl, skip bool) {
} }
} }
g.writeln('}') g.writeln('}')
g.defer_stmts = []
if g.pref.printfn_list.len > 0 && g.last_fn_c_name in g.pref.printfn_list { if g.pref.printfn_list.len > 0 && g.last_fn_c_name in g.pref.printfn_list {
println(g.out.after(fn_start_pos)) println(g.out.after(fn_start_pos))
} }

View File

@ -45,6 +45,10 @@ mut:
val int val int
} }
fn (n Num) add(i int) int {
return n.val + i
}
fn test_defer_early_exit() { fn test_defer_early_exit() {
mut sum := Num{0} mut sum := Num{0}
for i in 0 .. 10 { for i in 0 .. 10 {
@ -59,3 +63,23 @@ fn test_defer_option() {
set_num_opt(mut ok) or {} set_num_opt(mut ok) or {}
assert ok.val == 1 assert ok.val == 1
} }
fn test_defer_with_anon_fn() {
mut f := &Num{val: 110}
defer {
assert f.add(1) == 111
}
go fn () {
defer {
println('deferred 1')
}
}()
x := fn () {
defer {
println('defered 2')
}
return
}
x()
return
}