Skip to content

IRGen: Don't emit duplicate defintions for opaque type decls #61111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions lib/IRGen/GenStruct.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1443,10 +1443,13 @@ void IRGenModule::maybeEmitOpaqueTypeDecl(OpaqueTypeDecl *opaque) {
addRuntimeResolvableType(opaque);
if (IRGen.hasLazyMetadata(opaque))
IRGen.noteUseOfOpaqueTypeDescriptor(opaque);
else
emitOpaqueTypeDecl(opaque);
else {
if (IRGen.EmittedNonLazyOpaqueTypeDecls.insert(opaque).second)
emitOpaqueTypeDecl(opaque);
}
} else if (!IRGen.hasLazyMetadata(opaque)) {
emitOpaqueTypeDecl(opaque);
if (IRGen.EmittedNonLazyOpaqueTypeDecls.insert(opaque).second)
emitOpaqueTypeDecl(opaque);
}
}

Expand Down
4 changes: 4 additions & 0 deletions lib/IRGen/IRGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,10 @@ class IRGenerator {
llvm::DenseMap<OpaqueTypeDecl*, LazyOpaqueInfo> LazyOpaqueTypes;
/// The queue of opaque type descriptors to emit.
llvm::SmallVector<OpaqueTypeDecl*, 4> LazyOpaqueTypeDescriptors;
public:
/// The set of eagerly emitted opaque types.
llvm::SmallPtrSet<OpaqueTypeDecl *, 4> EmittedNonLazyOpaqueTypeDecls;
private:

/// The queue of lazy field metadata records to emit.
llvm::SmallVector<NominalTypeDecl *, 4> LazyFieldDescriptors;
Expand Down
42 changes: 42 additions & 0 deletions test/IRGen/always_emit_into_client_opaque_result.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// RUN: %target-swift-frontend -enable-library-evolution -emit-ir %s

// REQUIRES: OS=macosx

// This test used to crash with a duplicate LLVM IR definition.

@available(macOS 11.0, *)
public protocol Proto1 {}

@available(macOS 11.0, *)
public struct Thing {}

@available(macOS 11.0, *)
public struct Thing0: Proto1 {
public init() {}
}
@available(macOS 11.0, *)
@_marker public protocol MarkerProto {}

@available(macOS 11.0, *)
@frozen
@usableFromInline
struct LimitedAvailability: Proto1, MarkerProto {}

@available(macOS 11.0, *)
extension Thing {
@_alwaysEmitIntoClient
public static func doIt(
_ thingy: (any Proto1 & MarkerProto)?
) -> some Proto1 {
if #available(macOS 13.0, *) {
return thingy as! LimitedAvailability
} else {
return Thing0()
}
}
}

@available(macOS 11.0, *)
public func doIt(_ thingy: (any Proto1 & MarkerProto)?) -> some Proto1 {
return Thing.doIt(thingy)
}