Skip to content

Commit

Permalink
Merge pull request swiftlang#78107 from ktoso/pick-mpokhylets-isolate…
Browse files Browse the repository at this point in the history
…d-deinit-version
  • Loading branch information
ktoso authored Jan 12, 2025
2 parents bdaf590 + b51213f commit 7b4a1ab
Show file tree
Hide file tree
Showing 28 changed files with 119 additions and 72 deletions.
3 changes: 3 additions & 0 deletions include/swift/ABI/MetadataValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -1704,6 +1704,9 @@ namespace SpecialPointerAuthDiscriminators {
const uint16_t RelativeProtocolWitnessTable = 0xb830; // = 47152

const uint16_t TypeLayoutString = 0x8b65; // = 35685

/// Isolated deinit body function pointer
const uint16_t DeinitWorkFunction = 0x8438; // = 33848
}

/// The number of arguments that will be passed directly to a generic
Expand Down
5 changes: 5 additions & 0 deletions include/swift/AST/DiagnosticsSIL.def
Original file line number Diff line number Diff line change
Expand Up @@ -790,6 +790,11 @@ NOTE(box_to_stack_cannot_promote_box_to_stack_due_to_escape_location, none,

WARNING(semantic_function_improper_nesting, none, "'@_semantics' function calls non-'@_semantics' function with nested '@_semantics' calls", ())

// SDK mismatch diagnostics
ERROR(missing_deinit_on_executor_function, none,
"Missing 'swift_task_deinitOnExecutor' function! "
"This is likely due to an outdated/incompatible SDK.", ())

// Capture promotion diagnostics
WARNING(capturepromotion_concurrentcapture_mutation, none,
"'%0' mutated after capture by sendable closure", (StringRef))
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -5963,6 +5963,9 @@ ERROR(isolated_deinit_no_isolation,none,
ERROR(isolated_deinit_on_value_type,none,
"only classes and actors can have isolated deinit",
())
ERROR(isolated_deinit_unavailable,none,
"isolated deinit is only available in %0 %1 or newer",
(StringRef, llvm::VersionTuple))
ERROR(isolated_deinit_experimental,none,
"'isolated' deinit requires frontend flag -enable-experimental-feature IsolatedDeinit "
"to enable the usage of this language feature", ())
Expand Down
1 change: 1 addition & 0 deletions include/swift/AST/FeatureAvailability.def
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ FEATURE(InitRawStructMetadata, (6, 0))

FEATURE(LayoutStringValueWitnesses, (6, 1))
FEATURE(CreateTaskWithConsumedFunction, (6, 1))
FEATURE(IsolatedDeinit, (6, 1))

FEATURE(TaskExecutor, FUTURE)
FEATURE(Differentiation, FUTURE)
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Basic/Features.def
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ EXPERIMENTAL_FEATURE(SafeInterop, true)
EXPERIMENTAL_FEATURE(AssumeResilientCxxTypes, true)

// Isolated deinit
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(IsolatedDeinit, true)
SUPPRESSIBLE_EXPERIMENTAL_FEATURE(IsolatedDeinit, false)

// Enable values in generic signatures, e.g. <let N: Int>
EXPERIMENTAL_FEATURE(ValueGenerics, true)
Expand Down
15 changes: 15 additions & 0 deletions include/swift/Runtime/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,9 @@ extern uintptr_t __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTL
#define __ptrauth_swift_type_layout_string \
__ptrauth(ptrauth_key_process_independent_data, 1, \
SpecialPointerAuthDiscriminators::TypeLayoutString)
#define __ptrauth_swift_deinit_work_function \
__ptrauth(ptrauth_key_function_pointer, 1, \
SpecialPointerAuthDiscriminators::DeinitWorkFunction)

#if __has_attribute(ptrauth_struct)
#define swift_ptrauth_struct(key, discriminator) \
Expand Down Expand Up @@ -364,6 +367,7 @@ extern uintptr_t __COMPATIBILITY_LIBRARIES_CANNOT_CHECK_THE_IS_SWIFT_BIT_DIRECTL
#define swift_ptrauth_sign_opaque_read_resume_function(__fn, __buffer) (__fn)
#define swift_ptrauth_sign_opaque_modify_resume_function(__fn, __buffer) (__fn)
#define __ptrauth_swift_type_layout_string
#define __ptrauth_swift_deinit_work_function
#define swift_ptrauth_struct(key, discriminator)
#define swift_ptrauth_struct_derived(from)
#endif
Expand Down Expand Up @@ -542,6 +546,17 @@ swift_auth_code(T value, unsigned extra) {
#endif
}

template <typename T>
SWIFT_RUNTIME_ATTRIBUTE_ALWAYS_INLINE static inline T
swift_auth_code_function(T value, unsigned extra) {
#if SWIFT_PTRAUTH
return (T)ptrauth_auth_function((void *)value,
ptrauth_key_function_pointer, extra);
#else
return value;
#endif
}

/// Does this platform support backtrace-on-crash?
#ifdef __APPLE__
# include <TargetConditionals.h>
Expand Down
7 changes: 5 additions & 2 deletions lib/SILGen/SILGenDestructor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "SwitchEnumBuilder.h"
#include "swift/AST/ConformanceLookup.h"
#include "swift/AST/Decl.h"
#include "swift/AST/DiagnosticsSIL.h"
#include "swift/AST/GenericSignature.h"
#include "swift/AST/SubstitutionMap.h"
#include "swift/Basic/Assertions.h"
Expand Down Expand Up @@ -373,8 +374,10 @@ void SILGenFunction::emitIsolatingDestructor(DestructorDecl *dd) {

// Get deinitOnExecutor
FuncDecl *swiftDeinitOnExecutorDecl = SGM.getDeinitOnExecutor();
assert(swiftDeinitOnExecutorDecl &&
"Failed to find swift_task_deinitOnExecutor function decl");
if (!swiftDeinitOnExecutorDecl) {
dd->diagnose(diag::missing_deinit_on_executor_function);
return;
}
SILFunction *swiftDeinitOnExecutorSILFunc = SGM.getFunction(
SILDeclRef(swiftDeinitOnExecutorDecl, SILDeclRef::Kind::Func),
NotForDefinition);
Expand Down
8 changes: 8 additions & 0 deletions lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
return;
}
}

TypeChecker::checkAvailability(
attr->getRange(), C.getIsolatedDeinitAvailability(),
D->getDeclContext(),
[&](StringRef platformName, llvm::VersionTuple version) {
return diagnoseAndRemoveAttr(
attr, diag::isolated_deinit_unavailable, platformName, version);
});
}
}

Expand Down
6 changes: 5 additions & 1 deletion stdlib/public/Concurrency/Actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "swift/Runtime/Concurrency.h"
#include <atomic>
#include <new>
#include <ptrauth.h>

#include "../CompatibilityOverride/CompatibilityOverride.h"
#include "swift/ABI/Actor.h"
Expand Down Expand Up @@ -2322,7 +2323,7 @@ namespace {
class IsolatedDeinitJob : public Job {
private:
void *Object;
DeinitWorkFunction *Work;
DeinitWorkFunction *__ptrauth_swift_deinit_work_function Work;

public:
IsolatedDeinitJob(JobPriority priority, void *object,
Expand Down Expand Up @@ -2351,6 +2352,9 @@ static void swift_task_deinitOnExecutorImpl(void *object,
DeinitWorkFunction *work,
SerialExecutorRef newExecutor,
size_t rawFlags) {
// Sign the function pointer
work = swift_auth_code_function(
work, SpecialPointerAuthDiscriminators::DeinitWorkFunction);
// If the current executor is compatible with running the new executor,
// we can just immediately continue running with the resume function
// we were passed in.
Expand Down
2 changes: 1 addition & 1 deletion stdlib/public/Concurrency/Executor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ internal final class DispatchQueueShim: @unchecked Sendable, SerialExecutor {
#endif // SWIFT_CONCURRENCY_USES_DISPATCH


@available(SwiftStdlib 5.6, *) // TODO: Clarify version
@available(SwiftStdlib 6.1, *)
@_silgen_name("swift_task_deinitOnExecutor")
@usableFromInline
internal func _deinitOnExecutor(_ object: __owned AnyObject,
Expand Down
4 changes: 2 additions & 2 deletions test/Concurrency/Runtime/actor_deinit_escaping_self.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// RUN: %target-run-simple-swift( -enable-experimental-feature IsolatedDeinit -target %target-swift-5.1-abi-triple %import-libdispatch -parse-as-library)
// RUN: %target-run-simple-swift( -enable-experimental-feature IsolatedDeinit -target %target-future-triple %import-libdispatch -parse-as-library)

// REQUIRES: executable_test
// REQUIRES: libdispatch
// REQUIRES: concurrency
// REQUIRES: concurrency_runtime
// REQUIRES: swift_feature_IsolatedDeinit
// UNSUPPORTED: back_deployment_runtime
// REQUIRES: swift_feature_IsolatedDeinit

import _Concurrency
import Dispatch
Expand Down
4 changes: 2 additions & 2 deletions test/Concurrency/Runtime/actor_recursive_deinit.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// RUN: %target-run-simple-swift(-enable-experimental-feature IsolatedDeinit -target %target-swift-5.1-abi-triple -parse-stdlib -parse-as-library) | %FileCheck %s
// RUN: %target-run-simple-swift(-enable-experimental-feature IsolatedDeinit -target %target-future-triple -parse-stdlib -parse-as-library) | %FileCheck %s

// REQUIRES: executable_test
// REQUIRES: concurrency

// REQUIRES: concurrency_runtime
// REQUIRES: swift_feature_IsolatedDeinit
// UNSUPPORTED: back_deployment_runtime
// REQUIRES: swift_feature_IsolatedDeinit

// Compiler crashes because builtin "ifdef_SWIFT_STDLIB_PRINT_DISABLED"() gets lowered as "i32 0",
// which triggers assertion in LLVM, which expects it to be i1
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// RUN: %empty-directory(%t)
// RUN: %target-build-swift -enable-experimental-feature IsolatedDeinit -plugin-path %swift-plugin-dir -enable-experimental-feature IsolatedDeinit -target %target-swift-5.1-abi-triple -parse-stdlib %import-libdispatch %s -o %t/a.out
// RUN: %target-build-swift -enable-experimental-feature IsolatedDeinit -plugin-path %swift-plugin-dir -target %target-future-triple -parse-stdlib %import-libdispatch %s -o %t/a.out
// RUN: %target-codesign %t/a.out
// RUN: %env-SWIFT_IS_CURRENT_EXECUTOR_LEGACY_MODE_OVERRIDE=swift6 %target-run %t/a.out

Expand Down
2 changes: 1 addition & 1 deletion test/Concurrency/Runtime/isolated_deinit_main_sync.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-run-simple-swift(-enable-experimental-feature IsolatedDeinit -target %target-swift-5.1-abi-triple) | %FileCheck %s
// RUN: %target-run-simple-swift(-enable-experimental-feature IsolatedDeinit -target %target-future-triple) | %FileCheck %s

// REQUIRES: executable_test
// REQUIRES: concurrency
Expand Down
6 changes: 3 additions & 3 deletions test/Concurrency/deinit_isolation.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %target-swift-frontend -target %target-swift-5.1-abi-triple -parse-as-library -enable-experimental-feature IsolatedDeinit -emit-silgen -verify %s
// RUN: %target-swift-frontend -target %target-swift-5.1-abi-triple -parse-as-library -enable-experimental-feature IsolatedDeinit -emit-silgen -DSILGEN %s | %FileCheck %s
// RUN: %target-swift-frontend -target %target-swift-5.1-abi-triple -parse-as-library -enable-experimental-feature IsolatedDeinit -emit-silgen -DSILGEN %s | %FileCheck -check-prefix=CHECK-SYMB %s
// RUN: %target-swift-frontend -target %target-future-triple -parse-as-library -enable-experimental-feature IsolatedDeinit -emit-silgen -verify %s
// RUN: %target-swift-frontend -target %target-future-triple -parse-as-library -enable-experimental-feature IsolatedDeinit -emit-silgen -DSILGEN %s | %FileCheck %s
// RUN: %target-swift-frontend -target %target-future-triple -parse-as-library -enable-experimental-feature IsolatedDeinit -emit-silgen -DSILGEN %s | %FileCheck -check-prefix=CHECK-SYMB %s

// REQUIRES: concurrency
// REQUIRES: swift_feature_IsolatedDeinit
Expand Down
2 changes: 1 addition & 1 deletion test/Concurrency/deinit_isolation_import/test.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// RUN: cp -R $INPUT_DIR/Alpha.framework %t/Frameworks/
// RUN: %empty-directory(%t/Frameworks/Alpha.framework/Modules/Alpha.swiftmodule)
// RUN: %empty-directory(%t/Frameworks/Alpha.framework/Headers/)
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-feature IsolatedDeinit -disable-implicit-string-processing-module-import -parse-as-library -module-name Alpha \
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-feature IsolatedDeinit -disable-implicit-string-processing-module-import -parse-as-library -disable-availability-checking -module-name Alpha \
// RUN: -emit-module -o %t/Frameworks/Alpha.framework/Modules/Alpha.swiftmodule/%module-target-triple.swiftmodule \
// RUN: -enable-objc-interop -disable-objc-attr-requires-foundation-module \
// RUN: -emit-objc-header -emit-objc-header-path %t/Frameworks/Alpha.framework/Headers/Alpha-Swift.h $INPUT_DIR/Alpha.swift
Expand Down
2 changes: 1 addition & 1 deletion test/Concurrency/deinit_isolation_in_value_types.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -target %target-swift-5.1-abi-triple -enable-experimental-feature IsolatedDeinit -parse-as-library -emit-silgen -verify %s
// RUN: %target-swift-frontend -target %target-future-triple -enable-experimental-feature IsolatedDeinit -parse-as-library -emit-silgen -verify %s

// REQUIRES: swift_feature_IsolatedDeinit

Expand Down
6 changes: 3 additions & 3 deletions test/Concurrency/deinit_isolation_objc.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-feature IsolatedDeinit -disable-implicit-string-processing-module-import -target %target-swift-5.1-abi-triple -parse-as-library -emit-silgen -verify %s
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-feature IsolatedDeinit -disable-implicit-string-processing-module-import -target %target-swift-5.1-abi-triple -parse-as-library -emit-silgen -DSILGEN %s | %FileCheck %s
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-feature IsolatedDeinit -disable-implicit-string-processing-module-import -target %target-swift-5.1-abi-triple -parse-as-library -emit-silgen -DSILGEN %s | %FileCheck -check-prefix=CHECK-SYMB %s
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-feature IsolatedDeinit -disable-implicit-string-processing-module-import -target %target-future-triple -parse-as-library -emit-silgen -verify %s
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-feature IsolatedDeinit -disable-implicit-string-processing-module-import -target %target-future-triple -parse-as-library -emit-silgen -DSILGEN %s | %FileCheck %s
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-feature IsolatedDeinit -disable-implicit-string-processing-module-import -target %target-future-triple -parse-as-library -emit-silgen -DSILGEN %s | %FileCheck -check-prefix=CHECK-SYMB %s

// REQUIRES: concurrency
// REQUIRES: objc_interop
Expand Down
2 changes: 1 addition & 1 deletion test/Concurrency/deinit_isolation_tbd.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-feature IsolatedDeinit -emit-ir %s | %FileCheck %s
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -enable-experimental-feature IsolatedDeinit -disable-availability-checking -emit-ir %s | %FileCheck %s

// REQUIRES: swift_feature_IsolatedDeinit

Expand Down
10 changes: 5 additions & 5 deletions test/Concurrency/flow_isolation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ actor Demons {
self.ns = x
}

nonisolated deinit {
deinit {
let _ = self.ns // expected-warning {{cannot access property 'ns' with a non-sendable type 'NonSendableType' from nonisolated deinit; this is an error in the Swift 6 language mode}}
}
}
Expand Down Expand Up @@ -159,7 +159,7 @@ actor ExampleFromProposal {
}


nonisolated deinit {
deinit {
_ = self.immutableSendable // ok
_ = self.mutableSendable // ok
_ = self.nonSendable // expected-warning {{cannot access property 'nonSendable' with a non-sendable type 'NonSendableType' from nonisolated deinit; this is an error in the Swift 6 language mode}}
Expand Down Expand Up @@ -199,7 +199,7 @@ class CheckGAIT1 {
silly += 2 // expected-warning {{cannot access property 'silly' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
}

nonisolated deinit {
deinit {
_ = ns // expected-warning {{cannot access property 'ns' with a non-sendable type 'NonSendableType' from nonisolated deinit; this is an error in the Swift 6 language mode}}
f() // expected-note {{after calling instance method 'f()', only nonisolated properties of 'self' can be accessed from a deinit}}
_ = silly // expected-warning {{cannot access property 'silly' here in deinitializer; this is an error in the Swift 6 language mode}}
Expand Down Expand Up @@ -623,7 +623,7 @@ actor Ahmad {
prop += 1 // expected-warning {{cannot access property 'prop' here in nonisolated initializer; this is an error in the Swift 6 language mode}}
}

nonisolated deinit {
deinit {
// expected-warning@+2 {{actor-isolated property 'computedProp' can not be referenced from a nonisolated context; this is an error in the Swift 6 language mode}}
// expected-note@+1 {{after accessing property 'computedProp', only nonisolated properties of 'self' can be accessed from a deinit}}
let x = computedProp
Expand Down Expand Up @@ -679,7 +679,7 @@ actor NonIsolatedDeinitExceptionForSwift5 {
}
}

@available(SwiftStdlib 5.5, *)
@available(SwiftStdlib 6.1, *)
actor IsolatedDeinitExceptionForSwift5 {
var x: Int = 0

Expand Down
77 changes: 41 additions & 36 deletions test/Concurrency/voucher_propagation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ actor Counter {
func get() -> Int { n }
}

@available(SwiftStdlib 6.1, *)
actor ActorWithSelfIsolatedDeinit {
let expectedVoucher: voucher_t?
let group: DispatchGroup
Expand All @@ -102,6 +103,7 @@ actor ActorWithSelfIsolatedDeinit {
}
}

@available(SwiftStdlib 6.1, *)
actor ActorWithDeinitIsolatedOnAnother {
let expectedVoucher: voucher_t?
let group: DispatchGroup
Expand All @@ -121,6 +123,7 @@ actor ActorWithDeinitIsolatedOnAnother {
}
}

@available(SwiftStdlib 6.1, *)
class ClassWithIsolatedDeinit {
let expectedVoucher: voucher_t?
let group: DispatchGroup
Expand Down Expand Up @@ -427,47 +430,49 @@ if #available(SwiftStdlib 5.1, *) {
group.wait()
}
}

tests.test("voucher propagation in isolated deinit [fast path]") {
withVouchers { v1, v2, v3 in
let group = DispatchGroup()
group.enter()
group.enter()
group.enter()
Task {
await AnotherActor.shared.performTesting {
adopt(voucher: v1)
_ = ClassWithIsolatedDeinit(expectedVoucher: v1, group: group)
}
await AnotherActor.shared.performTesting {
adopt(voucher: v2)
_ = ActorWithSelfIsolatedDeinit(expectedVoucher: v2, group: group)
}
await AnotherActor.shared.performTesting {
adopt(voucher: v3)
_ = ActorWithDeinitIsolatedOnAnother(expectedVoucher: v3, group: group)

if #available(SwiftStdlib 6.1, *) {
tests.test("voucher propagation in isolated deinit [fast path]") {
withVouchers { v1, v2, v3 in
let group = DispatchGroup()
group.enter()
group.enter()
group.enter()
Task {
await AnotherActor.shared.performTesting {
adopt(voucher: v1)
_ = ClassWithIsolatedDeinit(expectedVoucher: v1, group: group)
}
await AnotherActor.shared.performTesting {
adopt(voucher: v2)
_ = ActorWithSelfIsolatedDeinit(expectedVoucher: v2, group: group)
}
await AnotherActor.shared.performTesting {
adopt(voucher: v3)
_ = ActorWithDeinitIsolatedOnAnother(expectedVoucher: v3, group: group)
}
}
group.wait()
}
group.wait()
}
}

tests.test("voucher propagation in isolated deinit [slow path]") {
withVouchers { v1, v2, v3 in
let group = DispatchGroup()
group.enter()
group.enter()
Task {
do {
adopt(voucher: v1)
_ = ActorWithDeinitIsolatedOnAnother(expectedVoucher: v1, group: group)
}
do {
adopt(voucher: v2)
_ = ClassWithIsolatedDeinit(expectedVoucher: v2, group: group)

tests.test("voucher propagation in isolated deinit [slow path]") {
withVouchers { v1, v2, v3 in
let group = DispatchGroup()
group.enter()
group.enter()
Task {
do {
adopt(voucher: v1)
_ = ActorWithDeinitIsolatedOnAnother(expectedVoucher: v1, group: group)
}
do {
adopt(voucher: v2)
_ = ClassWithIsolatedDeinit(expectedVoucher: v2, group: group)
}
}
group.wait()
}
group.wait()
}
}
}
Expand Down
Loading

0 comments on commit 7b4a1ab

Please sign in to comment.