Author: Boaz Brickner Date: 2024-10-18T10:11:14+02:00 New Revision: 09cc75e2ccc3616e1cb3b17f2fb99cb3bb323b12
URL: https://github.com/llvm/llvm-project/commit/09cc75e2ccc3616e1cb3b17f2fb99cb3bb323b12 DIFF: https://github.com/llvm/llvm-project/commit/09cc75e2ccc3616e1cb3b17f2fb99cb3bb323b12.diff LOG: [clang] Deduplicate the logic that only warns once when stack is almost full (#112552) Zero diff in behavior. Added: clang/include/clang/Basic/StackExhaustionHandler.h clang/lib/Basic/StackExhaustionHandler.cpp Modified: clang/include/clang/Sema/Sema.h clang/include/clang/Serialization/ASTReader.h clang/lib/Basic/CMakeLists.txt clang/lib/CodeGen/CodeGenModule.cpp clang/lib/CodeGen/CodeGenModule.h clang/lib/Sema/Sema.cpp clang/lib/Sema/SemaTemplateInstantiate.cpp clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTReaderDecl.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Basic/StackExhaustionHandler.h b/clang/include/clang/Basic/StackExhaustionHandler.h new file mode 100644 index 00000000000000..fb02b9521cb48f --- /dev/null +++ b/clang/include/clang/Basic/StackExhaustionHandler.h @@ -0,0 +1,45 @@ +//===--- StackExhaustionHandler.h - A utility for warning once when close to out +// of stack space -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Defines a utilitiy for warning once when close to out of stack space. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_BASIC_STACK_EXHAUSTION_HANDLER_H +#define LLVM_CLANG_BASIC_STACK_EXHAUSTION_HANDLER_H + +#include "clang/Basic/Diagnostic.h" + +namespace clang { +class StackExhaustionHandler { +public: + StackExhaustionHandler(DiagnosticsEngine &diags) : DiagsRef(diags) {} + + /// 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); + + /// Check to see if we're low on stack space and produce a warning if we're + /// low on stack space (Currently, at least 256Kis guaranteed). + void warnOnStackNearlyExhausted(SourceLocation Loc); + +private: + /// Warn that the stack is nearly exhausted. + void warnStackExhausted(SourceLocation Loc); + + DiagnosticsEngine &DiagsRef; + bool WarnedStackExhausted = false; +}; +} // end namespace clang + +#endif // LLVM_CLANG_BASIC_STACK_EXHAUSTION_HANDLER_H diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 2c5769f8469e5b..bc9c422ed4c477 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -49,6 +49,7 @@ #include "clang/Basic/PragmaKinds.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" +#include "clang/Basic/StackExhaustionHandler.h" #include "clang/Basic/TemplateKinds.h" #include "clang/Basic/TokenKinds.h" #include "clang/Basic/TypeTraits.h" @@ -546,9 +547,6 @@ class Sema final : public SemaBase { /// Print out statistics about the semantic analysis. void PrintStats() const; - /// 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 (for example, @@ -1183,7 +1181,7 @@ class Sema final : public SemaBase { std::optional<std::unique_ptr<DarwinSDKInfo>> CachedDarwinSDKInfo; bool WarnedDarwinSDKInfoMissing = false; - bool WarnedStackExhausted = false; + StackExhaustionHandler StackHandler; Sema(const Sema &) = delete; void operator=(const Sema &) = delete; diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index ee4e897b248882..b476a40ebd2c8c 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -19,6 +19,7 @@ #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/OpenCLOptions.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Basic/StackExhaustionHandler.h" #include "clang/Basic/Version.h" #include "clang/Lex/ExternalPreprocessorSource.h" #include "clang/Lex/HeaderSearch.h" @@ -445,7 +446,7 @@ class ASTReader DiagnosticsEngine &Diags; // Sema has duplicate logic, but SemaObj can sometimes be null so ASTReader // has its own version. - bool WarnedStackExhausted = false; + StackExhaustionHandler StackHandler; /// The semantic analysis object that will be processing the /// AST files and the translation unit that uses it. @@ -2180,7 +2181,8 @@ class ASTReader /// Report a diagnostic. DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const; - void warnStackExhausted(SourceLocation Loc); + void runWithSufficientStackSpace(SourceLocation Loc, + llvm::function_ref<void()> Fn); IdentifierInfo *DecodeIdentifierInfo(serialization::IdentifierID ID); diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt index e7ebc8f191aa6b..e11e1ac4a6fa63 100644 --- a/clang/lib/Basic/CMakeLists.txt +++ b/clang/lib/Basic/CMakeLists.txt @@ -89,6 +89,7 @@ add_clang_library(clangBasic SourceManager.cpp SourceMgrAdapter.cpp Stack.cpp + StackExhaustionHandler.cpp TargetID.cpp TargetInfo.cpp Targets.cpp diff --git a/clang/lib/Basic/StackExhaustionHandler.cpp b/clang/lib/Basic/StackExhaustionHandler.cpp new file mode 100644 index 00000000000000..24b499c810dbfe --- /dev/null +++ b/clang/lib/Basic/StackExhaustionHandler.cpp @@ -0,0 +1,35 @@ +//===--- StackExhaustionHandler.cpp - - A utility for warning once when close +// to out of stack space -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Defines a utilitiy for warning once when close to out of stack space. +/// +//===----------------------------------------------------------------------===// + +#include "clang/Basic/StackExhaustionHandler.h" +#include "clang/Basic/Stack.h" + +void clang::StackExhaustionHandler::runWithSufficientStackSpace( + SourceLocation Loc, llvm::function_ref<void()> Fn) { + clang::runWithSufficientStackSpace([&] { warnStackExhausted(Loc); }, Fn); +} + +void clang::StackExhaustionHandler::warnOnStackNearlyExhausted( + SourceLocation Loc) { + if (isStackNearlyExhausted()) + warnStackExhausted(Loc); +} + +void clang::StackExhaustionHandler::warnStackExhausted(SourceLocation Loc) { + // Only warn about this once. + if (!WarnedStackExhausted) { + DiagsRef.Report(Loc, diag::warn_stack_exhausted); + WarnedStackExhausted = true; + } +} diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 9a84a11973b1a9..24655b809b2eff 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -342,7 +342,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, : Context(C), LangOpts(C.getLangOpts()), FS(FS), HeaderSearchOpts(HSO), PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M), Diags(diags), Target(C.getTargetInfo()), ABI(createCXXABI(*this)), - VMContext(M.getContext()), VTables(*this), + VMContext(M.getContext()), VTables(*this), StackHandler(diags), SanitizerMD(new SanitizerMetadata(*this)) { // Initialize the type cache. @@ -1595,17 +1595,9 @@ 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; - } -} - void CodeGenModule::runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref<void()> Fn) { - clang::runWithSufficientStackSpace([&] { warnStackExhausted(Loc); }, Fn); + StackHandler.runWithSufficientStackSpace(Loc, Fn); } llvm::ConstantInt *CodeGenModule::getSize(CharUnits size) { diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index fa82a81b05dd53..1b77490e261c21 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -26,6 +26,7 @@ #include "clang/Basic/LangOptions.h" #include "clang/Basic/NoSanitizeList.h" #include "clang/Basic/ProfileList.h" +#include "clang/Basic/StackExhaustionHandler.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/XRayLists.h" #include "clang/Lex/PreprocessorOptions.h" @@ -336,7 +337,7 @@ class CodeGenModule : public CodeGenTypeCache { std::unique_ptr<llvm::IndexedInstrProfReader> PGOReader; InstrProfStats PGOStats; std::unique_ptr<llvm::SanitizerStatReport> SanStats; - bool WarnedStackExhausted = false; + StackExhaustionHandler StackHandler; // 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 @@ -1298,9 +1299,6 @@ 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 diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index f0d1634af529f0..5e9886a109468f 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -220,7 +220,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, AnalysisWarnings(*this), ThreadSafetyDeclCache(nullptr), LateTemplateParser(nullptr), LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr), CurContext(nullptr), ExternalSource(nullptr), - CurScope(nullptr), Ident_super(nullptr), + StackHandler(Diags), CurScope(nullptr), Ident_super(nullptr), AMDGPUPtr(std::make_unique<SemaAMDGPU>(*this)), ARMPtr(std::make_unique<SemaARM>(*this)), AVRPtr(std::make_unique<SemaAVR>(*this)), @@ -562,17 +562,9 @@ Sema::~Sema() { SemaPPCallbackHandler->reset(); } -void Sema::warnStackExhausted(SourceLocation Loc) { - // Only warn about this once. - if (!WarnedStackExhausted) { - Diag(Loc, diag::warn_stack_exhausted); - WarnedStackExhausted = true; - } -} - void Sema::runWithSufficientStackSpace(SourceLocation Loc, llvm::function_ref<void()> Fn) { - clang::runWithSufficientStackSpace([&] { warnStackExhausted(Loc); }, Fn); + StackHandler.runWithSufficientStackSpace(Loc, Fn); } bool Sema::makeUnavailableInSystemHeader(SourceLocation loc, diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 8665c099903dc3..457a9968c32a4a 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -806,8 +806,7 @@ void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) { // Check to see if we're low on stack space. We can't do anything about this // from here, but we can at least warn the user. - if (isStackNearlyExhausted()) - warnStackExhausted(Ctx.PointOfInstantiation); + StackHandler.warnOnStackNearlyExhausted(Ctx.PointOfInstantiation); } void Sema::popCodeSynthesisContext() { diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 1b2473f2457344..1cf6c9352f3686 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -64,6 +64,7 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManagerInternals.h" #include "clang/Basic/Specifiers.h" +#include "clang/Basic/Stack.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/TargetOptions.h" #include "clang/Basic/TokenKinds.h" @@ -9648,18 +9649,15 @@ DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) const { return Diags.Report(Loc, DiagID); } -void ASTReader::warnStackExhausted(SourceLocation Loc) { +void ASTReader::runWithSufficientStackSpace(SourceLocation Loc, + llvm::function_ref<void()> Fn) { // When Sema is available, avoid duplicate errors. if (SemaObj) { - SemaObj->warnStackExhausted(Loc); + SemaObj->runWithSufficientStackSpace(Loc, Fn); return; } - if (WarnedStackExhausted) - return; - WarnedStackExhausted = true; - - Diag(Loc, diag::warn_stack_exhausted); + StackHandler.runWithSufficientStackSpace(Loc, Fn); } /// Retrieve the identifier table associated with the @@ -10509,13 +10507,14 @@ ASTReader::ASTReader(Preprocessor &PP, InMemoryModuleCache &ModuleCache, bool AllowConfigurationMismatch, bool ValidateSystemInputs, bool ValidateASTInputFilesContent, bool UseGlobalIndex, std::unique_ptr<llvm::Timer> ReadTimer) - : Listener(bool(DisableValidationKind &DisableValidationForModuleKind::PCH) + : Listener(bool(DisableValidationKind & DisableValidationForModuleKind::PCH) ? cast<ASTReaderListener>(new SimpleASTReaderListener(PP)) : cast<ASTReaderListener>(new PCHValidator(PP, *this))), SourceMgr(PP.getSourceManager()), FileMgr(PP.getFileManager()), - PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), PP(PP), - ContextObj(Context), ModuleMgr(PP.getFileManager(), ModuleCache, - PCHContainerRdr, PP.getHeaderSearchInfo()), + PCHContainerRdr(PCHContainerRdr), Diags(PP.getDiagnostics()), + StackHandler(Diags), PP(PP), ContextObj(Context), + ModuleMgr(PP.getFileManager(), ModuleCache, PCHContainerRdr, + PP.getHeaderSearchInfo()), DummyIdResolver(PP), ReadTimer(std::move(ReadTimer)), isysroot(isysroot), DisableValidationKind(DisableValidationKind), AllowASTWithCompilerErrors(AllowASTWithCompilerErrors), diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 1ccc810f415eb4..d4e392dcc6bcd0 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -4168,8 +4168,7 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { D->setDeclContext(Context.getTranslationUnitDecl()); // Reading some declarations can result in deep recursion. - clang::runWithSufficientStackSpace([&] { warnStackExhausted(DeclLoc); }, - [&] { Reader.Visit(D); }); + runWithSufficientStackSpace(DeclLoc, [&] { Reader.Visit(D); }); // If this declaration is also a declaration context, get the // offsets for its tables of lexical and visible declarations. _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits