Skip to content

Commit b65aaf8

Browse files
committed
Make sure the sret type matches the type of the pointee type.
1 parent e2081b9 commit b65aaf8

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(),
@@ -931,7 +929,7 @@ SignatureExpansion::expandDirectResult() {
931929
auto &ti = IGM.getTypeInfo(resultType);
932930
auto &native = ti.nativeReturnValueSchema(IGM);
933931
if (native.requiresIndirect())
934-
return std::make_pair(addIndirectResult(), nullptr);
932+
return std::make_pair(addIndirectResult(resultType), nullptr);
935933

936934
// Disable the use of sret if we have a non-trivial direct result.
937935
if (!native.empty()) CanUseSRet = false;
@@ -1572,16 +1570,18 @@ void SignatureExpansion::expandExternalSignatureTypes() {
15721570

15731571
// If we return indirectly, that is the first parameter type.
15741572
if (returnInfo.isIndirect()) {
1573+
auto resultType = getSILFuncConventions().getSingleSILResultType(
1574+
IGM.getMaximalTypeExpansionContext());
15751575
if (IGM.Triple.isWindowsMSVCEnvironment() &&
15761576
FnType->getRepresentation() ==
15771577
SILFunctionTypeRepresentation::CXXMethod) {
15781578
// Windows ABI places `this` before the
15791579
// returned indirect values.
15801580
emitArg(0);
15811581
firstParamToLowerNormally = 1;
1582-
addIndirectResult();
1582+
addIndirectResult(resultType);
15831583
} else
1584-
addIndirectResult();
1584+
addIndirectResult(resultType);
15851585
}
15861586

15871587
// Use a special IR type for passing block pointers.
@@ -2007,7 +2007,7 @@ void SignatureExpansion::expandAsyncEntryType() {
20072007
auto &ti = IGM.getTypeInfo(resultType);
20082008
auto &native = ti.nativeReturnValueSchema(IGM);
20092009
if (native.requiresIndirect())
2010-
addIndirectResult();
2010+
addIndirectResult(resultType);
20112011

20122012
// Add the indirect result types.
20132013
expandIndirectResults();
@@ -3257,7 +3257,13 @@ llvm::CallBase *IRBuilder::CreateCallOrInvoke(
32573257
for (unsigned argIndex = 0; argIndex < func->arg_size(); ++argIndex) {
32583258
if (func->hasParamAttribute(argIndex, llvm::Attribute::StructRet)) {
32593259
llvm::AttrBuilder builder(func->getContext());
3260-
builder.addStructRetAttr(func->getParamStructRetType(argIndex));
3260+
// See if there is a sret parameter in the signature. There are cases
3261+
// where the called function has a sret parameter, but the signature
3262+
// doesn't (e.g., noreturn functions).
3263+
llvm::Type *ty = attrs.getParamStructRetType(argIndex);
3264+
if (!ty)
3265+
ty = func->getParamStructRetType(argIndex);
3266+
builder.addStructRetAttr(ty);
32613267
attrs = attrs.addParamAttributes(func->getContext(), argIndex, builder);
32623268
}
32633269
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)