Files
swift-mirror/test/SILGen/literal_closure_reabstraction_with_peephole.swift
Joe Groff 8db31d5804 SILGen: Complete initialization of FinalContext in ConversionInitialization::tryPeephole
The callers to ConversionInitialization::tryPeephole assume that, if the conversion peephole
succeeded, that the peepholed result was fully emitted into the initialization. However, if
the ConversionInitialization sat on top of an in-memory initialization, then tryPeephole would
only set the value of the ConversionInitialization, without forwarding the value into the underlying
initialization, causing code generation to proceed leaving the underlying memory uninitialized.
This problem becomes exposed now when literal closures are emitted with a return value that is
indirectly returned and also reabstracted, and the return expression undergoes a ping-pong reabstraction
pair: we see through the conversions and peephole away the reabstractions, but fail to emplace the
result in the indirect return slot.

Fixes rdar://92654098
2022-05-27 09:07:16 -07:00

33 lines
929 B
Swift

// RUN: %target-swift-emit-silgen -verify %s
fileprivate typealias Closure = () -> Void
func crash1() {
let closure1: Closure? = nil
let closure2: Closure? = nil
let closure3: Closure? = nil
print("Closures: \(String(describing: closure1)), \(String(describing: closure2)), \(String(describing: closure3))")
let closure = closure1 ?? closure2 ?? closure3
print("\(#line): \(String(describing: closure))")
closure?() // <- EXC_BAD_ACCESS
assert(closure == nil)
}
func crash2() {
let closure1: Closure? = nil
let closure2: Closure? = nil
let closure3: Closure? = { }
print("Closures: \(String(describing: closure1)), \(String(describing: closure2)), \(String(describing: closure3))")
let closure = closure1 ?? closure2 ?? closure3
print("\(#line): \(String(describing: closure))")
closure?() // <- EXC_BAD_ACCESS
assert(closure != nil)
}
crash1()
crash2()