Skip to content

Commit 495a86d

Browse files
committed
[IRGen] Only emit AssociatedTypeInProtocolContextByte for default associated type witnesses
rdar://159310652 This was causing the runtime to try to get types by mangled names for types of which the mangling was not supported by the target runtime, which led to runtime crashes.
1 parent 6942742 commit 495a86d

File tree

3 files changed

+86
-7
lines changed

3 files changed

+86
-7
lines changed

lib/IRGen/GenReflection.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -315,9 +315,8 @@ getRuntimeVersionThatSupportsDemanglingType(CanType type) {
315315
// where completing the metadata during demangling might cause cyclic
316316
// dependencies.
317317
static std::pair<llvm::Constant *, unsigned>
318-
getTypeRefByFunction(IRGenModule &IGM,
319-
CanGenericSignature sig,
320-
CanType t) {
318+
getTypeRefByFunction(IRGenModule &IGM, CanGenericSignature sig, CanType t,
319+
MangledTypeRefRole role) {
321320
IRGenMangler mangler(IGM.Context);
322321
std::string symbolName =
323322
mangler.mangleSymbolNameForMangledMetadataAccessorString(
@@ -433,7 +432,11 @@ getTypeRefByFunction(IRGenModule &IGM,
433432
// Form the mangled name with its relative reference.
434433
auto S = B.beginStruct();
435434
S.setPacked(true);
436-
S.add(llvm::ConstantInt::get(IGM.Int8Ty, 255));
435+
if (role == MangledTypeRefRole::DefaultAssociatedTypeWitness) {
436+
S.add(llvm::ConstantInt::get(
437+
IGM.Int8Ty,
438+
ProtocolRequirementFlags::AssociatedTypeInProtocolContextByte));
439+
}
437440
S.add(llvm::ConstantInt::get(IGM.Int8Ty, 9));
438441
S.addCompactFunctionReference(accessor);
439442

@@ -513,7 +516,7 @@ getTypeRefImpl(IRGenModule &IGM,
513516
// the field will be artificially hidden to reflectors.
514517
if (isAlwaysNoncopyable) {
515518
IGM.IRGen.noteUseOfTypeMetadata(type);
516-
return getTypeRefByFunction(IGM, sig, type);
519+
return getTypeRefByFunction(IGM, sig, type, role);
517520
}
518521
}
519522
LLVM_FALLTHROUGH;
@@ -524,12 +527,12 @@ getTypeRefImpl(IRGenModule &IGM,
524527
// ensuring that we can always reconstruct type metadata from a mangled name
525528
// in-process.
526529
IGM.IRGen.noteUseOfTypeMetadata(type);
527-
530+
528531
// If the minimum deployment target's runtime demangler wouldn't understand
529532
// this mangled name, then fall back to generating a "mangled name" with a
530533
// symbolic reference with a callback function.
531534
if (mangledNameIsUnknownToDeployTarget(IGM, type)) {
532-
return getTypeRefByFunction(IGM, sig, type);
535+
return getTypeRefByFunction(IGM, sig, type, role);
533536
}
534537

535538
break;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
public protocol Proto {
2+
associatedtype T: Proto
3+
4+
var value: T {get}
5+
}
6+
7+
public func makeThing<P: Proto>(_ t: P) -> some Proto {
8+
return ProtoImpl(t.value)
9+
}
10+
11+
public struct ProtoImpl<V>: Proto {
12+
public let genValue: V
13+
14+
public init(_ genValue: V) {
15+
self.genValue = genValue
16+
}
17+
18+
public var value: some Proto {
19+
return self
20+
}
21+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-build-swift-dylib(%t/%target-library-name(associated_type_by_mangled_name)) -target %target-cpu-apple-macosx15.0 -enable-library-evolution %S/Inputs/associated_type_by_mangled_name.swift -emit-module -emit-module-path %t/associated_type_by_mangled_name.swiftmodule -module-name associated_type_by_mangled_name
4+
// RUN: %target-codesign %t/%target-library-name(associated_type_by_mangled_name)
5+
6+
// RUN: %target-swift-frontend -target %target-cpu-apple-macosx15.0 -I %t %s -emit-ir -o - | %FileCheck %s
7+
// RUN: %target-swift-frontend -target %target-cpu-apple-macosx26.0 -I %t %s -emit-ir -o - | %FileCheck %s -check-prefix CHECK-SUPPORTED
8+
9+
// RUN: %target-build-swift -target %target-cpu-apple-macosx15.0 %s -lassociated_type_by_mangled_name -I %t -L %t -o %t/main15 %target-rpath(%t)
10+
// RUN: %target-codesign %t/main15
11+
12+
// RUN: %target-run %t/main15 %t/%target-library-name(associated_type_by_mangled_name)
13+
14+
// RUN: %target-build-swift -target %target-cpu-apple-macosx26.0 %s -lassociated_type_by_mangled_name -I %t -L %t -o %t/main26 %target-rpath(%t)
15+
// RUN: %target-codesign %t/main26
16+
17+
// RUN: %target-run %t/main26 %t/%target-library-name(associated_type_by_mangled_name)
18+
19+
// REQUIRES: executable_test
20+
// REQUIRES: OS=macosx
21+
// UNSUPPORTED: back_deployment_runtime || use_os_stdlib
22+
23+
import associated_type_by_mangled_name
24+
25+
protocol P: Sendable {
26+
associatedtype T: Proto
27+
func foo() -> T
28+
}
29+
30+
struct PImpl: P {
31+
func foo() -> some Proto {
32+
return ProtoImpl(2)
33+
}
34+
}
35+
36+
// CHECK: @"get_type_metadata 30nonisolated_nonsending_closure1PRzl31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcG.3" = linkonce_odr hidden constant <{ i8, i32, i8 }> <{ i8 9, i32 trunc (i64 sub (i64 ptrtoint (ptr @"get_type_metadata 30nonisolated_nonsending_closure1PRzl31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcG" to i64), i64 ptrtoint (ptr getelementptr inbounds (<{ i8, i32, i8 }>, ptr @"get_type_metadata 30nonisolated_nonsending_closure1PRzl31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcG.3", i32 0, i32 1) to i64)) to i32), i8 0 }>
37+
// CHECK: define linkonce_odr hidden ptr @"$s31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcGACyxGAA0F0AAWl"() #1 {
38+
// CHECK: call swiftcc %swift.metadata_response @"$s31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcGMa"(i64 255)
39+
// CHECK: }
40+
41+
// CHECK-SUPPORTED-NOT: @"get_type_metadata 30nonisolated_nonsending_closure1PRzl31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcG.3"
42+
// CHECK-SUPPORTED: define linkonce_odr hidden ptr @"$s31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcGACyxGAA0F0AAWl"() #1 {
43+
// CHECK-SUPPORTED: call ptr @__swift_instantiateConcreteTypeFromMangledNameAbstract(ptr @"$s31associated_type_by_mangled_name9ProtoImplVyySiYaKYCcGMD")
44+
// CHECK-SUPPORTED: }
45+
struct MyStruct<T: P>: Proto {
46+
typealias Closure = nonisolated(nonsending) (Int) async throws -> Void
47+
48+
let x: T
49+
50+
public var value: some Proto {
51+
return ProtoImpl<Closure> { _ in }
52+
}
53+
}
54+
55+
print(makeThing(MyStruct(x: PImpl())))

0 commit comments

Comments
 (0)