Skip to content

Conversation

@slavapestov
Copy link
Contributor

In the following code, SILGen emits a mark_uninitialized instruction
on the projected box value, diagnosing the reference to 'x' before
it has been fully initialized:

var x: Int
x = { _ = x; 123 }()

However, when the binding has an initial value, we don't emit the
mark_uninitialized instruction, and the closure ends up capturing the
uninitialized box:

var x: Int = { _ = x; 123 }() // undefined behavior

Unfortunately, we can't unconditionally emit a mark_uninitialized here,
because DI does not recognize all the code patterns that SILGen can emit
when initializing an address-only value in-place.

Instead, what we want to do is only enter the box into SILGenFunction::VarLocs
after the initial value expression has been emitted. This ensures that the
forward-referenced-capture diagnostics catch this.

Note that this only addresses the case of a local binding; we still
generate invalid code here if you forward-reference a global 'var' in
this manner. Fixing that requires some additional changes.

Fixes https://bugs.swift.org/browse/SR-14747, rdar://problem/79051431, rdar://problem/77933460.

…alized

In the following code, SILGen emits a mark_uninitialized instruction
on the projected box value, diagnosing the reference to 'x' before
it has been fully initialized:

    var x: Int
    x = { _ = x; 123 }()

However, when the binding has an initial value, we don't emit the
mark_uninitialized instruction, and the closure ends up capturing the
uninitialized box:

    var x: Int = { _ = x; 123 }() // undefined behavior

Unfortunately, we can't unconditionally emit a mark_uninitialized here,
because DI does not recognize all the code patterns that SILGen can emit
when initializing an address-only value in-place.

Instead, what we want to do is only enter the box into SILGenFunction::VarLocs
after the initial value expression has been emitted. This ensures that the
forward-referenced-capture diagnostics catch this.

Note that this only addresses the case of a local binding; we still
generate invalid code here if you forward-reference a global 'var' in
this manner. Fixing that requires some additional changes.

Fixes https://bugs.swift.org/browse/SR-14747, rdar://problem/77933460.
@slavapestov
Copy link
Contributor Author

@jckarter Does this look reasonable?

@slavapestov
Copy link
Contributor Author

@swift-ci Please smoke test

@slavapestov slavapestov merged commit 62caff6 into swiftlang:main Jun 24, 2021
jamieQ added a commit to jamieQ/swift that referenced this pull request Oct 21, 2025
This addresses the same problem as swiftlang#37935
but handles address-only lets rather than vars.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant