Skip to content

Commit f674e56

Browse files
authored
Merge pull request #67681 from mikeash/fix-actor-dynamic-subclassing
[Concurrency] Fix crash when actor is dynamically subclassed.
2 parents 300d04a + 9f9929a commit f674e56

File tree

3 files changed

+38
-2
lines changed

3 files changed

+38
-2
lines changed

stdlib/public/BackDeployConcurrency/Actor.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1712,8 +1712,10 @@ static bool isDefaultActorClass(const ClassMetadata *metadata) {
17121712
assert(metadata->isTypeMetadata());
17131713
while (true) {
17141714
// Trust the class descriptor if it says it's a default actor.
1715-
if (metadata->getDescription()->isDefaultActor())
1715+
if (!metadata->isArtificialSubclass() &&
1716+
metadata->getDescription()->isDefaultActor()) {
17161717
return true;
1718+
}
17171719

17181720
// Go to the superclass.
17191721
metadata = metadata->Superclass;

stdlib/public/Concurrency/Actor.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1775,7 +1775,8 @@ static bool isDefaultActorClass(const ClassMetadata *metadata) {
17751775
assert(metadata->isTypeMetadata());
17761776
while (true) {
17771777
// Trust the class descriptor if it says it's a default actor.
1778-
if (metadata->getDescription()->isDefaultActor()) {
1778+
if (!metadata->isArtificialSubclass() &&
1779+
metadata->getDescription()->isDefaultActor()) {
17791780
return true;
17801781
}
17811782

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// RUN: %target-run-simple-swift(-Xfrontend -disable-availability-checking -parse-as-library)
2+
3+
// REQUIRES: executable_test
4+
// REQUIRES: concurrency
5+
// REQUIRES: objc_interop
6+
7+
// UNSUPPORTED: back_deployment_runtime
8+
// UNSUPPORTED: use_os_stdlib
9+
10+
// Make sure the concurrency runtime tolerates dynamically-subclassed actors.
11+
12+
import ObjectiveC
13+
14+
actor Foo: NSObject {
15+
var x = 0
16+
17+
func doit() async {
18+
x += 1
19+
try! await Task.sleep(nanoseconds: 1000)
20+
x += 1
21+
}
22+
}
23+
24+
@main
25+
enum Main {
26+
static func main() async {
27+
let FooSub = objc_allocateClassPair(Foo.self, "FooSub", 0) as! Foo.Type
28+
objc_registerClassPair(FooSub)
29+
let foosub = FooSub.init()
30+
await foosub.doit()
31+
}
32+
}
33+

0 commit comments

Comments
 (0)