Skip to content
Merged
5 changes: 4 additions & 1 deletion clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5817,7 +5817,10 @@ LValue CodeGenFunction::EmitHLSLArrayAssignLValue(const BinaryOperator *E) {

LValue CodeGenFunction::EmitCallExprLValue(const CallExpr *E,
llvm::CallBase **CallOrInvoke) {
RValue RV = EmitCallExpr(E, ReturnValueSlot(), CallOrInvoke);
RValue RV;
CGM.runWithSufficientStackSpace(E->getExprLoc(), [&] {
RV = EmitCallExpr(E, ReturnValueSlot(), CallOrInvoke);
});

if (!RV.isScalar())
return MakeAddrLValue(RV.getAggregateAddress(), E->getType(),
Expand Down
14 changes: 14 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "clang/Basic/FileManager.h"
#include "clang/Basic/Module.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/Stack.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
#include "clang/CodeGen/BackendUtil.h"
Expand Down Expand Up @@ -1596,6 +1597,19 @@ void CodeGenModule::ErrorUnsupported(const Decl *D, const char *Type) {
getDiags().Report(Context.getFullLoc(D->getLocation()), DiagID) << Msg;
}

void CodeGenModule::warnStackExhausted(SourceLocation Loc) {
// Only warn about this once.
if (!WarnedStackExhausted) {
getDiags().Report(Loc, diag::warn_stack_exhausted);
WarnedStackExhausted = true;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a way to avoid the duplication with Sema here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking that as a follow up I will extract this small logic into a class which both Sema and CodeGen would own.
I also have #111799 to make them more similar.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SGTM and also feels like something that we could do in a follow-up, even if the code here is duplicated for some short period of time.

I suspect there's some wiring up to figure out for sharing this in the same class, so it'd be good to land this while that's still happening.


void CodeGenModule::runWithSufficientStackSpace(SourceLocation Loc,
llvm::function_ref<void()> Fn) {
clang::runWithSufficientStackSpace([&] { warnStackExhausted(Loc); }, Fn);
}

llvm::ConstantInt *CodeGenModule::getSize(CharUnits size) {
return llvm::ConstantInt::get(SizeTy, size.getQuantity());
}
Expand Down
11 changes: 11 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ class CodeGenModule : public CodeGenTypeCache {
std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader;
InstrProfStats PGOStats;
std::unique_ptr<llvm::SanitizerStatReport> SanStats;
bool WarnedStackExhausted = false;

// A set of references that have only been seen via a weakref so far. This is
// used to remove the weak of the reference if we ever see a direct reference
Expand Down Expand Up @@ -1297,6 +1298,16 @@ class CodeGenModule : public CodeGenTypeCache {
/// Print out an error that codegen doesn't support the specified decl yet.
void ErrorUnsupported(const Decl *D, const char *Type);

/// Warn that the stack is nearly exhausted.
void warnStackExhausted(SourceLocation Loc);

/// Run some code with "sufficient" stack space. (Currently, at least 256K is
/// guaranteed). Produces a warning if we're low on stack space and allocates
/// more in that case. Use this in code that may recurse deeply to avoid stack
/// overflow.
void runWithSufficientStackSpace(SourceLocation Loc,
llvm::function_ref<void()> Fn);

/// Set the attributes on the LLVM function for the given decl and function
/// info. This applies attributes necessary for handling the ABI as well as
/// user specified attributes like section.
Expand Down
Loading