Skip to content

Commit d50a310

Browse files
committed
IRGen: Fix issues when partial applying methods on resilient value types
Fixes <rdar://problem/28673540>.
1 parent 54ac82b commit d50a310

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

lib/IRGen/GenFunc.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM,
925925

926926
// If there's a data pointer required, grab it and load out the
927927
// extra, previously-curried parameters.
928-
} else if (!layout->isKnownEmpty()) {
928+
} else {
929929
unsigned origParamI = outType->getParameters().size();
930930
assert(layout->getElements().size() == conventions.size()
931931
&& "conventions don't match context layout");
@@ -1017,7 +1017,7 @@ static llvm::Function *emitPartialApplicationForwarder(IRGenModule &IGM,
10171017
// If the parameters can live independent of the context, release it now
10181018
// so we can tail call. The safety of this assumes that neither this release
10191019
// nor any of the loads can throw.
1020-
if (consumesContext && !dependsOnContextLifetime)
1020+
if (consumesContext && !dependsOnContextLifetime && rawData)
10211021
subIGF.emitNativeStrongRelease(rawData);
10221022
}
10231023

@@ -1357,7 +1357,7 @@ void irgen::emitFunctionPartialApplication(IRGenFunction &IGF,
13571357
layout);
13581358

13591359
llvm::Value *data;
1360-
if (layout.isKnownEmpty()) {
1360+
if (args.empty() && layout.isKnownEmpty()) {
13611361
data = IGF.IGM.RefCountedNull;
13621362
} else {
13631363
// Allocate a new object.

lib/IRGen/GenHeap.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,13 @@ HeapNonFixedOffsets::HeapNonFixedOffsets(IRGenFunction &IGF,
102102
case ElementLayout::Kind::NonFixed:
103103
// Start calculating non-fixed offsets from the end of the first fixed
104104
// field.
105+
if (i == 0) {
106+
totalAlign = elt.getType().getAlignmentMask(IGF, eltTy);
107+
offset = totalAlign;
108+
Offsets.push_back(totalAlign);
109+
break;
110+
}
111+
105112
assert(i > 0 && "shouldn't begin with a non-fixed field");
106113
auto &prevElt = layout.getElement(i-1);
107114
auto prevType = layout.getElementTypes()[i-1];

test/IRGen/struct_resilience.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,26 @@ public struct StructWithIndirectResilientEnum {
140140
// CHECK-NEXT: ret [[INT]] [[FIELD_PAYLOAD]]
141141

142142

143+
// Partial application of methods on resilient value types
144+
145+
public struct ResilientStructWithMethod {
146+
public func method() {}
147+
}
148+
149+
// Corner case -- type is address-only in SIL, but empty in IRGen
150+
151+
// CHECK-LABEL: define{{( protected)?}} void @_TF17struct_resilience29partialApplyOfResilientMethodFT1rVS_25ResilientStructWithMethod_T_(%V17struct_resilience25ResilientStructWithMethod* noalias nocapture)
152+
public func partialApplyOfResilientMethod(r: ResilientStructWithMethod) {
153+
_ = r.method
154+
}
155+
156+
// Type is address-only in SIL, and resilient in IRGen
157+
158+
// CHECK-LABEL: define{{( protected)?}} void @_TF17struct_resilience29partialApplyOfResilientMethodFT1sV16resilient_struct4Size_T_(%swift.opaque* noalias nocapture)
159+
public func partialApplyOfResilientMethod(s: Size) {
160+
_ = s.method
161+
}
162+
143163
// Public metadata accessor for our resilient struct
144164

145165
// CHECK-LABEL: define{{( protected)?}} %swift.type* @_TMaV17struct_resilience6MySize()

0 commit comments

Comments
 (0)