Skip to content

Commit d9f21b7

Browse files
authored
Merge pull request swiftlang#22806 from slavapestov/imported-conformance-corner-case
SIL: Don't serialize imported conformances nested in non-public types
2 parents aff0709 + 72c8e78 commit d9f21b7

File tree

4 files changed

+57
-12
lines changed

4 files changed

+57
-12
lines changed

lib/SIL/SILWitnessTable.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
//
1313
// This file defines the SILWitnessTable class, which is used to map a protocol
1414
// conformance for a type to its implementing SILFunctions. This information is
15-
// (FIXME will be) used by IRGen to create witness tables for protocol dispatch.
15+
// used by IRGen to create witness tables for protocol dispatch.
16+
//
1617
// It can also be used by generic specialization and existential
17-
// devirtualization passes to promote witness_method and protocol_method
18-
// instructions to static function_refs.
18+
// devirtualization passes to promote witness_method instructions to static
19+
// function_refs.
1920
//
2021
//===----------------------------------------------------------------------===//
2122

@@ -24,7 +25,6 @@
2425
#include "swift/AST/ASTMangler.h"
2526
#include "swift/AST/Module.h"
2627
#include "swift/AST/ProtocolConformance.h"
27-
#include "swift/ClangImporter/ClangModule.h"
2828
#include "swift/SIL/SILModule.h"
2929
#include "llvm/ADT/SmallString.h"
3030

@@ -172,11 +172,6 @@ bool SILWitnessTable::conformanceIsSerialized(
172172
if (normalConformance && normalConformance->isResilient())
173173
return false;
174174

175-
// Serialize witness tables for conformances synthesized by
176-
// the ClangImporter.
177-
if (isa<ClangModuleUnit>(conformance->getDeclContext()->getModuleScopeContext()))
178-
return true;
179-
180175
if (conformance->getProtocol()->getEffectiveAccess() < AccessLevel::Public)
181176
return false;
182177

lib/SILGen/SILGenType.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -487,9 +487,18 @@ class SILGenConformance : public SILGenWitnessTable<SILGenConformance> {
487487
} else {
488488
// This is the "real" rule; the above case should go away once we
489489
// figure out what's going on.
490-
witnessLinkage = (witnessSerialized
491-
? SILLinkage::Shared
492-
: SILLinkage::Private);
490+
491+
// Normally witness thunks can be private.
492+
witnessLinkage = SILLinkage::Private;
493+
494+
// Unless the witness table is going to be serialized.
495+
if (witnessSerialized)
496+
witnessLinkage = SILLinkage::Shared;
497+
498+
// Or even if its not serialized, it might be for an imported
499+
// conformance in which case it can be emitted multiple times.
500+
if (Linkage == SILLinkage::Shared)
501+
witnessLinkage = SILLinkage::Shared;
493502
}
494503

495504
SILFunction *witnessFn = SGM.emitProtocolWitness(
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@class Public;
2+
@class Internal;
3+
4+
enum InternalInner { a, b, c } __attribute__((swift_name("Public.Inner")));
5+
enum PublicInner { d, e, f } __attribute__((swift_name("Internal.Inner")));
6+
enum TopLevel { g, h, i };
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// RUN: %target-swift-emit-silgen -sdk %S/Inputs -I %S/Inputs -enable-source-import %s -import-objc-header %S/Inputs/objc_witnesses_serialized.h | %FileCheck %s
2+
3+
// REQUIRES: objc_interop
4+
5+
import Foundation
6+
7+
func useRawRepresentable<T : RawRepresentable>(_: T) {}
8+
9+
// FIXME: getEffectiveClangContext() is broken and checks
10+
// for an explicit '@objc' attribute.
11+
12+
@objc public class Public : NSObject {
13+
func takesInner(_ value: Inner) {
14+
useRawRepresentable(value)
15+
}
16+
}
17+
18+
@objc internal class Internal : NSObject {
19+
func takesInner(_ value: Inner) {
20+
useRawRepresentable(value)
21+
}
22+
}
23+
24+
func takesTopLevel(_ value: TopLevel) {
25+
useRawRepresentable(value)
26+
}
27+
28+
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$sSo13InternalInnerVSYSCSY8rawValuexSg03RawD0Qz_tcfCTW : $@convention(witness_method: RawRepresentable) (@in UInt32, @thick Public.Inner.Type) -> @out Optional<Public.Inner>
29+
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$sSo13InternalInnerVSYSCSY8rawValue03RawD0QzvgTW : $@convention(witness_method: RawRepresentable) (@in_guaranteed Public.Inner) -> @out UInt32
30+
31+
// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$sSo11PublicInnerVSYSCSY8rawValuexSg03RawD0Qz_tcfCTW : $@convention(witness_method: RawRepresentable) (@in UInt32, @thick Internal.Inner.Type) -> @out Optional<Internal.Inner>
32+
// CHECK-LABEL: sil shared [transparent] [thunk] [ossa] @$sSo11PublicInnerVSYSCSY8rawValue03RawD0QzvgTW : $@convention(witness_method: RawRepresentable) (@in_guaranteed Internal.Inner) -> @out UInt32
33+
34+
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$sSo8TopLevelVSYSCSY8rawValuexSg03RawD0Qz_tcfCTW : $@convention(witness_method: RawRepresentable) (@in UInt32, @thick TopLevel.Type) -> @out Optional<TopLevel>
35+
// CHECK-LABEL: sil shared [transparent] [serialized] [thunk] [ossa] @$sSo8TopLevelVSYSCSY8rawValue03RawD0QzvgTW : $@convention(witness_method: RawRepresentable) (@in_guaranteed TopLevel) -> @out UInt32

0 commit comments

Comments
 (0)