Skip to content

Commit f3eca93

Browse files
committed
[IRGen] Don't use mangled names for metadata including Span et al when back-deploying
If back-deploying prior to the introduction of name mangling and runtime support for invertible constraints (~Copyable, ~Escapable), don't use mangled names to access metadata. The code already existed for this, but had a carve-out that still used mangled names for standard library types that have always existed but got generalized to support non-copyable & non-escapable types. Tweak that carve-out to not apply to types like Span that come from a back-deployment library. Fixes crashes when using metadata for Span et al on older platforms. Fixes rdar://155639204.
1 parent d10b3f8 commit f3eca93

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

lib/IRGen/GenReflection.cpp

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,25 @@ class PrintMetadataSource
177177
}
178178
};
179179

180+
/// Determine whether the given generic nominal that involves inverse
181+
/// requirements (e.g., Optional, Span) is always available for demangling
182+
/// purposes.
183+
static bool nominalIsAlwaysAvailableForDemangling(const NominalTypeDecl *nom) {
184+
// Only consider standard library types for this.
185+
if (!nom->getModuleContext()->isStdlibModule())
186+
return false;
187+
188+
// If there's an @_originallyDefined(in:) attribute, then the nominal is
189+
// not always available for demangling.
190+
for (auto attr: nom->getAttrs().getAttributes<OriginallyDefinedInAttr>()) {
191+
if (!attr->isInvalid() && attr->isActivePlatform(nom->getASTContext()))
192+
return false;
193+
}
194+
195+
// Everything else is available.
196+
return true;
197+
}
198+
180199
std::optional<llvm::VersionTuple>
181200
getRuntimeVersionThatSupportsDemanglingType(CanType type) {
182201
enum VersionRequirement {
@@ -246,16 +265,16 @@ getRuntimeVersionThatSupportsDemanglingType(CanType type) {
246265
/// signature uses NoncopyableGenerics. Since inverses are mangled into
247266
/// symbols, a Swift 6.0+ runtime is generally needed to demangle them.
248267
///
249-
/// We make an exception for types in the stdlib, like Optional, since the
250-
/// runtime should still be able to demangle them, based on the availability
251-
/// of the type.
268+
/// We make an exception for some types in the stdlib, like Optional, since
269+
/// the runtime should still be able to demangle them, based on the
270+
/// availability of the type.
252271
if (auto nominalTy = dyn_cast<NominalOrBoundGenericNominalType>(t)) {
253272
auto *nom = nominalTy->getDecl();
254273
if (auto sig = nom->getGenericSignature()) {
255274
SmallVector<InverseRequirement, 2> inverses;
256275
SmallVector<Requirement, 2> reqs;
257276
sig->getRequirementsWithInverses(reqs, inverses);
258-
if (!inverses.empty() && !nom->getModuleContext()->isStdlibModule()) {
277+
if (!inverses.empty() && !nominalIsAlwaysAvailableForDemangling(nom)) {
259278
return addRequirement(Swift_6_0);
260279
}
261280
}

test/IRGen/backward_deploy_span.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-swift-frontend -target %target-cpu-apple-macos12 -emit-ir -o - -primary-file %s | %FileCheck %s
2+
// REQUIRES: concurrency
3+
// REQUIRES: OS=macosx
4+
5+
func useGenericMetatype(_ type: any ~Escapable.Type) { }
6+
7+
// CHECK-LABEL: define hidden swiftcc void @"$s20backward_deploy_span11testSpanIntyyF"()
8+
func testSpanInt() {
9+
// CHECK: call swiftcc %swift.metadata_response @"$ss4SpanVySiGMa"
10+
// CHECK: call swiftcc void @"$s20backward_deploy_span18useGenericMetatypeyyypRi0_s_XPXpF"
11+
useGenericMetatype(Span<Int>.self)
12+
}
13+
14+
// CHECK-LABEL: define linkonce_odr hidden swiftcc %swift.metadata_response @"$ss4SpanVySiGMa"(i64 %0)
15+
// CHECK: call swiftcc %swift.metadata_response @"$ss4SpanVMa"(i64 %0, ptr @"$sSiN")
16+
17+

0 commit comments

Comments
 (0)