Skip to content

Commit bbcc305

Browse files
Merge pull request swiftlang#75967 from aschwaighofer/non_copyable_deinit_private_field
IRGen: We cannot call destroy through metadata of private types of non-copyable fields
2 parents d88b799 + 50156f2 commit bbcc305

20 files changed

+269
-78
lines changed

lib/IRGen/FixedTypeInfo.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,9 @@ class FixedTypeInfo : public TypeInfo {
4646
IsBitwiseTakable_t bt,
4747
IsCopyable_t copy,
4848
IsFixedSize_t alwaysFixedSize,
49+
IsABIAccessible_t isABIAccessible,
4950
SpecialTypeInfoKind stik = SpecialTypeInfoKind::Fixed)
50-
: TypeInfo(type, align, pod, bt, copy, alwaysFixedSize, IsABIAccessible, stik),
51+
: TypeInfo(type, align, pod, bt, copy, alwaysFixedSize, isABIAccessible, stik),
5152
SpareBits(spareBits) {
5253
assert(SpareBits.size() == size.getValueInBits());
5354
assert(isFixedSize());
@@ -61,8 +62,9 @@ class FixedTypeInfo : public TypeInfo {
6162
IsBitwiseTakable_t bt,
6263
IsCopyable_t copy,
6364
IsFixedSize_t alwaysFixedSize,
65+
IsABIAccessible_t isABIAccessible,
6466
SpecialTypeInfoKind stik = SpecialTypeInfoKind::Fixed)
65-
: TypeInfo(type, align, pod, bt, copy, alwaysFixedSize, IsABIAccessible, stik),
67+
: TypeInfo(type, align, pod, bt, copy, alwaysFixedSize, isABIAccessible, stik),
6668
SpareBits(std::move(spareBits)) {
6769
assert(SpareBits.size() == size.getValueInBits());
6870
assert(isFixedSize());
@@ -73,7 +75,6 @@ class FixedTypeInfo : public TypeInfo {
7375
public:
7476
// This is useful for metaprogramming.
7577
static bool isFixed() { return true; }
76-
static IsABIAccessible_t isABIAccessible() { return IsABIAccessible; }
7778

7879
/// Whether this type is known to be empty.
7980
bool isKnownEmpty(ResilienceExpansion expansion) const {

lib/IRGen/GenConcurrency.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ class ExecutorTypeInfo :
4646
Size size, Alignment align, SpareBitVector &&spareBits)
4747
: TrivialScalarPairTypeInfo(storageType, size, std::move(spareBits),
4848
align, IsTriviallyDestroyable,
49-
IsCopyable, IsFixedSize) {}
49+
IsCopyable, IsFixedSize, IsABIAccessible) {}
5050

5151
static Size getFirstElementSize(IRGenModule &IGM) {
5252
return IGM.getPointerSize();

lib/IRGen/GenDiffFunc.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ class DifferentiableFuncTypeInfo final
9696
unsigned explosionSize, llvm::Type *ty, Size size,
9797
SpareBitVector &&spareBits, Alignment align,
9898
IsTriviallyDestroyable_t isTriviallyDestroyable, IsFixedSize_t alwaysFixedSize)
99-
: super(fields, explosionSize, ty, size, std::move(spareBits), align,
100-
isTriviallyDestroyable, IsCopyable, alwaysFixedSize) {}
99+
: super(fields, explosionSize, FieldsAreABIAccessible, ty, size, std::move(spareBits), align,
100+
isTriviallyDestroyable, IsCopyable, alwaysFixedSize, IsABIAccessible) {}
101101

102102
Address projectFieldAddress(IRGenFunction &IGF, Address addr, SILType T,
103103
const DifferentiableFuncFieldInfo &field) const {
@@ -174,12 +174,14 @@ class DifferentiableFuncTypeBuilder
174174
}
175175

176176
TypeInfo *createFixed(ArrayRef<DifferentiableFuncFieldInfo> fields,
177+
FieldsAreABIAccessible_t unused,
177178
StructLayout &&layout) {
178179
llvm_unreachable("@differentiable functions are always loadable");
179180
}
180181

181182
DifferentiableFuncTypeInfo *
182183
createLoadable(ArrayRef<DifferentiableFuncFieldInfo> fields,
184+
FieldsAreABIAccessible_t unused,
183185
StructLayout &&layout, unsigned explosionSize) {
184186
return DifferentiableFuncTypeInfo::create(
185187
fields, explosionSize, layout.getType(), layout.getSize(),
@@ -273,8 +275,8 @@ class LinearFuncTypeInfo final
273275
unsigned explosionSize, llvm::Type *ty, Size size,
274276
SpareBitVector &&spareBits, Alignment align, IsTriviallyDestroyable_t isTriviallyDestroyable,
275277
IsFixedSize_t alwaysFixedSize)
276-
: super(fields, explosionSize, ty, size, std::move(spareBits), align,
277-
isTriviallyDestroyable, IsCopyable, alwaysFixedSize) {}
278+
: super(fields, explosionSize, FieldsAreABIAccessible, ty, size, std::move(spareBits), align,
279+
isTriviallyDestroyable, IsCopyable, alwaysFixedSize, IsABIAccessible) {}
278280

279281
Address projectFieldAddress(IRGenFunction &IGF, Address addr, SILType T,
280282
const LinearFuncFieldInfo &field) const {
@@ -345,11 +347,13 @@ class LinearFuncTypeBuilder
345347
}
346348

347349
TypeInfo *createFixed(ArrayRef<LinearFuncFieldInfo> fields,
350+
FieldsAreABIAccessible_t areFieldsABIAccessible,
348351
StructLayout &&layout) {
349352
llvm_unreachable("@differentiable functions are always loadable");
350353
}
351354

352355
LinearFuncTypeInfo *createLoadable(ArrayRef<LinearFuncFieldInfo> fields,
356+
FieldsAreABIAccessible_t unused,
353357
StructLayout &&layout,
354358
unsigned explosionSize) {
355359
return LinearFuncTypeInfo::create(

lib/IRGen/GenEnum.cpp

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,13 @@ namespace {
663663
return;
664664
}
665665

666+
if (!ElementsAreABIAccessible) {
667+
auto temporary = TI->allocateStack(IGF, T, "deinit.arg").getAddress();
668+
cast<LoadableTypeInfo>(TI)->initialize(IGF, src, temporary, /*outlined*/false);
669+
emitDestroyCall(IGF, T, temporary);
670+
return;
671+
}
672+
666673
if (getLoadableSingleton())
667674
getLoadableSingleton()->consume(IGF, src, atomicity,
668675
getSingletonType(IGF.IGM, T));
@@ -677,7 +684,7 @@ namespace {
677684
if (tryEmitDestroyUsingDeinit(IGF, addr, T)) {
678685
return;
679686
}
680-
687+
681688
if (getSingleton() &&
682689
!getSingleton()->isTriviallyDestroyable(ResilienceExpansion::Maximal)) {
683690
if (!ElementsAreABIAccessible) {
@@ -1986,6 +1993,7 @@ namespace {
19861993

19871994
// If the payload is TriviallyDestroyable, then we can use TriviallyDestroyable value semantics.
19881995
auto &payloadTI = *ElementsWithPayload[0].ti;
1996+
19891997
if (!payloadTI.isABIAccessible()) {
19901998
CopyDestroyKind = ABIInaccessible;
19911999
} else if (payloadTI.isTriviallyDestroyable(ResilienceExpansion::Maximal)) {
@@ -2851,6 +2859,14 @@ namespace {
28512859
if (tryEmitConsumeUsingDeinit(IGF, src, T)) {
28522860
return;
28532861
}
2862+
2863+
if (!ElementsAreABIAccessible) {
2864+
auto temporary = TI->allocateStack(IGF, T, "deinit.arg").getAddress();
2865+
cast<LoadableTypeInfo>(TI)->initialize(IGF, src, temporary, /*outlined*/false);
2866+
emitDestroyCall(IGF, T, temporary);
2867+
return;
2868+
}
2869+
28542870
assert(TIK >= Loadable);
28552871

28562872
switch (CopyDestroyKind) {
@@ -4882,6 +4898,14 @@ namespace {
48824898
if (tryEmitConsumeUsingDeinit(IGF, src, T)) {
48834899
return;
48844900
}
4901+
4902+
if (!ElementsAreABIAccessible) {
4903+
auto temporary = TI->allocateStack(IGF, T, "deinit.arg").getAddress();
4904+
cast<LoadableTypeInfo>(TI)->initialize(IGF, src, temporary, /*outlined*/false);
4905+
emitDestroyCall(IGF, T, temporary);
4906+
return;
4907+
}
4908+
48854909
assert(TIK >= Loadable);
48864910
switch (CopyDestroyKind) {
48874911
case TriviallyDestroyable:
@@ -6407,7 +6431,6 @@ EnumImplStrategy::get(TypeConverter &TC, SILType type, EnumDecl *theEnum) {
64076431
// fixed-size from this resilience scope.
64086432
ResilienceExpansion layoutScope =
64096433
TC.IGM.getResilienceExpansionForLayout(theEnum);
6410-
64116434
for (auto elt : theEnum->getAllElements()) {
64126435
++numElements;
64136436

@@ -6693,10 +6716,11 @@ namespace {
66936716
IsTriviallyDestroyable_t isTriviallyDestroyable,
66946717
IsBitwiseTakable_t isBT,
66956718
IsCopyable_t copyable,
6696-
IsFixedSize_t alwaysFixedSize)
6719+
IsFixedSize_t alwaysFixedSize,
6720+
IsABIAccessible_t isABIAccessible)
66976721
: FixedEnumTypeInfoBase(strategy, T, S, std::move(SB), A,
66986722
isTriviallyDestroyable, isBT, copyable,
6699-
alwaysFixedSize) {}
6723+
alwaysFixedSize, isABIAccessible) {}
67006724
};
67016725

67026726
/// TypeInfo for loadable enum types.
@@ -6708,10 +6732,11 @@ namespace {
67086732
Alignment A,
67096733
IsTriviallyDestroyable_t isTriviallyDestroyable,
67106734
IsCopyable_t copyable,
6711-
IsFixedSize_t alwaysFixedSize)
6735+
IsFixedSize_t alwaysFixedSize,
6736+
IsABIAccessible_t isABIAccessible)
67126737
: FixedEnumTypeInfoBase(strategy, T, S, std::move(SB), A,
67136738
isTriviallyDestroyable, copyable,
6714-
alwaysFixedSize) {}
6739+
alwaysFixedSize, isABIAccessible) {}
67156740

67166741
void addToAggLowering(IRGenModule &IGM, SwiftAggLowering &lowering,
67176742
Size offset) const override {
@@ -6821,7 +6846,8 @@ EnumImplStrategy::getFixedEnumTypeInfo(llvm::StructType *T, Size S,
68216846
Alignment A,
68226847
IsTriviallyDestroyable_t isTriviallyDestroyable,
68236848
IsBitwiseTakable_t isBT,
6824-
IsCopyable_t isCopyable) {
6849+
IsCopyable_t isCopyable,
6850+
IsABIAccessible_t abiAccessible) {
68256851
TypeInfo *mutableTI;
68266852
switch (TIK) {
68276853
case Opaque:
@@ -6831,14 +6857,16 @@ EnumImplStrategy::getFixedEnumTypeInfo(llvm::StructType *T, Size S,
68316857
isTriviallyDestroyable,
68326858
isBT,
68336859
isCopyable,
6834-
AlwaysFixedSize);
6860+
AlwaysFixedSize,
6861+
abiAccessible);
68356862
break;
68366863
case Loadable:
68376864
assert(isBT && "loadable enum not bitwise takable?!");
68386865
mutableTI = new LoadableEnumTypeInfo(*this, T, S, std::move(SB), A,
68396866
isTriviallyDestroyable,
68406867
isCopyable,
6841-
AlwaysFixedSize);
6868+
AlwaysFixedSize,
6869+
abiAccessible);
68426870
break;
68436871
}
68446872
TI = mutableTI;
@@ -6859,7 +6887,8 @@ SingletonEnumImplStrategy::completeEnumTypeLayout(TypeConverter &TC,
68596887
alignment,
68606888
TriviallyDestroyable,
68616889
Copyable,
6862-
AlwaysFixedSize));
6890+
AlwaysFixedSize,
6891+
IsABIAccessible));
68636892
} else {
68646893
const TypeInfo &eltTI = *getSingleton();
68656894

@@ -6886,13 +6915,16 @@ SingletonEnumImplStrategy::completeEnumTypeLayout(TypeConverter &TC,
68866915
auto alignment = fixedEltTI.getFixedAlignment();
68876916
applyLayoutAttributes(TC.IGM, theEnum, /*fixed*/true, alignment);
68886917

6918+
auto isABIAccessible = isTypeABIAccessibleIfFixedSize(TC.IGM,
6919+
Type.getASTType());
68896920
return getFixedEnumTypeInfo(enumTy,
68906921
fixedEltTI.getFixedSize(),
68916922
fixedEltTI.getSpareBits(),
68926923
alignment,
68936924
TriviallyDestroyable,
68946925
BitwiseTakable,
6895-
Copyable);
6926+
Copyable,
6927+
isABIAccessible);
68966928
}
68976929
}
68986930
}
@@ -6927,7 +6959,8 @@ NoPayloadEnumImplStrategy::completeEnumTypeLayout(TypeConverter &TC,
69276959
alignment,
69286960
TriviallyDestroyable,
69296961
Copyable,
6930-
AlwaysFixedSize));
6962+
AlwaysFixedSize,
6963+
IsABIAccessible));
69316964
}
69326965

69336966
TypeInfo *
@@ -6976,7 +7009,8 @@ CCompatibleEnumImplStrategy::completeEnumTypeLayout(TypeConverter &TC,
69767009
alignment,
69777010
IsTriviallyDestroyable,
69787011
IsCopyable,
6979-
IsFixedSize));
7012+
IsFixedSize,
7013+
IsABIAccessible));
69807014
}
69817015

69827016
TypeInfo *SinglePayloadEnumImplStrategy::completeFixedLayout(
@@ -7044,11 +7078,15 @@ TypeInfo *SinglePayloadEnumImplStrategy::completeFixedLayout(
70447078
? IsNotTriviallyDestroyable : IsTriviallyDestroyable;
70457079
auto copyable = !theEnum->canBeCopyable()
70467080
? IsNotCopyable : IsCopyable;
7081+
7082+
auto isABIAccessible = isTypeABIAccessibleIfFixedSize(TC.IGM,
7083+
Type.getASTType());
70477084
getFixedEnumTypeInfo(
70487085
enumTy, Size(sizeWithTag), spareBits.build(), alignment,
70497086
deinit & payloadTI.isTriviallyDestroyable(ResilienceExpansion::Maximal),
70507087
payloadTI.isBitwiseTakable(ResilienceExpansion::Maximal),
7051-
copyable);
7088+
copyable, isABIAccessible);
7089+
70527090
if (TIK >= Loadable && CopyDestroyKind == Normal) {
70537091
computePayloadTypesAndTagType(TC.IGM, *TI, PayloadTypesAndTagType);
70547092
loweredType = Type;
@@ -7255,9 +7293,12 @@ MultiPayloadEnumImplStrategy::completeFixedLayout(TypeConverter &TC,
72557293

72567294
applyLayoutAttributes(TC.IGM, theEnum, /*fixed*/ true, worstAlignment);
72577295

7296+
auto isABIAccessible = isTypeABIAccessibleIfFixedSize(TC.IGM,
7297+
Type.getASTType());
72587298
getFixedEnumTypeInfo(enumTy, Size(sizeWithTag), std::move(spareBits),
72597299
worstAlignment, isTriviallyDestroyable, isBT,
7260-
isCopyable);
7300+
isCopyable, isABIAccessible);
7301+
72617302
if (TIK >= Loadable &&
72627303
(CopyDestroyKind == Normal || CopyDestroyKind == BitwiseTakable)) {
72637304
computePayloadTypesAndTagType(TC.IGM, *TI, PayloadTypesAndTagType);

lib/IRGen/GenEnum.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ class EnumImplStrategy {
180180
Alignment A,
181181
IsTriviallyDestroyable_t isTriviallyDestroyable,
182182
IsBitwiseTakable_t isBT,
183-
IsCopyable_t isCopyable);
183+
IsCopyable_t isCopyable,
184+
IsABIAccessible_t abiAccessible);
184185

185186
public:
186187
virtual ~EnumImplStrategy() { }

lib/IRGen/GenExistential.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -689,7 +689,8 @@ namespace {
689689
align, IsNotTriviallyDestroyable, \
690690
IsNotBitwiseTakable, \
691691
IsCopyable, \
692-
IsFixedSize), \
692+
IsFixedSize, \
693+
IsABIAccessible), \
693694
IsOptional(isOptional) {} \
694695
TypeLayoutEntry \
695696
*buildTypeLayoutEntry(IRGenModule &IGM, \
@@ -747,7 +748,7 @@ namespace {
747748
spareBits, align, \
748749
IsNotTriviallyDestroyable, \
749750
IsCopyable, \
750-
IsFixedSize), \
751+
IsFixedSize, IsABIAccessible), \
751752
Refcounting(refcounting), ValueType(valueTy), IsOptional(isOptional) { \
752753
assert(refcounting == ReferenceCounting::Native || \
753754
refcounting == ReferenceCounting::Unknown); \
@@ -816,7 +817,7 @@ namespace {
816817
bool isOptional) \
817818
: ScalarExistentialTypeInfoBase(storedProtocols, ty, size, \
818819
spareBits, align, IsTriviallyDestroyable,\
819-
IsCopyable, IsFixedSize), \
820+
IsCopyable, IsFixedSize, IsABIAccessible), \
820821
IsOptional(isOptional) {} \
821822
TypeLayoutEntry \
822823
*buildTypeLayoutEntry(IRGenModule &IGM, \
@@ -904,7 +905,7 @@ class OpaqueExistentialTypeInfo final :
904905
: super(protocols, ty, size,
905906
std::move(spareBits), align,
906907
IsNotTriviallyDestroyable, IsBitwiseTakable, IsCopyable,
907-
IsFixedSize) {}
908+
IsFixedSize, IsABIAccessible) {}
908909

909910
public:
910911
OpaqueExistentialLayout getLayout() const {
@@ -1402,7 +1403,7 @@ class ExistentialMetatypeTypeInfo final
14021403
std::move(spareBits), align,
14031404
IsTriviallyDestroyable,
14041405
IsCopyable,
1405-
IsFixedSize),
1406+
IsFixedSize, IsABIAccessible),
14061407
MetatypeTI(metatypeTI) {}
14071408

14081409
public:

lib/IRGen/GenFunc.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ namespace {
504504
IsTriviallyDestroyable_t pod, IsBitwiseTakable_t bt, Size captureOffset)
505505
: IndirectTypeInfo(type, size, std::move(spareBits), align, pod, bt,
506506
IsCopyable,
507-
IsFixedSize),
507+
IsFixedSize, IsABIAccessible),
508508
CaptureOffset(captureOffset)
509509
{}
510510

lib/IRGen/GenHeap.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ namespace {
7474
SpareBitVector &&spareBits, \
7575
bool isOptional) \
7676
: IndirectTypeInfo(type, size, std::move(spareBits), alignment, \
77-
IsNotTriviallyDestroyable, IsNotBitwiseTakable, IsCopyable, IsFixedSize), \
77+
IsNotTriviallyDestroyable, IsNotBitwiseTakable, IsCopyable, IsFixedSize, IsABIAccessible), \
7878
ValueTypeAndIsOptional(valueType, isOptional) {} \
7979
void initializeWithCopy(IRGenFunction &IGF, Address destAddr, \
8080
Address srcAddr, SILType T, \
@@ -151,7 +151,7 @@ namespace {
151151
: SingleScalarTypeInfo(type, size, std::move(spareBits), \
152152
alignment, IsNotTriviallyDestroyable, \
153153
IsCopyable, \
154-
IsFixedSize), \
154+
IsFixedSize, IsABIAccessible), \
155155
ValueTypeAndIsOptional(valueType, isOptional) {} \
156156
enum { IsScalarTriviallyDestroyable = false }; \
157157
TypeLayoutEntry \

lib/IRGen/GenIntegerLiteral.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class IntegerLiteralTypeInfo :
4444
IntegerLiteralTypeInfo(llvm::StructType *storageType,
4545
Size size, Alignment align, SpareBitVector &&spareBits)
4646
: TrivialScalarPairTypeInfo(storageType, size, std::move(spareBits), align,
47-
IsTriviallyDestroyable, IsCopyable, IsFixedSize) {}
47+
IsTriviallyDestroyable, IsCopyable, IsFixedSize, IsABIAccessible) {}
4848

4949
static Size getFirstElementSize(IRGenModule &IGM) {
5050
return IGM.getPointerSize();

0 commit comments

Comments
 (0)