@@ -474,7 +474,7 @@ namespace {
474
474
475
475
private:
476
476
const TypeInfo &expand (SILParameterInfo param);
477
- llvm::Type *addIndirectResult ();
477
+ llvm::Type *addIndirectResult (SILType resultType );
478
478
479
479
SILFunctionConventions getSILFuncConventions () const {
480
480
return SILFunctionConventions (FnType, IGM.getSILModule ());
@@ -532,9 +532,7 @@ namespace {
532
532
} // end namespace irgen
533
533
} // end namespace swift
534
534
535
- llvm::Type *SignatureExpansion::addIndirectResult () {
536
- auto resultType = getSILFuncConventions ().getSILResultType (
537
- IGM.getMaximalTypeExpansionContext ());
535
+ llvm::Type *SignatureExpansion::addIndirectResult (SILType resultType) {
538
536
const TypeInfo &resultTI = IGM.getTypeInfo (resultType);
539
537
auto storageTy = resultTI.getStorageType ();
540
538
addIndirectResultAttributes (IGM, Attrs, ParamIRTypes.size (), claimSRet (),
@@ -941,7 +939,7 @@ SignatureExpansion::expandDirectResult() {
941
939
auto &ti = IGM.getTypeInfo (resultType);
942
940
auto &native = ti.nativeReturnValueSchema (IGM);
943
941
if (native.requiresIndirect ())
944
- return std::make_pair (addIndirectResult (), nullptr );
942
+ return std::make_pair (addIndirectResult (resultType ), nullptr );
945
943
946
944
// Disable the use of sret if we have a non-trivial direct result.
947
945
if (!native.empty ()) CanUseSRet = false ;
@@ -1582,16 +1580,18 @@ void SignatureExpansion::expandExternalSignatureTypes() {
1582
1580
1583
1581
// If we return indirectly, that is the first parameter type.
1584
1582
if (returnInfo.isIndirect ()) {
1583
+ auto resultType = getSILFuncConventions ().getSingleSILResultType (
1584
+ IGM.getMaximalTypeExpansionContext ());
1585
1585
if (IGM.Triple .isWindowsMSVCEnvironment () &&
1586
1586
FnType->getRepresentation () ==
1587
1587
SILFunctionTypeRepresentation::CXXMethod) {
1588
1588
// Windows ABI places `this` before the
1589
1589
// returned indirect values.
1590
1590
emitArg (0 );
1591
1591
firstParamToLowerNormally = 1 ;
1592
- addIndirectResult ();
1592
+ addIndirectResult (resultType );
1593
1593
} else
1594
- addIndirectResult ();
1594
+ addIndirectResult (resultType );
1595
1595
}
1596
1596
1597
1597
// Use a special IR type for passing block pointers.
@@ -2017,7 +2017,7 @@ void SignatureExpansion::expandAsyncEntryType() {
2017
2017
auto &ti = IGM.getTypeInfo (resultType);
2018
2018
auto &native = ti.nativeReturnValueSchema (IGM);
2019
2019
if (native.requiresIndirect ())
2020
- addIndirectResult ();
2020
+ addIndirectResult (resultType );
2021
2021
2022
2022
// Add the indirect result types.
2023
2023
expandIndirectResults ();
@@ -3267,7 +3267,13 @@ llvm::CallBase *IRBuilder::CreateCallOrInvoke(
3267
3267
for (unsigned argIndex = 0 ; argIndex < func->arg_size (); ++argIndex) {
3268
3268
if (func->hasParamAttribute (argIndex, llvm::Attribute::StructRet)) {
3269
3269
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);
3271
3277
attrs = attrs.addParamAttributes (func->getContext (), argIndex, builder);
3272
3278
}
3273
3279
if (func->hasParamAttribute (argIndex, llvm::Attribute::ByVal)) {
0 commit comments