[clang] [Serialization] Check for stack exhaustion when reading declarations (PR #79875)
Ilya Biryukov via cfe-commits
cfe-commits at lists.llvm.org
Wed May 29 08:26:59 PDT 2024
ilya-biryukov wrote:
> Yeah, I was hoping to have it in the text of the discussion here without having to do it myself since you've already got the repro locally, presumably... so we can all see/discuss it. But perhaps it's not sufficiently helpful/constructive to worry about - not sure.
@dwblaikie sorry, I was responding to the AST and somehow missed the stack part. I should have definitely included it from the start, my bad. Here it is:
<details>
<summary>Click to expand the stack trace</summary>
```text
#0 0x000055555b15abdd in clang::ASTReader::ReadDeclRecord(unsigned int) ()
#1 0x000055555bec8504 in clang::ASTReader::GetDecl(unsigned int) [clone .cold] ()
#2 0x000055555b2028de in clang::ASTDeclReader::VisitUsingShadowDecl(clang::UsingShadowDecl*) ()
#3 0x000055555b164667 in clang::ASTReader::ReadDeclRecord(unsigned int) ()
#4 0x000055555bec8504 in clang::ASTReader::GetDecl(unsigned int) [clone .cold] ()
#5 0x000055555b2028de in clang::ASTDeclReader::VisitUsingShadowDecl(clang::UsingShadowDecl*) ()
.............................................
#11814 0x000055555b164667 in clang::ASTReader::ReadDeclRecord(unsigned int) ()
#11815 0x000055555bec8504 in clang::ASTReader::GetDecl(unsigned int) [clone .cold] ()
#11816 0x000055555b206e7a in clang::ASTDeclReader::VisitUsingDecl(clang::UsingDecl*) ()
#11817 0x000055555b164994 in clang::ASTReader::ReadDeclRecord(unsigned int) ()
#11818 0x000055555bae90d8 in clang::ASTReader::FindExternalLexicalDecls(clang::DeclContext const*, llvm::function_ref<bool (clang::Decl::Kind)>, llvm::SmallVectorImpl<clang::Decl*>&) ()
#11819 0x000055555bb0bc69 in clang::DeclContext::LoadLexicalDeclsFromExternalStorage() const ()
#11820 0x000055555bb6b87d in clang::Sema::SetCtorInitializers(clang::CXXConstructorDecl*, bool, llvm::ArrayRef<clang::CXXCtorInitializer*>) ()
#11821 0x000055555bb6e84e in clang::Sema::DefineImplicitMoveConstructor(clang::SourceLocation, clang::CXXConstructorDecl*) ()
#11822 0x000055555961f28c in void llvm::function_ref<void ()>::callback_fn<clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool)::$_0>(long) [clone .__uniq.244473529911816543723239142225852553696] [clone .llvm.16089407488121690861] ()
#11823 0x000055555ba821b8 in clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool) ()
#11824 0x000055555bda0be9 in clang::Sema::BuildCXXConstructExpr(clang::SourceLocation, clang::QualType, clang::NamedDecl*, clang::CXXConstructorDecl*, llvm::MutableArrayRef<clang::Expr*>, bool, bool, bool, bool, clang::CXXConstructionKind, clang::SourceRange) ()
#11825 0x000055555ba1fcef in clang::InitializationSequence::Perform(clang::Sema&, clang::InitializedEntity const&, clang::InitializationKind const&, llvm::MutableArrayRef<clang::Expr*>, clang::QualType*) ()
#11826 0x000055555c76f7dd in CollectFieldInitializer(clang::Sema&, (anonymous namespace)::BaseAndFieldInfo&, clang::FieldDecl*, clang::IndirectFieldDecl*) [clone .__uniq.266194649099037377127634867174551623720] [clone .cold] ()
#11827 0x000055555bb6c0ba in clang::Sema::SetCtorInitializers(clang::CXXConstructorDecl*, bool, llvm::ArrayRef<clang::CXXCtorInitializer*>) ()
#11828 0x000055555bb6e84e in clang::Sema::DefineImplicitMoveConstructor(clang::SourceLocation, clang::CXXConstructorDecl*) ()
#11829 0x000055555961f28c in void llvm::function_ref<void ()>::callback_fn<clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool)::$_0>(long) [clone .__uniq.244473529911816543723239142225852553696] [clone .llvm.16089407488121690861] ()
#11830 0x000055555ba821b8 in clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool) ()
#11831 0x000055555bda0be9 in clang::Sema::BuildCXXConstructExpr(clang::SourceLocation, clang::QualType, clang::NamedDecl*, clang::CXXConstructorDecl*, llvm::MutableArrayRef<clang::Expr*>, bool, bool, bool, bool, clang::CXXConstructionKind, clang::SourceRange) ()
#11832 0x000055555ba1fcef in clang::InitializationSequence::Perform(clang::Sema&, clang::InitializedEntity const&, clang::InitializationKind const&, llvm::MutableArrayRef<clang::Expr*>, clang::QualType*) ()
#11833 0x000055555bb6dfd8 in BuildImplicitBaseInitializer(clang::Sema&, clang::CXXConstructorDecl*, ImplicitInitializerKind, clang::CXXBaseSpecifier*, bool, clang::CXXCtorInitializer*&) [clone .__uniq.266194649099037377127634867174551623720] ()
#11834 0x000055555bb6b798 in clang::Sema::SetCtorInitializers(clang::CXXConstructorDecl*, bool, llvm::ArrayRef<clang::CXXCtorInitializer*>) ()
#11835 0x000055555bb6e84e in clang::Sema::DefineImplicitMoveConstructor(clang::SourceLocation, clang::CXXConstructorDecl*) ()
#11836 0x000055555961f28c in void llvm::function_ref<void ()>::callback_fn<clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool)::$_0>(long) [clone .__uniq.244473529911816543723239142225852553696] [clone .llvm.16089407488121690861] ()
#11837 0x000055555ba821b8 in clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool) ()
#11838 0x000055555bda0be9 in clang::Sema::BuildCXXConstructExpr(clang::SourceLocation, clang::QualType, clang::NamedDecl*, clang::CXXConstructorDecl*, llvm::MutableArrayRef<clang::Expr*>, bool, bool, bool, bool, clang::CXXConstructionKind, clang::SourceRange) ()
#11839 0x000055555ba1fcef in clang::InitializationSequence::Perform(clang::Sema&, clang::InitializedEntity const&, clang::InitializationKind const&, llvm::MutableArrayRef<clang::Expr*>, clang::QualType*) ()
#11840 0x000055555bb6dfd8 in BuildImplicitBaseInitializer(clang::Sema&, clang::CXXConstructorDecl*, ImplicitInitializerKind, clang::CXXBaseSpecifier*, bool, clang::CXXCtorInitializer*&) [clone .__uniq.266194649099037377127634867174551623720] ()
#11841 0x000055555bb6b798 in clang::Sema::SetCtorInitializers(clang::CXXConstructorDecl*, bool, llvm::ArrayRef<clang::CXXCtorInitializer*>) ()
#11842 0x000055555bb6e84e in clang::Sema::DefineImplicitMoveConstructor(clang::SourceLocation, clang::CXXConstructorDecl*) ()
#11843 0x000055555961f28c in void llvm::function_ref<void ()>::callback_fn<clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool)::$_0>(long) [clone .__uniq.244473529911816543723239142225852553696] [clone .llvm.16089407488121690861] ()
#11844 0x000055555ba821b8 in clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool) ()
#11845 0x000055555bda0be9 in clang::Sema::BuildCXXConstructExpr(clang::SourceLocation, clang::QualType, clang::NamedDecl*, clang::CXXConstructorDecl*, llvm::MutableArrayRef<clang::Expr*>, bool, bool, bool, bool, clang::CXXConstructionKind, clang::SourceRange) ()
#11846 0x000055555ba1fcef in clang::InitializationSequence::Perform(clang::Sema&, clang::InitializedEntity const&, clang::InitializationKind const&, llvm::MutableArrayRef<clang::Expr*>, clang::QualType*) ()
#11847 0x000055555bb6dfd8 in BuildImplicitBaseInitializer(clang::Sema&, clang::CXXConstructorDecl*, ImplicitInitializerKind, clang::CXXBaseSpecifier*, bool, clang::CXXCtorInitializer*&) [clone .__uniq.266194649099037377127634867174551623720] ()
#11848 0x000055555bb6b798 in clang::Sema::SetCtorInitializers(clang::CXXConstructorDecl*, bool, llvm::ArrayRef<clang::CXXCtorInitializer*>) ()
#11849 0x000055555bb6e84e in clang::Sema::DefineImplicitMoveConstructor(clang::SourceLocation, clang::CXXConstructorDecl*) ()
#11850 0x000055555961f28c in void llvm::function_ref<void ()>::callback_fn<clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool)::$_0>(long) [clone .__uniq.244473529911816543723239142225852553696] [clone .llvm.16089407488121690861] ()
#11851 0x000055555ba821b8 in clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool) ()
#11852 0x000055555bda0be9 in clang::Sema::BuildCXXConstructExpr(clang::SourceLocation, clang::QualType, clang::NamedDecl*, clang::CXXConstructorDecl*, llvm::MutableArrayRef<clang::Expr*>, bool, bool, bool, bool, clang::CXXConstructionKind, clang::SourceRange) ()
#11853 0x000055555ba1fcef in clang::InitializationSequence::Perform(clang::Sema&, clang::InitializedEntity const&, clang::InitializationKind const&, llvm::MutableArrayRef<clang::Expr*>, clang::QualType*) ()
#11854 0x000055555bb6dfd8 in BuildImplicitBaseInitializer(clang::Sema&, clang::CXXConstructorDecl*, ImplicitInitializerKind, clang::CXXBaseSpecifier*, bool, clang::CXXCtorInitializer*&) [clone .__uniq.266194649099037377127634867174551623720] ()
#11855 0x000055555bb6b798 in clang::Sema::SetCtorInitializers(clang::CXXConstructorDecl*, bool, llvm::ArrayRef<clang::CXXCtorInitializer*>) ()
#11856 0x000055555bb6e84e in clang::Sema::DefineImplicitMoveConstructor(clang::SourceLocation, clang::CXXConstructorDecl*) ()
#11857 0x000055555961f28c in void llvm::function_ref<void ()>::callback_fn<clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool)::$_0>(long) [clone .__uniq.244473529911816543723239142225852553696] [clone .llvm.16089407488121690861] ()
#11858 0x000055555ba821b8 in clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool) ()
#11859 0x000055555bda0be9 in clang::Sema::BuildCXXConstructExpr(clang::SourceLocation, clang::QualType, clang::NamedDecl*, clang::CXXConstructorDecl*, llvm::MutableArrayRef<clang::Expr*>, bool, bool, bool, bool, clang::CXXConstructionKind, clang::SourceRange) ()
#11860 0x000055555ba1fcef in clang::InitializationSequence::Perform(clang::Sema&, clang::InitializedEntity const&, clang::InitializationKind const&, llvm::MutableArrayRef<clang::Expr*>, clang::QualType*) ()
#11861 0x000055555bb6dfd8 in BuildImplicitBaseInitializer(clang::Sema&, clang::CXXConstructorDecl*, ImplicitInitializerKind, clang::CXXBaseSpecifier*, bool, clang::CXXCtorInitializer*&) [clone .__uniq.266194649099037377127634867174551623720] ()
#11862 0x000055555bb6b798 in clang::Sema::SetCtorInitializers(clang::CXXConstructorDecl*, bool, llvm::ArrayRef<clang::CXXCtorInitializer*>) ()
#11863 0x000055555bb6e84e in clang::Sema::DefineImplicitMoveConstructor(clang::SourceLocation, clang::CXXConstructorDecl*) ()
#11864 0x000055555961f28c in void llvm::function_ref<void ()>::callback_fn<clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool)::$_0>(long) [clone .__uniq.244473529911816543723239142225852553696] [clone .llvm.16089407488121690861] ()
#11865 0x000055555ba821b8 in clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool) ()
#11866 0x000055555bda0be9 in clang::Sema::BuildCXXConstructExpr(clang::SourceLocation, clang::QualType, clang::NamedDecl*, clang::CXXConstructorDecl*, llvm::MutableArrayRef<clang::Expr*>, bool, bool, bool, bool, clang::CXXConstructionKind, clang::SourceRange) ()
#11867 0x000055555ba1fcef in clang::InitializationSequence::Perform(clang::Sema&, clang::InitializedEntity const&, clang::InitializationKind const&, llvm::MutableArrayRef<clang::Expr*>, clang::QualType*) ()
#11868 0x000055555c76f7dd in CollectFieldInitializer(clang::Sema&, (anonymous namespace)::BaseAndFieldInfo&, clang::FieldDecl*, clang::IndirectFieldDecl*) [clone .__uniq.266194649099037377127634867174551623720] [clone .cold] ()
#11869 0x000055555bb6c0ba in clang::Sema::SetCtorInitializers(clang::CXXConstructorDecl*, bool, llvm::ArrayRef<clang::CXXCtorInitializer*>) ()
#11870 0x000055555bb6e84e in clang::Sema::DefineImplicitMoveConstructor(clang::SourceLocation, clang::CXXConstructorDecl*) ()
#11871 0x000055555961f28c in void llvm::function_ref<void ()>::callback_fn<clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool)::$_0>(long) [clone .__uniq.244473529911816543723239142225852553696] [clone .llvm.16089407488121690861] ()
#11872 0x000055555ba821b8 in clang::Sema::MarkFunctionReferenced(clang::SourceLocation, clang::FunctionDecl*, bool) ()
#11873 0x000055555bda0be9 in clang::Sema::BuildCXXConstructExpr(clang::SourceLocation, clang::QualType, clang::NamedDecl*, clang::CXXConstructorDecl*, llvm::MutableArrayRef<clang::Expr*>, bool, bool, bool, bool, clang::CXXConstructionKind, clang::SourceRange) ()
#11874 0x000055555ba1fcef in clang::InitializationSequence::Perform(clang::Sema&, clang::InitializedEntity const&, clang::InitializationKind const&, llvm::MutableArrayRef<clang::Expr*>, clang::QualType*) ()
#11875 0x000055555bce8f6a in clang::Sema::BuildCXXNew(clang::SourceRange, bool, clang::SourceLocation, llvm::MutableArrayRef<clang::Expr*>, clang::SourceLocation, clang::SourceRange, clang::QualType, clang::TypeSourceInfo*, std::__u::optional<clang::Expr*>, clang::SourceRange, clang::Expr*) ()
#11876 0x000055555ca73bec in clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCXXNewExpr(clang::CXXNewExpr*) [clone .__uniq.16014532493918845222783194145290083557] [clone .cold] ()
#11877 0x000055555998793d in clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformStmt(clang::Stmt*, clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::StmtDiscardKind) [clone .__uniq.16014532493918845222783194145290083557] [clone .llvm.10034200992258561765] ()
#11878 0x000055555ba198e3 in clang::TreeTransform<(anonymous namespace)::TemplateInstantiator>::TransformCompoundStmt(clang::CompoundStmt*, bool) [clone .__uniq.16014532493918845222783194145290083557] ()
#11879 0x000055555bae2b42 in clang::Sema::InstantiateFunctionDefinition(clang::SourceLocation, clang::FunctionDecl*, bool, bool, bool) ()
```
</details>
I have updated the code to account for `SemaObj` potentially being null, but it now contains the same logic that we have in Sema to avoid showing the warning about stack exhaustion twice (and also reuses the one in Sema, when it's available). This is slightly trickier than I would want it to be and the behavior is not ideal, but the best I could come up with so far. Happy to hear alternative suggestions.
@ChuanqiXu9 I would like to experiment with your idea of unit-testing this in a follow-up and land this without tests for now (people seem to be ok landing this without tests, so I hope it's not controversial). I like the idea of unit-testing this, but the amount of moving pieces needed to set this up worries me, I wonder if I can find a way to write a relatively small test for this (specifically, I'm hopeful that there will be some way to reuse existing helpers to make setting up the compiler-instance mostly boilerplate-free).
I will be out until the rest of the week, but my colleague @usx95 can help land this if the PR is approved.
https://github.com/llvm/llvm-project/pull/79875
More information about the cfe-commits
mailing list