mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Because `_taskLocalValuePush` and `_taskLocalValuePop` can result in calls to `swift_task_alloc` and `swift_task_dealloc` respectively, and because the compiler hasn't been taught about that (e.g. `SILInstruction::isAllocatingStack`, `SILInstruction::isDeallocatingStack`, etc), calling them (push and pop) from a function which makes use the stack for dynamically sized allocations can result in violations of stack discipline of the form ``` swift_task_alloc // allocates %ptr_1 copy_value_witness // copies into %ptr_1 swift_task_localValuePush // calls swift_task_alloc and allocates %ptr_2 swift_task_dealloc // deallocates %ptr_1 swift_task_localValuePop // calls swift_task_dealloc and deallocates %ptr_2 ``` Avoid the problem by not allocating dynamically sized stack space in the function which calls `_taskLocalValuePush` and `_taskLocalValuePop`. Split the calls to those functions into `withValueImpl` function which takes its argument `__owned`. Call that function from `withValue`, ensuring that the necessary copy (to account for the fact that withValue takes its argument `__guaranteed` but `_taskLocalValuePush` takes its `__owned`) and associated stack traffic occur in `withValue`. Still, allow `withValueImpl` to be inlined. The stack nesting will be preserved across it. rdar://107275872