Skip to content

Commit d5de496

Browse files
committed
IRGen: Private opaque result types from another TU are not ABI accessible
rdar://76416817
1 parent 861f47f commit d5de496

File tree

4 files changed

+49
-7
lines changed

4 files changed

+49
-7
lines changed

lib/IRGen/GenArchetype.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,13 @@ namespace {
9595
class OpaqueArchetypeTypeInfo
9696
: public ResilientTypeInfo<OpaqueArchetypeTypeInfo>
9797
{
98-
OpaqueArchetypeTypeInfo(llvm::Type *type)
99-
: ResilientTypeInfo(type, IsABIAccessible) {}
98+
OpaqueArchetypeTypeInfo(llvm::Type *type, IsABIAccessible_t abiAccessible)
99+
: ResilientTypeInfo(type, abiAccessible) {}
100100

101101
public:
102-
static const OpaqueArchetypeTypeInfo *create(llvm::Type *type) {
103-
return new OpaqueArchetypeTypeInfo(type);
102+
static const OpaqueArchetypeTypeInfo *
103+
create(llvm::Type *type, IsABIAccessible_t abiAccessible) {
104+
return new OpaqueArchetypeTypeInfo(type, abiAccessible);
104105
}
105106

106107
void collectMetadataForOutlining(OutliningMetadataCollector &collector,
@@ -342,7 +343,18 @@ const TypeInfo *TypeConverter::convertArchetypeType(ArchetypeType *archetype) {
342343

343344
// Otherwise, for now, always use an opaque indirect type.
344345
llvm::Type *storageType = IGM.OpaquePtrTy->getElementType();
345-
return OpaqueArchetypeTypeInfo::create(storageType);
346+
347+
// Opaque result types can be private and from a different module. In this
348+
// case we can't access their type metadata from another module.
349+
IsABIAccessible_t abiAccessible = IsABIAccessible;
350+
if (auto opaqueArchetype = dyn_cast<OpaqueTypeArchetypeType>(archetype)) {
351+
auto &currentSILModule = IGM.getSILModule();
352+
abiAccessible =
353+
currentSILModule.isTypeMetadataAccessible(archetype->getCanonicalType())
354+
? IsABIAccessible
355+
: IsNotABIAccessible;
356+
}
357+
return OpaqueArchetypeTypeInfo::create(storageType, abiAccessible);
346358
}
347359

348360
static void setMetadataRef(IRGenFunction &IGF,

lib/SIL/IR/SIL.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,14 @@ bool SILModule::isTypeMetadataAccessible(CanType type) {
107107
return !type.findIf([&](CanType type) {
108108
// Note that this function returns true if the type is *illegal* to use.
109109

110-
// Ignore non-nominal types.
111-
auto decl = type.getNominalOrBoundGenericNominal();
110+
// Ignore non-nominal types -- except for opaque result types which can be
111+
// private and in a different translation unit in which case they can't be
112+
// accessed.
113+
ValueDecl *decl = type.getNominalOrBoundGenericNominal();
114+
if (!decl)
115+
decl = isa<OpaqueTypeArchetypeType>(type)
116+
? cast<OpaqueTypeArchetypeType>(type)->getDecl()
117+
: nullptr;
112118
if (!decl)
113119
return false;
114120

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
public protocol P { }
2+
3+
extension Int : P {}
4+
5+
struct Container {
6+
// This opaque result type is private to this file and its type metadata is
7+
// not accessible from another TU. Therefore, Container's fields are not ABI
8+
// accessible from another TU.
9+
private let mem : some P = 5
10+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-frontend -disable-availability-checking -emit-ir -primary-file %s %S/Inputs/opaque_result_type_private_typemetadata2.swift | %FileCheck %s
2+
3+
// Container's fields are not ABI accessible so copying Container must use its
4+
// metadata instead of exploding its fields.
5+
6+
// CHECK: define{{.*}} swiftcc void @"$s39opaque_result_type_private_typemetadata4doItyyF"()
7+
// CHECK-NOT: ret void
8+
// CHECK: call {{.*}} @"$s39opaque_result_type_private_typemetadata9ContainerVMa"(
9+
// CHECK: ret void
10+
11+
public func doIt() {
12+
var x = Container()
13+
var y = x
14+
}

0 commit comments

Comments
 (0)