================
@@ -4128,47 +4107,78 @@ void CodeGenFunction::EmitFunctionEpilog(
// Load all of the coerced elements out into results.
llvm::SmallVector<llvm::Value *, 4> results;
- Address addr = ReturnValue.withElementType(coercionType);
+ Address addr = CGF.ReturnValue.withElementType(coercionType);
unsigned unpaddedIndex = 0;
for (unsigned i = 0, e = coercionType->getNumElements(); i != e; ++i) {
auto coercedEltType = coercionType->getElementType(i);
if (ABIArgInfo::isPaddingForCoerceAndExpand(coercedEltType))
continue;
- auto eltAddr = Builder.CreateStructGEP(addr, i);
+ auto eltAddr = CGF.Builder.CreateStructGEP(addr, i);
llvm::Value *elt = CreateCoercedLoad(
eltAddr,
unpaddedStruct ? unpaddedStruct->getElementType(unpaddedIndex++)
: unpaddedCoercionType,
- *this);
+ CGF);
results.push_back(elt);
}
// If we have one result, it's the single direct result type.
if (results.size() == 1) {
RV = results[0];
- // Otherwise, we need to make a first-class aggregate.
+ // Otherwise, we need to make a first-class aggregate.
} else {
// Construct a return type that lacks padding elements.
llvm::Type *returnType = RetAI.getUnpaddedCoerceAndExpandType();
RV = llvm::PoisonValue::get(returnType);
for (unsigned i = 0, e = results.size(); i != e; ++i) {
- RV = Builder.CreateInsertValue(RV, results[i], i);
+ RV = CGF.Builder.CreateInsertValue(RV, results[i], i);
}
}
break;
}
case ABIArgInfo::TargetSpecific: {
- Address V = emitAddressAtOffset(*this, ReturnValue, RetAI);
- RV = CGM.getABIInfo().createCoercedLoad(V, RetAI, *this);
+ Address V = emitAddressAtOffset(CGF, CGF.ReturnValue, RetAI);
+ RV = CGF.CGM.getABIInfo().createCoercedLoad(V, RetAI, CGF);
break;
}
case ABIArgInfo::Expand:
case ABIArgInfo::IndirectAliased:
llvm_unreachable("Invalid ABI kind for return argument");
}
+}
+
+static bool isReturnReachable(CodeGenFunction::JumpDest &ReturnBlock) {
+ return !ReturnBlock.isValid() || !ReturnBlock.getBlock()->use_empty();
+}
+
+void CodeGenFunction::EmitFunctionEpilog(
+ const CGFunctionInfo &FI, bool EmitRetDbgLoc, SourceLocation EndLoc,
+ uint64_t RetKeyInstructionsSourceAtom) {
+ if (FI.isNoReturn()) {
+ // Noreturn functions don't return.
+ EmitUnreachable(EndLoc);
+ return;
+ }
+
+ if (CurCodeDecl && CurCodeDecl->hasAttr<NakedAttr>()) {
+ // Naked functions don't have epilogues.
+ Builder.CreateUnreachable();
+ return;
+ }
+
+ llvm::Value *RV = nullptr;
+ llvm::DebugLoc RetDbgLoc;
+ QualType RetTy = FI.getReturnType();
+
+ if (ReturnValue.isValid())
+ processFunctionReturnInfo(*this, FI, EmitRetDbgLoc, EndLoc, RetTy, RV,
+ RetDbgLoc);
+
+ if (SehTryEndInvokeDest && isReturnReachable(ReturnBlock))
+ EmitSehTryScopeEnd(SehTryEndInvokeDest);
----------------
MuellerMP wrote:
I think it is possible to formulate this as a `NormalCleanup` on the EHStack
(similar how SEH finally scopes are pushed). I initially put this here (and
fixed up WinEHPrepare to work with already ended scopes) so i can emit the
scope end just before the ret and keep return value loads inside the try scope.
But I do agree that using the EHStack is probably the better approach here.
https://github.com/llvm/llvm-project/pull/167176
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits