[Concurrency] Fix a crash caused by misuse of isolated modifier

Adjust isolation checking to handle misused `isolated` attribute
and let attribute checker property diagnose it.

Resolves: rdar://148076903
Resolves: https://github.com/swiftlang/swift/issues/80363
This commit is contained in:
Pavel Yaskevich
2025-06-27 18:03:28 -07:00
parent 0999792bf4
commit 358067917e
3 changed files with 56 additions and 5 deletions

View File

@@ -5046,7 +5046,13 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
bool onlyExplicit = false) {
// Look up attributes on the declaration that can affect its actor isolation.
// If any of them are present, use that attribute.
auto isolatedAttr = decl->getAttrs().getAttribute<IsolatedAttr>();
// 'isolated` attribute in the declaration context currently applies
// only to `deinit` declarations, invalid uses are going to
// be diagnosed as part of attribute checking.
auto isolatedAttr = isa<DestructorDecl>(decl)
? decl->getAttrs().getAttribute<IsolatedAttr>()
: nullptr;
auto nonisolatedAttr = decl->getAttrs().getAttribute<NonisolatedAttr>();
auto globalActorAttr = decl->getGlobalActorAttr();
auto concurrentAttr = decl->getAttrs().getAttribute<ConcurrentAttr>();
@@ -5099,10 +5105,8 @@ getIsolationFromAttributes(const Decl *decl, bool shouldDiagnose = true,
}
// If the declaration is explicitly marked 'isolated', infer actor isolation
// from the context. Currently applies only to DestructorDecl
// from the context. Currently applies only to DestructorDecl.
if (isolatedAttr) {
assert(isa<DestructorDecl>(decl));
auto dc = decl->getDeclContext();
auto selfTypeDecl = dc->getSelfNominalTypeDecl();
std::optional<ActorIsolation> result;

View File

@@ -0,0 +1,47 @@
// RUN: %target-typecheck-verify-swift
// https://github.com/swiftlang/swift/issues/80363
class C {}
func testLocal() {
isolated let c = C()
// expected-error@-1 {{'isolated' may only be used on 'deinit' declarations}}
_ = c
isolated func test() {
// expected-error@-1 {{'isolated' may only be used on 'deinit' declarations}}
}
}
isolated var x: Int = 42
// expected-error@-1 {{'isolated' may only be used on 'deinit' declarations}}
isolated class Test {
// expected-error@-1 {{'isolated' may only be used on 'deinit' declarations}}
}
struct TestMembers {
isolated var q: String {
// expected-error@-1 {{'isolated' may only be used on 'deinit' declarations}}
get {
"ultimate question"
}
isolated set {
// expected-error@-1 {{expected 'get', 'set', 'willSet', or 'didSet' keyword to start an accessor definition}}
}
}
isolated let a: Int = 42
// expected-error@-1 {{'isolated' may only be used on 'deinit' declarations}}
isolated subscript(x: Int) -> Bool {
// expected-error@-1 {{'isolated' may only be used on 'deinit' declarations}}
get { true }
}
isolated func test() {
// expected-error@-1 {{'isolated' may only be used on 'deinit' declarations}}
}
}

View File

@@ -1,3 +1,3 @@
// {"signature":"getIsolationFromAttributes(swift::Decl const*, bool, bool)"}
// RUN: not --crash %target-swift-frontend -typecheck %s
// RUN: not %target-swift-frontend -typecheck %s
isolated let a