Author: Ilya Biryukov Date: 2024-06-03T17:07:31+02:00 New Revision: 3315f0a2227b960265b9ed699e1ad33cdc5d3b65
URL: https://github.com/llvm/llvm-project/commit/3315f0a2227b960265b9ed699e1ad33cdc5d3b65 DIFF: https://github.com/llvm/llvm-project/commit/3315f0a2227b960265b9ed699e1ad33cdc5d3b65.diff LOG: [Serialization] Check for stack exhaustion when reading declarations (#79875) Particular example that lead to this is a very long chain of `UsingShadowDecl`s that we hit in our codebase in generated code. To avoid that, check for stack exhaustion when deserializing the declaration. At that point, we can point to source location of a particular declaration that is being deserialized. Added: Modified: clang/include/clang/Serialization/ASTReader.h clang/lib/Serialization/ASTReader.cpp clang/lib/Serialization/ASTReaderDecl.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index 4ece4593f0738..bea58d60d36c4 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -429,6 +429,9 @@ class ASTReader FileManager &FileMgr; const PCHContainerReader &PCHContainerRdr; DiagnosticsEngine &Diags; + // Sema has duplicate logic, but SemaObj can sometimes be null so ASTReader + // has its own version. + bool WarnedStackExhausted = false; /// The semantic analysis object that will be processing the /// AST files and the translation unit that uses it. @@ -2135,6 +2138,8 @@ class ASTReader /// Report a diagnostic. DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) const; + void warnStackExhausted(SourceLocation Loc); + IdentifierInfo *DecodeIdentifierInfo(serialization::IdentifierID ID); IdentifierInfo *readIdentifier(ModuleFile &M, const RecordData &Record, diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index ae72fcdd26119..2bc00e1bb3e38 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -44,6 +44,7 @@ #include "clang/Basic/CommentOptions.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticError.h" +#include "clang/Basic/DiagnosticIDs.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/ExceptionSpecificationType.h" @@ -9404,6 +9405,20 @@ DiagnosticBuilder ASTReader::Diag(SourceLocation Loc, unsigned DiagID) const { return Diags.Report(Loc, DiagID); } +void ASTReader::warnStackExhausted(SourceLocation Loc) { + // When Sema is available, avoid duplicate errors. + if (SemaObj) { + SemaObj->warnStackExhausted(Loc); + return; + } + + if (WarnedStackExhausted) + return; + WarnedStackExhausted = true; + + Diag(Loc, diag::warn_stack_exhausted); +} + /// Retrieve the identifier table associated with the /// preprocessor. IdentifierTable &ASTReader::getIdentifierTable() { diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 61cc99d4df687..765c083ce8df8 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -49,6 +49,7 @@ #include "clang/Basic/PragmaKinds.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" +#include "clang/Basic/Stack.h" #include "clang/Sema/IdentifierResolver.h" #include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTRecordReader.h" @@ -4127,7 +4128,10 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { // calls to Decl::getASTContext() by Decl's methods will find the // TranslationUnitDecl without crashing. D->setDeclContext(Context.getTranslationUnitDecl()); - Reader.Visit(D); + + // Reading some declarations can result in deep recursion. + clang::runWithSufficientStackSpace([&] { warnStackExhausted(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