Skip to content

Commit 9fc5bb1

Browse files
Merge pull request #61111 from aschwaighofer/non_unique_opaque_type_decl_emission
IRGen: Don't emit duplicate defintions for opaque type decls
2 parents 57052f0 + 2b556bc commit 9fc5bb1

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

lib/IRGen/GenStruct.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1443,10 +1443,13 @@ void IRGenModule::maybeEmitOpaqueTypeDecl(OpaqueTypeDecl *opaque) {
14431443
addRuntimeResolvableType(opaque);
14441444
if (IRGen.hasLazyMetadata(opaque))
14451445
IRGen.noteUseOfOpaqueTypeDescriptor(opaque);
1446-
else
1447-
emitOpaqueTypeDecl(opaque);
1446+
else {
1447+
if (IRGen.EmittedNonLazyOpaqueTypeDecls.insert(opaque).second)
1448+
emitOpaqueTypeDecl(opaque);
1449+
}
14481450
} else if (!IRGen.hasLazyMetadata(opaque)) {
1449-
emitOpaqueTypeDecl(opaque);
1451+
if (IRGen.EmittedNonLazyOpaqueTypeDecls.insert(opaque).second)
1452+
emitOpaqueTypeDecl(opaque);
14501453
}
14511454
}
14521455

lib/IRGen/IRGenModule.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,10 @@ class IRGenerator {
301301
llvm::DenseMap<OpaqueTypeDecl*, LazyOpaqueInfo> LazyOpaqueTypes;
302302
/// The queue of opaque type descriptors to emit.
303303
llvm::SmallVector<OpaqueTypeDecl*, 4> LazyOpaqueTypeDescriptors;
304+
public:
305+
/// The set of eagerly emitted opaque types.
306+
llvm::SmallPtrSet<OpaqueTypeDecl *, 4> EmittedNonLazyOpaqueTypeDecls;
307+
private:
304308

305309
/// The queue of lazy field metadata records to emit.
306310
llvm::SmallVector<NominalTypeDecl *, 4> LazyFieldDescriptors;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// RUN: %target-swift-frontend -enable-library-evolution -emit-ir %s
2+
3+
// REQUIRES: OS=macosx
4+
5+
// This test used to crash with a duplicate LLVM IR definition.
6+
7+
@available(macOS 11.0, *)
8+
public protocol Proto1 {}
9+
10+
@available(macOS 11.0, *)
11+
public struct Thing {}
12+
13+
@available(macOS 11.0, *)
14+
public struct Thing0: Proto1 {
15+
public init() {}
16+
}
17+
@available(macOS 11.0, *)
18+
@_marker public protocol MarkerProto {}
19+
20+
@available(macOS 11.0, *)
21+
@frozen
22+
@usableFromInline
23+
struct LimitedAvailability: Proto1, MarkerProto {}
24+
25+
@available(macOS 11.0, *)
26+
extension Thing {
27+
@_alwaysEmitIntoClient
28+
public static func doIt(
29+
_ thingy: (any Proto1 & MarkerProto)?
30+
) -> some Proto1 {
31+
if #available(macOS 13.0, *) {
32+
return thingy as! LimitedAvailability
33+
} else {
34+
return Thing0()
35+
}
36+
}
37+
}
38+
39+
@available(macOS 11.0, *)
40+
public func doIt(_ thingy: (any Proto1 & MarkerProto)?) -> some Proto1 {
41+
return Thing.doIt(thingy)
42+
}

0 commit comments

Comments
 (0)