[clang] [clang] Fix the crash when dumping deserialized decls (PR #133395)
Ilya Biryukov via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 28 03:10:25 PDT 2025
================
@@ -103,15 +120,30 @@ class DeserializedDeclsDumper : public DelegatingDeserializationListener {
: DelegatingDeserializationListener(Previous, DeletePrevious) {}
void DeclRead(GlobalDeclID ID, const Decl *D) override {
- llvm::outs() << "PCH DECL: " << D->getDeclKindName();
- if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
- llvm::outs() << " - ";
- ND->printQualifiedName(llvm::outs());
+ PendingDecls.push_back(D);
+ DelegatingDeserializationListener::DeclRead(ID, D);
+ }
+ void FinishedDeserializing() override {
+ auto Decls = std::move(PendingDecls);
+ for (const auto *D : Decls) {
+ llvm::outs() << "PCH DECL: " << D->getDeclKindName();
+ if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
+ llvm::outs() << " - ";
+ ND->printQualifiedName(llvm::outs());
+ }
+ llvm::outs() << "\n";
}
- llvm::outs() << "\n";
- DelegatingDeserializationListener::DeclRead(ID, D);
+ if (!PendingDecls.empty()) {
----------------
ilya-biryukov wrote:
Our theory is that `printQualifiedName` can start deserializing more.
At the point where the callback is called now, we have already updated the state of `ASTReader` such that **more deserialization will cause this callback to be called again**. I.e. this should be a possible stack trace:
```
OurListener::FinishDeserializing()
ASTReader::FinishDeserializing()
ASTReader::doSomeDeserialization()
...
Decl::printQualifiedName()
OurListener::FinishDeserializing()
ASTReader::FinishDeserializing()
```
We probably need to figure out an API that does not require handling situations like this.
E.g. right now it means (I believe) that this condition will never be true: the recursive serialization will just remember all other decls and print their names and clear the `PendingDecls` vector.
https://github.com/llvm/llvm-project/pull/133395
More information about the cfe-commits
mailing list