@@ -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 (),
@@ -931,7 +929,7 @@ SignatureExpansion::expandDirectResult() {
931
929
auto &ti = IGM.getTypeInfo (resultType);
932
930
auto &native = ti.nativeReturnValueSchema (IGM);
933
931
if (native.requiresIndirect ())
934
- return std::make_pair (addIndirectResult (), nullptr );
932
+ return std::make_pair (addIndirectResult (resultType ), nullptr );
935
933
936
934
// Disable the use of sret if we have a non-trivial direct result.
937
935
if (!native.empty ()) CanUseSRet = false ;
@@ -1572,16 +1570,18 @@ void SignatureExpansion::expandExternalSignatureTypes() {
1572
1570
1573
1571
// If we return indirectly, that is the first parameter type.
1574
1572
if (returnInfo.isIndirect ()) {
1573
+ auto resultType = getSILFuncConventions ().getSingleSILResultType (
1574
+ IGM.getMaximalTypeExpansionContext ());
1575
1575
if (IGM.Triple .isWindowsMSVCEnvironment () &&
1576
1576
FnType->getRepresentation () ==
1577
1577
SILFunctionTypeRepresentation::CXXMethod) {
1578
1578
// Windows ABI places `this` before the
1579
1579
// returned indirect values.
1580
1580
emitArg (0 );
1581
1581
firstParamToLowerNormally = 1 ;
1582
- addIndirectResult ();
1582
+ addIndirectResult (resultType );
1583
1583
} else
1584
- addIndirectResult ();
1584
+ addIndirectResult (resultType );
1585
1585
}
1586
1586
1587
1587
// Use a special IR type for passing block pointers.
@@ -2007,7 +2007,7 @@ void SignatureExpansion::expandAsyncEntryType() {
2007
2007
auto &ti = IGM.getTypeInfo (resultType);
2008
2008
auto &native = ti.nativeReturnValueSchema (IGM);
2009
2009
if (native.requiresIndirect ())
2010
- addIndirectResult ();
2010
+ addIndirectResult (resultType );
2011
2011
2012
2012
// Add the indirect result types.
2013
2013
expandIndirectResults ();
@@ -3257,7 +3257,13 @@ llvm::CallBase *IRBuilder::CreateCallOrInvoke(
3257
3257
for (unsigned argIndex = 0 ; argIndex < func->arg_size (); ++argIndex) {
3258
3258
if (func->hasParamAttribute (argIndex, llvm::Attribute::StructRet)) {
3259
3259
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);
3261
3267
attrs = attrs.addParamAttributes (func->getContext (), argIndex, builder);
3262
3268
}
3263
3269
if (func->hasParamAttribute (argIndex, llvm::Attribute::ByVal)) {
0 commit comments