@@ -659,7 +659,15 @@ namespace {
659659 void consume (IRGenFunction &IGF, Explosion &src,
660660 Atomicity atomicity,
661661 SILType T) const override {
662- if (tryEmitConsumeUsingDeinit (IGF, src, T)) {
662+ if (ElementsAreABIAccessible &&
663+ tryEmitConsumeUsingDeinit (IGF, src, T)) {
664+ return ;
665+ }
666+
667+ if (!ElementsAreABIAccessible) {
668+ auto temporary = TI->allocateStack (IGF, T, " deinit.arg" ).getAddress ();
669+ cast<LoadableTypeInfo>(TI)->initialize (IGF, src, temporary, /* outlined*/ false );
670+ emitDestroyCall (IGF, T, temporary);
663671 return ;
664672 }
665673
@@ -674,10 +682,11 @@ namespace {
674682
675683 void destroy (IRGenFunction &IGF, Address addr, SILType T,
676684 bool isOutlined) const override {
677- if (tryEmitDestroyUsingDeinit (IGF, addr, T)) {
685+ if (ElementsAreABIAccessible &&
686+ tryEmitDestroyUsingDeinit (IGF, addr, T)) {
678687 return ;
679688 }
680-
689+
681690 if (getSingleton () &&
682691 !getSingleton ()->isTriviallyDestroyable (ResilienceExpansion::Maximal)) {
683692 if (!ElementsAreABIAccessible) {
@@ -1986,6 +1995,7 @@ namespace {
19861995
19871996 // If the payload is TriviallyDestroyable, then we can use TriviallyDestroyable value semantics.
19881997 auto &payloadTI = *ElementsWithPayload[0 ].ti ;
1998+
19891999 if (!payloadTI.isABIAccessible ()) {
19902000 CopyDestroyKind = ABIInaccessible;
19912001 } else if (payloadTI.isTriviallyDestroyable (ResilienceExpansion::Maximal)) {
@@ -2848,9 +2858,18 @@ namespace {
28482858
28492859 void consume (IRGenFunction &IGF, Explosion &src,
28502860 Atomicity atomicity, SILType T) const override {
2851- if (tryEmitConsumeUsingDeinit (IGF, src, T)) {
2861+ if (ElementsAreABIAccessible &&
2862+ tryEmitConsumeUsingDeinit (IGF, src, T)) {
28522863 return ;
28532864 }
2865+
2866+ if (!ElementsAreABIAccessible) {
2867+ auto temporary = TI->allocateStack (IGF, T, " deinit.arg" ).getAddress ();
2868+ cast<LoadableTypeInfo>(TI)->initialize (IGF, src, temporary, /* outlined*/ false );
2869+ emitDestroyCall (IGF, T, temporary);
2870+ return ;
2871+ }
2872+
28542873 assert (TIK >= Loadable);
28552874
28562875 switch (CopyDestroyKind) {
@@ -2968,7 +2987,8 @@ namespace {
29682987
29692988 void destroy (IRGenFunction &IGF, Address addr, SILType T,
29702989 bool isOutlined) const override {
2971- if (tryEmitDestroyUsingDeinit (IGF, addr, T)) {
2990+ if (ElementsAreABIAccessible &&
2991+ tryEmitDestroyUsingDeinit (IGF, addr, T)) {
29722992 return ;
29732993 }
29742994
@@ -4879,9 +4899,18 @@ namespace {
48794899
48804900 void consume (IRGenFunction &IGF, Explosion &src,
48814901 Atomicity atomicity, SILType T) const override {
4882- if (tryEmitConsumeUsingDeinit (IGF, src, T)) {
4902+ if (ElementsAreABIAccessible &&
4903+ tryEmitConsumeUsingDeinit (IGF, src, T)) {
48834904 return ;
48844905 }
4906+
4907+ if (!ElementsAreABIAccessible) {
4908+ auto temporary = TI->allocateStack (IGF, T, " deinit.arg" ).getAddress ();
4909+ cast<LoadableTypeInfo>(TI)->initialize (IGF, src, temporary, /* outlined*/ false );
4910+ emitDestroyCall (IGF, T, temporary);
4911+ return ;
4912+ }
4913+
48854914 assert (TIK >= Loadable);
48864915 switch (CopyDestroyKind) {
48874916 case TriviallyDestroyable:
@@ -5230,7 +5259,8 @@ namespace {
52305259
52315260 void destroy (IRGenFunction &IGF, Address addr, SILType T,
52325261 bool isOutlined) const override {
5233- if (tryEmitDestroyUsingDeinit (IGF, addr, T)) {
5262+ if (ElementsAreABIAccessible &&
5263+ tryEmitDestroyUsingDeinit (IGF, addr, T)) {
52345264 return ;
52355265 }
52365266
@@ -6407,7 +6437,6 @@ EnumImplStrategy::get(TypeConverter &TC, SILType type, EnumDecl *theEnum) {
64076437 // fixed-size from this resilience scope.
64086438 ResilienceExpansion layoutScope =
64096439 TC.IGM .getResilienceExpansionForLayout (theEnum);
6410-
64116440 for (auto elt : theEnum->getAllElements ()) {
64126441 ++numElements;
64136442
@@ -6652,8 +6681,6 @@ namespace {
66526681 public:
66536682 using EnumTypeInfoBase<Base>::Strategy;
66546683
6655- // / \group Methods delegated to the EnumImplStrategy
6656-
66576684 unsigned getFixedExtraInhabitantCount (IRGenModule &IGM) const override {
66586685 return Strategy.getFixedExtraInhabitantCount (IGM);
66596686 }
@@ -6693,10 +6720,11 @@ namespace {
66936720 IsTriviallyDestroyable_t isTriviallyDestroyable,
66946721 IsBitwiseTakable_t isBT,
66956722 IsCopyable_t copyable,
6696- IsFixedSize_t alwaysFixedSize)
6723+ IsFixedSize_t alwaysFixedSize,
6724+ IsABIAccessible_t isABIAccessible)
66976725 : FixedEnumTypeInfoBase(strategy, T, S, std::move(SB), A,
66986726 isTriviallyDestroyable, isBT, copyable,
6699- alwaysFixedSize) {}
6727+ alwaysFixedSize, isABIAccessible ) {}
67006728 };
67016729
67026730 // / TypeInfo for loadable enum types.
@@ -6708,10 +6736,11 @@ namespace {
67086736 Alignment A,
67096737 IsTriviallyDestroyable_t isTriviallyDestroyable,
67106738 IsCopyable_t copyable,
6711- IsFixedSize_t alwaysFixedSize)
6739+ IsFixedSize_t alwaysFixedSize,
6740+ IsABIAccessible_t isABIAccessible)
67126741 : FixedEnumTypeInfoBase(strategy, T, S, std::move(SB), A,
67136742 isTriviallyDestroyable, copyable,
6714- alwaysFixedSize) {}
6743+ alwaysFixedSize, isABIAccessible ) {}
67156744
67166745 void addToAggLowering (IRGenModule &IGM, SwiftAggLowering &lowering,
67176746 Size offset) const override {
@@ -6821,7 +6850,8 @@ EnumImplStrategy::getFixedEnumTypeInfo(llvm::StructType *T, Size S,
68216850 Alignment A,
68226851 IsTriviallyDestroyable_t isTriviallyDestroyable,
68236852 IsBitwiseTakable_t isBT,
6824- IsCopyable_t isCopyable) {
6853+ IsCopyable_t isCopyable,
6854+ IsABIAccessible_t abiAccessible) {
68256855 TypeInfo *mutableTI;
68266856 switch (TIK) {
68276857 case Opaque:
@@ -6831,14 +6861,16 @@ EnumImplStrategy::getFixedEnumTypeInfo(llvm::StructType *T, Size S,
68316861 isTriviallyDestroyable,
68326862 isBT,
68336863 isCopyable,
6834- AlwaysFixedSize);
6864+ AlwaysFixedSize,
6865+ abiAccessible);
68356866 break ;
68366867 case Loadable:
68376868 assert (isBT && " loadable enum not bitwise takable?!" );
68386869 mutableTI = new LoadableEnumTypeInfo (*this , T, S, std::move (SB), A,
68396870 isTriviallyDestroyable,
68406871 isCopyable,
6841- AlwaysFixedSize);
6872+ AlwaysFixedSize,
6873+ abiAccessible);
68426874 break ;
68436875 }
68446876 TI = mutableTI;
@@ -6859,7 +6891,8 @@ SingletonEnumImplStrategy::completeEnumTypeLayout(TypeConverter &TC,
68596891 alignment,
68606892 TriviallyDestroyable,
68616893 Copyable,
6862- AlwaysFixedSize));
6894+ AlwaysFixedSize,
6895+ IsABIAccessible));
68636896 } else {
68646897 const TypeInfo &eltTI = *getSingleton ();
68656898
@@ -6886,13 +6919,19 @@ SingletonEnumImplStrategy::completeEnumTypeLayout(TypeConverter &TC,
68866919 auto alignment = fixedEltTI.getFixedAlignment ();
68876920 applyLayoutAttributes (TC.IGM , theEnum, /* fixed*/ true , alignment);
68886921
6922+ IsABIAccessible_t isABIAccessible = IsABIAccessible;
6923+ if (Type.getASTType ()->isNoncopyable () &&
6924+ !IGM.getSILModule ().isTypeMetadataAccessible (Type.getASTType ()))
6925+ isABIAccessible = IsNotABIAccessible;
6926+
68896927 return getFixedEnumTypeInfo (enumTy,
68906928 fixedEltTI.getFixedSize (),
68916929 fixedEltTI.getSpareBits (),
68926930 alignment,
68936931 TriviallyDestroyable,
68946932 BitwiseTakable,
6895- Copyable);
6933+ Copyable,
6934+ isABIAccessible);
68966935 }
68976936 }
68986937}
@@ -6927,7 +6966,8 @@ NoPayloadEnumImplStrategy::completeEnumTypeLayout(TypeConverter &TC,
69276966 alignment,
69286967 TriviallyDestroyable,
69296968 Copyable,
6930- AlwaysFixedSize));
6969+ AlwaysFixedSize,
6970+ IsABIAccessible));
69316971}
69326972
69336973TypeInfo *
@@ -6976,7 +7016,8 @@ CCompatibleEnumImplStrategy::completeEnumTypeLayout(TypeConverter &TC,
69767016 alignment,
69777017 IsTriviallyDestroyable,
69787018 IsCopyable,
6979- IsFixedSize));
7019+ IsFixedSize,
7020+ IsABIAccessible));
69807021}
69817022
69827023TypeInfo *SinglePayloadEnumImplStrategy::completeFixedLayout (
@@ -7044,11 +7085,18 @@ TypeInfo *SinglePayloadEnumImplStrategy::completeFixedLayout(
70447085 ? IsNotTriviallyDestroyable : IsTriviallyDestroyable;
70457086 auto copyable = !theEnum->canBeCopyable ()
70467087 ? IsNotCopyable : IsCopyable;
7088+
7089+ IsABIAccessible_t isABIAccessible = IsABIAccessible;
7090+ if (Type.getASTType ()->isNoncopyable () &&
7091+ !IGM.getSILModule ().isTypeMetadataAccessible (Type.getASTType ()))
7092+ isABIAccessible = IsNotABIAccessible;
7093+
70477094 getFixedEnumTypeInfo (
70487095 enumTy, Size (sizeWithTag), spareBits.build (), alignment,
70497096 deinit & payloadTI.isTriviallyDestroyable (ResilienceExpansion::Maximal),
70507097 payloadTI.isBitwiseTakable (ResilienceExpansion::Maximal),
7051- copyable);
7098+ copyable, isABIAccessible);
7099+
70527100 if (TIK >= Loadable && CopyDestroyKind == Normal) {
70537101 computePayloadTypesAndTagType (TC.IGM , *TI, PayloadTypesAndTagType);
70547102 loweredType = Type;
@@ -7255,9 +7303,15 @@ MultiPayloadEnumImplStrategy::completeFixedLayout(TypeConverter &TC,
72557303
72567304 applyLayoutAttributes (TC.IGM , theEnum, /* fixed*/ true , worstAlignment);
72577305
7306+ IsABIAccessible_t isABIAccessible = IsABIAccessible;
7307+ if (Type.getASTType ()->isNoncopyable () &&
7308+ !IGM.getSILModule ().isTypeMetadataAccessible (Type.getASTType ()))
7309+ isABIAccessible = IsNotABIAccessible;
7310+
72587311 getFixedEnumTypeInfo (enumTy, Size (sizeWithTag), std::move (spareBits),
72597312 worstAlignment, isTriviallyDestroyable, isBT,
7260- isCopyable);
7313+ isCopyable, isABIAccessible);
7314+
72617315 if (TIK >= Loadable &&
72627316 (CopyDestroyKind == Normal || CopyDestroyKind == BitwiseTakable)) {
72637317 computePayloadTypesAndTagType (TC.IGM , *TI, PayloadTypesAndTagType);
0 commit comments