Skip to content

Commit cf0e656

Browse files
committed
Make sure the sret type matches the type of the pointee type.
1 parent 708195a commit cf0e656

File tree

3 files changed

+21
-17
lines changed

3 files changed

+21
-17
lines changed

lib/IRGen/GenCall.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ namespace {
474474

475475
private:
476476
const TypeInfo &expand(SILParameterInfo param);
477-
llvm::Type *addIndirectResult();
477+
llvm::Type *addIndirectResult(SILType resultType);
478478

479479
SILFunctionConventions getSILFuncConventions() const {
480480
return SILFunctionConventions(FnType, IGM.getSILModule());
@@ -532,9 +532,7 @@ namespace {
532532
} // end namespace irgen
533533
} // end namespace swift
534534

535-
llvm::Type *SignatureExpansion::addIndirectResult() {
536-
auto resultType = getSILFuncConventions().getSILResultType(
537-
IGM.getMaximalTypeExpansionContext());
535+
llvm::Type *SignatureExpansion::addIndirectResult(SILType resultType) {
538536
const TypeInfo &resultTI = IGM.getTypeInfo(resultType);
539537
auto storageTy = resultTI.getStorageType();
540538
addIndirectResultAttributes(IGM, Attrs, ParamIRTypes.size(), claimSRet(),
@@ -941,7 +939,7 @@ SignatureExpansion::expandDirectResult() {
941939
auto &ti = IGM.getTypeInfo(resultType);
942940
auto &native = ti.nativeReturnValueSchema(IGM);
943941
if (native.requiresIndirect())
944-
return std::make_pair(addIndirectResult(), nullptr);
942+
return std::make_pair(addIndirectResult(resultType), nullptr);
945943

946944
// Disable the use of sret if we have a non-trivial direct result.
947945
if (!native.empty()) CanUseSRet = false;
@@ -1582,16 +1580,18 @@ void SignatureExpansion::expandExternalSignatureTypes() {
15821580

15831581
// If we return indirectly, that is the first parameter type.
15841582
if (returnInfo.isIndirect()) {
1583+
auto resultType = getSILFuncConventions().getSingleSILResultType(
1584+
IGM.getMaximalTypeExpansionContext());
15851585
if (IGM.Triple.isWindowsMSVCEnvironment() &&
15861586
FnType->getRepresentation() ==
15871587
SILFunctionTypeRepresentation::CXXMethod) {
15881588
// Windows ABI places `this` before the
15891589
// returned indirect values.
15901590
emitArg(0);
15911591
firstParamToLowerNormally = 1;
1592-
addIndirectResult();
1592+
addIndirectResult(resultType);
15931593
} else
1594-
addIndirectResult();
1594+
addIndirectResult(resultType);
15951595
}
15961596

15971597
// Use a special IR type for passing block pointers.
@@ -2017,7 +2017,7 @@ void SignatureExpansion::expandAsyncEntryType() {
20172017
auto &ti = IGM.getTypeInfo(resultType);
20182018
auto &native = ti.nativeReturnValueSchema(IGM);
20192019
if (native.requiresIndirect())
2020-
addIndirectResult();
2020+
addIndirectResult(resultType);
20212021

20222022
// Add the indirect result types.
20232023
expandIndirectResults();
@@ -3267,7 +3267,13 @@ llvm::CallBase *IRBuilder::CreateCallOrInvoke(
32673267
for (unsigned argIndex = 0; argIndex < func->arg_size(); ++argIndex) {
32683268
if (func->hasParamAttribute(argIndex, llvm::Attribute::StructRet)) {
32693269
llvm::AttrBuilder builder(func->getContext());
3270-
builder.addStructRetAttr(func->getParamStructRetType(argIndex));
3270+
// See if there is a sret parameter in the signature. There are cases
3271+
// where the called function has a sret parameter, but the signature
3272+
// doesn't (e.g., noreturn functions).
3273+
llvm::Type *ty = attrs.getParamStructRetType(argIndex);
3274+
if (!ty)
3275+
ty = func->getParamStructRetType(argIndex);
3276+
builder.addStructRetAttr(ty);
32713277
attrs = attrs.addParamAttributes(func->getContext(), argIndex, builder);
32723278
}
32733279
if (func->hasParamAttribute(argIndex, llvm::Attribute::ByVal)) {

test/Interop/Cxx/class/method/methods-this-and-indirect-return-irgen-itanium.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,6 @@ public func use() -> CInt {
1212

1313
// CHECK: %[[instance:.*]] = alloca %TSo10HasMethodsV
1414
// CHECK: %[[result:.*]] = alloca %TSo19NonTrivialInWrapperV
15-
// CHECK: call void @_ZN10HasMethods28nonConstPassThroughAsWrapperEi(ptr noalias nocapture sret(%struct.NonTrivialInWrapper) %[[result]], ptr %[[instance]], i32 42)
15+
// CHECK: call void @_ZN10HasMethods28nonConstPassThroughAsWrapperEi(ptr noalias sret(%TSo19NonTrivialInWrapperV) %[[result]], ptr %[[instance]], i32 42)
1616

1717
// CHECK: define {{.*}} void @_ZN10HasMethods28nonConstPassThroughAsWrapperEi(ptr noalias sret(%struct.NonTrivialInWrapper) {{.*}} %{{.*}}, ptr {{.*}} %{{.*}}, i32 noundef %{{.*}})

test/Interop/Cxx/objc-correctness/sret.swift

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,6 @@ func test(c : C, s : S) {
4545

4646
// CHECK: %[[TSO1SV:.*]] = type <{ %[[TS5INT32V:.*]] }>
4747
// CHECK: %[[TS5INT32V]] = type <{ i32 }>
48-
// CHECK: %[[SWIFT_OPAQUE:.*]] = type opaque
49-
// CHECK: %[[CLASS_S:.*]] = type { i32 }
5048

5149
// CHECK: define hidden swiftcc void @"$s4testAA1c1sySo1CC_So1SVtF"(ptr %[[V0:.*]], ptr {{.*}}%[[V1:.*]])
5250
// CHECK: %[[V2:.*]] = alloca %[[TSO1SV]], align 4
@@ -57,16 +55,16 @@ func test(c : C, s : S) {
5755
// CHECK: %[[V7:.*]] = alloca %[[TSO1SV]], align 4
5856
// CHECK: call void @llvm.lifetime.start.p0(i64 4, ptr %[[V2]])
5957
// CHECK: %[[V8:.*]] = load ptr, ptr @"\01L_selector(getS:)", align 8
60-
// CHECK: invoke void @objc_msgSend(ptr noalias nocapture sret(%[[SWIFT_OPAQUE]]) %[[V2]], ptr %[[V0]], ptr %[[V8]], i32 1)
58+
// CHECK: invoke void @objc_msgSend(ptr noalias sret(%[[TSO1SV]]) %[[V2]], ptr %[[V0]], ptr %[[V8]], i32 1)
6159

6260
// CHECK: %[[V10:.*]] = load ptr, ptr @"OBJC_CLASS_REF_$_C", align 8
6361
// CHECK: %[[V11:.*]] = call ptr @objc_opt_self(ptr %[[V10]])
6462
// CHECK: %[[V12:.*]] = load ptr, ptr @"\01L_selector(getS:)", align 8
65-
// CHECK: invoke void @objc_msgSend(ptr noalias nocapture sret(%[[SWIFT_OPAQUE]]) %[[V3]], ptr %[[V11]], ptr %[[V12]], i32 1)
63+
// CHECK: invoke void @objc_msgSend(ptr noalias sret(%[[TSO1SV]]) %[[V3]], ptr %[[V11]], ptr %[[V12]], i32 1)
6664

6765
// CHECK: %[[V14:.*]] = call ptr @_ZN1SC1Ev(ptr %[[V4]])
68-
// CHECK: invoke void @_Z4getSi(ptr noalias nocapture sret(%[[CLASS_S]]) %[[V5]], i32 1)
66+
// CHECK: invoke void @_Z4getSi(ptr noalias sret(%[[TSO1SV]]) %[[V5]], i32 1)
6967

70-
// CHECK: invoke void @_ZNK1S4getSEi(ptr noalias nocapture sret(%[[CLASS_S]]) %[[V6]], ptr %[[V1]], i32 1)
68+
// CHECK: invoke void @_ZNK1S4getSEi(ptr noalias sret(%[[TSO1SV]]) %[[V6]], ptr %[[V1]], i32 1)
7169

72-
// CHECK: invoke void @_ZN1S10getSStaticEi(ptr noalias nocapture sret(%[[CLASS_S]]) %[[V7]], i32 1)
70+
// CHECK: invoke void @_ZN1S10getSStaticEi(ptr noalias sret(%[[TSO1SV]]) %[[V7]], i32 1)

0 commit comments

Comments
 (0)