================
@@ -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

Reply via email to