Avatar
SILの質問です。closureのSILを見て遊んでたら気づいたんですが、strong_retainstrong_releaseはペアになってないときもあるんですか?strong_retainは1回しか呼ばれてないのにstrong_releaseは2回呼ばれている func foo() -> Int { var i = 1 let closure: ((Int) -> Void) = { _ in } closure(10) return i } // foo() sil hidden @$S7sample23fooSiyF : $@convention(thin) () -> Int { bb0: %0 = alloc_stack $Int, var, name "i" // users: %3, %13 %1 = integer_literal $Builtin.Int64, 1 // user: %2 %2 = struct $Int (%1 : $Builtin.Int64) // users: %14, %3 store %2 to %0 : $*Int // id: %3 // function_ref closure #1 in foo() %4 = function_ref @$S7sample23fooSiyFySicfU_ : $@convention(thin) (Int) -> () // user: %5 %5 = thin_to_thick_function %4 : $@convention(thin) (Int) -> () to $@callee_guaranteed (Int) -> () // users: %12, %11, %10, %7, %6 debug_value %5 : $@callee_guaranteed (Int) -> (), let, name "closure" // id: %6 strong_retain %5 : $@callee_guaranteed (Int) -> () // id: %7 %8 = integer_literal $Builtin.Int64, 10 // user: %9 %9 = struct $Int (%8 : $Builtin.Int64) // user: %10 %10 = apply %5(%9) : $@callee_guaranteed (Int) -> () strong_release %5 : $@callee_guaranteed (Int) -> () // id: %11 strong_release %5 : $@callee_guaranteed (Int) -> () // id: %12 dealloc_stack %0 : $*Int // id: %13 return %2 : $Int // id: %14 } // end sil function '$S7sample23fooSiyF'