llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-modules @llvm/pr-subscribers-clang Author: Ilya Biryukov (ilya-biryukov) <details> <summary>Changes</summary> 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. --- Full diff: https://github.com/llvm/llvm-project/pull/79875.diff 2 Files Affected: - (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+3-1) - (added) clang/test/Modules/lots-of-using-shadow-decls.cpp (+43) ``````````diff diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 547eb77930b4eec..e2507d7c14a15d0 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -4099,7 +4099,9 @@ Decl *ASTReader::ReadDeclRecord(DeclID 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. + SemaObj->runWithSufficientStackSpace(DeclLoc, [&] { Reader.Visit(D); }); // If this declaration is also a declaration context, get the // offsets for its tables of lexical and visible declarations. diff --git a/clang/test/Modules/lots-of-using-shadow-decls.cpp b/clang/test/Modules/lots-of-using-shadow-decls.cpp new file mode 100644 index 000000000000000..c3048352842e3f9 --- /dev/null +++ b/clang/test/Modules/lots-of-using-shadow-decls.cpp @@ -0,0 +1,43 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t + +// RUN: %clang_cc1 -std=c++20 -emit-module-interface %t/usings.cppm -o %t/usings.pcm +// RUN: %clang_cc1 -std=c++20 -fmodule-file=usings=%t/usings.pcm %t/use.cpp -verify -fsyntax-only -Wno-stack-exhausted + +// expected-no-diagnostics + +//--- usings.cppm +export module usings; + +#define TYPES1(NAME) DECLARE(NAME##a) DECLARE(NAME##b) DECLARE(NAME##c) \ + DECLARE(NAME##d) DECLARE(NAME##e) DECLARE(NAME##f) DECLARE(NAME##g) \ + DECLARE(NAME##h) DECLARE(NAME##i) DECLARE(NAME##j) +#define TYPES2(NAME) TYPES1(NAME##a) TYPES1(NAME##b) TYPES1(NAME##c) \ + TYPES1(NAME##d) TYPES1(NAME##e) TYPES1(NAME##f) TYPES1(NAME##g) \ + TYPES1(NAME##h) TYPES1(NAME##i) TYPES1(NAME##j) +#define TYPES3(NAME) TYPES2(NAME##a) TYPES2(NAME##b) TYPES2(NAME##c) \ + TYPES2(NAME##d) TYPES2(NAME##e) TYPES2(NAME##f) TYPES2(NAME##g) \ + TYPES2(NAME##h) TYPES2(NAME##i) TYPES2(NAME##j) +#define TYPES4(NAME) TYPES3(NAME##a) TYPES3(NAME##b) TYPES3(NAME##c) \ + TYPES3(NAME##d) TYPES3(NAME##e) TYPES3(NAME##f) TYPES3(NAME##g) + +#define DECLARE(NAME) struct NAME {}; +TYPES4(Type) + +export struct Base { +#undef DECLARE +#define DECLARE(NAME) void func(NAME*); +TYPES4(Type) +}; + +export struct Derived : Base { + using Base::func; +}; + +//--- use.cpp +import usings; +void test() { + Derived().func(nullptr); // expected-error{{ambiguous}} + // expected-note@* + {{candidate function}} +} `````````` </details> https://github.com/llvm/llvm-project/pull/79875 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits