[clang] 3315f0a - [Serialization] Check for stack exhaustion when reading declarations (#79875)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 3 08:07:34 PDT 2024
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.
More information about the cfe-commits
mailing list