[Lldb-commits] [lldb] [lldb] handle existing ClassTemplateSpecializationDecl gracefully (PR #207705)
github-actions[bot] wrote: # :penguin: Linux x64 Test Results * 33988 tests passed * 545 tests skipped * 1 test failed ## Failed Tests (click on a test name to see its output) ### lldb-api lldb-api.python_api/run_locker/TestRunLocker.py ``` Script: -- /usr/bin/python3 /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/dotest.py -u CXXFLAGS -u CFLAGS --env LLVM_LIBS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib --env LLVM_INCLUDE_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/include --env LLVM_TOOLS_DIR=/home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin --libcxx-include-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/c++/v1 --libcxx-include-target-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/include/x86_64-unknown-linux-gnu/c++/v1 --libcxx-library-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib/x86_64-unknown-linux-gnu --triple x86_64-unknown-linux-gnu --build-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build --lldb-module-cache-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build/module-cache-lldb/lldb-api --clang-module-cache-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build/module-cache-clang/lldb-api --executable /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/lldb --lldb-python-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/local/lib/python3.12/dist-packages --compiler /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/clang --dsymutil /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin/dsymutil --make /usr/bin/gmake --llvm-tools-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./bin --lldb-obj-root /home/gha/actions-runner/_work/llvm-project/llvm-project/build/tools/lldb --lldb-libs-dir /home/gha/actions-runner/_work/llvm-project/llvm-project/build/./lib --cmake-build-type Release /home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/python_api/run_locker -p TestRunLocker.py -- Exit Code: 1 Command Output (stdout): -- "can't evaluate expressions when the process is running." Skipping the following test categories: msvcstl, dsym, pdb, gmodules, debugserver, objc -- Command Output (stderr): -- Traceback (most recent call last): File "", line 1, in AttributeError: 'NoneType' object has no attribute 'EvaluateExpression' FAIL: LLDB (/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-x86_64) :: test_run_locker (TestRunLocker.TestRunLocker.test_run_locker) Log Files: - /home/gha/actions-runner/_work/llvm-project/llvm-project/build/lldb-test-build/python_api/run_locker/TestRunLocker/Failure_test_run_locker.log PASS: LLDB (/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang-x86_64) :: test_run_locker_stop_at_entry (TestRunLocker.TestRunLocker.test_run_locker_stop_at_entry) == FAIL: test_run_locker (TestRunLocker.TestRunLocker.test_run_locker) Test that the run locker is set correctly when we launch -- Traceback (most recent call last): File "/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/packages/Python/lldbsuite/test/decorators.py", line 175, in wrapper return func(*args, **kwargs) ^ File "/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/python_api/run_locker/TestRunLocker.py", line 23, in test_run_locker self.runlocker_test(False) File "/home/gha/actions-runner/_work/llvm-project/llvm-project/lldb/test/API/python_api/run_locker/TestRunLocker.py", line 126, in runlocker_test self.assertIn( AssertionError: "can't evaluate expressions when the process is running" not found in '' Config=x86_64-/home/gha/actions-runner/_work/llvm-project/llvm-project/build/bin/clang -- Ran 2 tests in 0.524s FAILED (failures=1) -- ``` If these failures are unrelated to your changes (for example tests are broken or flaky at HEAD), please open an issue at https://github.com/llvm/llvm-project/issues and add the `infrastructure` label. https://github.com/llvm/llvm-project/pull/207705 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] handle existing ClassTemplateSpecializationDecl gracefully (PR #207705)
github-actions[bot] wrote:
:warning: C/C++ code formatter, clang-format found issues in your code.
:warning:
You can test this locally with the following command:
``bash
git-clang-format --diff origin/main HEAD --extensions cpp --
lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
--diff_from_common_commit
``
:warning:
The reproduction instructions above might return results for more than one PR
in a stack if you are using a stacked PR workflow. You can limit the results by
changing `origin/main` to the base branch/commit you want to compare against.
:warning:
View the diff from clang-format here.
``diff
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index f6deb3abd..4c394eca0 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1883,8 +1883,8 @@ TypeSP DWARFASTParserClang::ParseStructureLikeDIE(
containing_decl_ctx, GetOwningClangModule(die),
class_template_decl,
tag_decl_kind, template_param_infos);
if (class_specialization_decl) {
- clang_type =
-
m_ast.CreateClassTemplateSpecializationType(class_specialization_decl);
+ clang_type = m_ast.CreateClassTemplateSpecializationType(
+ class_specialization_decl);
m_ast.SetMetadata(class_template_decl, metadata);
m_ast.SetMetadata(class_specialization_decl, metadata);
``
https://github.com/llvm/llvm-project/pull/207705
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] handle existing ClassTemplateSpecializationDecl gracefully (PR #207705)
@@ -1882,22 +1882,27 @@ TypeSP DWARFASTParserClang::ParseStructureLikeDIE(
m_ast.CreateClassTemplateSpecializationDecl(
containing_decl_ctx, GetOwningClangModule(die),
class_template_decl,
tag_decl_kind, template_param_infos);
-if (!class_specialization_decl) {
- if (log) {
-dwarf->GetObjectFile()->GetModule()->LogMessage(
-log,
-"SymbolFileDWARF({0:p}) - Failed to create specialization for "
-"clang::ClassTemplateDecl({1}, {2:p}).",
-this, llvm::StringRef(attrs.name), class_template_decl);
- }
- return TypeSP();
+if (class_specialization_decl) {
+ clang_type =
+
m_ast.CreateClassTemplateSpecializationType(class_specialization_decl);
+
+ m_ast.SetMetadata(class_template_decl, metadata);
+ m_ast.SetMetadata(class_specialization_decl, metadata);
+} else if (log) {
+ // A specialization with identical template arguments already exists.
+ // This happens with malformed/duplicated DWARF, e.g. GCC emits several
+ // reduced copies of a std::tuple<...> instantiation whose only template
+ // child is an empty DW_TAG_GNU_template_parameter_pack, so every copy
+ // collapses to the same (empty) argument list. Failing to parse the type
+ // here would leave members that reference it (such as unique_ptr's _M_t)
+ // with a null type and crash data formatters. Instead, fall through and
+ // build a plain (non-template) record type below.
Michael137 wrote:
> A specialization with identical template arguments already exists.
`class_specialization_decl == nullptr` doesn't necessarily imply that there is
a duplicate specialization.
It's true based on the implementation, but it's not an obvious signal when
reading this code and also may change in the future. E.g., nullptr could just
be a different error condition. Probably best to signal the "there is an
existing specialization" differently then just returning nullptr. We should've
thought of that as part of
https://github.com/llvm/llvm-project/commit/4dfe212dade7
Also, could you explain why with a `class_specialization_decl == nullptr` its
fine to skip `CreateClassTemplateSpecializationType` and continue with the rest
of this function? That seems like it would cause more trouble.
https://github.com/llvm/llvm-project/pull/207705
___
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] handle existing ClassTemplateSpecializationDecl gracefully (PR #207705)
llvmorg-github-actions[bot] wrote:
@llvm/pr-subscribers-lldb
Author: Konstantin Bolshakov (konstantinbo)
Changes
This fixes #207704
Assisted-by: Github Copilot (Claude Opus 4.8)
---
Full diff: https://github.com/llvm/llvm-project/pull/207705.diff
2 Files Affected:
- (modified) lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
(+20-15)
- (modified) lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
(+26-3)
``diff
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 0506b7d4da40f..f6deb3abd3881 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1882,22 +1882,27 @@ TypeSP DWARFASTParserClang::ParseStructureLikeDIE(
m_ast.CreateClassTemplateSpecializationDecl(
containing_decl_ctx, GetOwningClangModule(die),
class_template_decl,
tag_decl_kind, template_param_infos);
-if (!class_specialization_decl) {
- if (log) {
-dwarf->GetObjectFile()->GetModule()->LogMessage(
-log,
-"SymbolFileDWARF({0:p}) - Failed to create specialization for "
-"clang::ClassTemplateDecl({1}, {2:p}).",
-this, llvm::StringRef(attrs.name), class_template_decl);
- }
- return TypeSP();
+if (class_specialization_decl) {
+ clang_type =
+
m_ast.CreateClassTemplateSpecializationType(class_specialization_decl);
+
+ m_ast.SetMetadata(class_template_decl, metadata);
+ m_ast.SetMetadata(class_specialization_decl, metadata);
+} else if (log) {
+ // A specialization with identical template arguments already exists.
+ // This happens with malformed/duplicated DWARF, e.g. GCC emits several
+ // reduced copies of a std::tuple<...> instantiation whose only template
+ // child is an empty DW_TAG_GNU_template_parameter_pack, so every copy
+ // collapses to the same (empty) argument list. Failing to parse the type
+ // here would leave members that reference it (such as unique_ptr's _M_t)
+ // with a null type and crash data formatters. Instead, fall through and
+ // build a plain (non-template) record type below.
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF({0:p}) - Specialization for
clang::ClassTemplateDecl"
+ "({1}, {2:p}) already exists; falling back to a non-template
record.",
+ this, llvm::StringRef(attrs.name), class_template_decl);
}
-
-clang_type =
-m_ast.CreateClassTemplateSpecializationType(class_specialization_decl);
-
-m_ast.SetMetadata(class_template_decl, metadata);
-m_ast.SetMetadata(class_specialization_decl, metadata);
}
if (!clang_type) {
diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
index a95d6ecfab790..66b220aa8dc98 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -622,8 +622,15 @@ TEST_F(DWARFASTParserClangTests,
TestDefaultTemplateParamParsing) {
}
TEST_F(DWARFASTParserClangTests, TestSpecDeclExistsError) {
- // Tests that parsing a ClassTemplateSpecializationDecl that already exists
- // is handled gracefully.
+ // Tests that parsing a second class DIE whose template arguments collapse to
+ // an already-existing ClassTemplateSpecializationDecl is handled gracefully.
+ // The malformed input drops DW_TAG_template_value_parameter entries, which
+ // makes two distinct specializations look structurally identical. Rather
than
+ // failing to parse the second type (which would leave members referring to
it
+ // with a null type and crash data formatters), the parser falls back to a
+ // plain, non-template record type. Critically, neither resulting type may
end
+ // up inheriting from itself, which used to cause infinite recursion during
+ // layout.
auto BufferOrError = llvm::MemoryBuffer::getFile(
GetInputFilePath("DW_AT_spec_decl_exists-test.yaml"), /*IsText=*/true);
ASSERT_TRUE(BufferOrError);
@@ -643,7 +650,23 @@ TEST_F(DWARFASTParserClangTests, TestSpecDeclExistsError) {
ASSERT_EQ(specializations.size(), 2U);
ASSERT_NE(specializations[0], nullptr);
- ASSERT_EQ(specializations[1], nullptr);
+ ASSERT_NE(specializations[1], nullptr);
+
+ // Completing each type must not recurse infinitely, and no type may inherit
+ // from itself.
+ for (auto const &type_sp : specializations) {
+CompilerType ct = type_sp->GetFullCompilerType();
+auto const *record = llvm::dyn_cast_or_null(
+ClangUtil::GetAsTagDecl(ct));
+ASSERT_NE(record, nullptr);
+if (!record->hasDefinition())
+ continue;
+for (clang::CXXBaseSpecifier const &base : record->bases()) {
+ clang::CXXRecordDec
[Lldb-commits] [lldb] [lldb] handle existing ClassTemplateSpecializationDecl gracefully (PR #207705)
https://github.com/konstantinbo ready_for_review https://github.com/llvm/llvm-project/pull/207705 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] handle existing ClassTemplateSpecializationDecl gracefully (PR #207705)
github-actions[bot] wrote: Hello @konstantinbo :wave: Thank you for submitting a Pull Request (PR) to the LLVM Project. Since this is your first PR, here are a few useful links covering our main contribution policies and review practices. * All contributions to LLVM must follow our [LLVM AI Tool Use Policy](https://llvm.org/docs/AIToolPolicy.html). In particular, if you used AI while working on this PR, remember to add a note to the PR description. * The [LLVM Code-Review Policy and Practices](https://llvm.org/docs/CodeReview.html) document contains practical information about the PR process, including how patches are reviewed and accepted, and who can review a PR. * Our [LLVM Developer Policy](https://llvm.org/docs/DeveloperPolicy.html) describes our expectations for code quality, commit summaries and contains notes on our CI system. Please reply to this message to confirm that you have read these policies, especially the LLVM AI Tool Use Policy, and that any AI tool usage has been noted in the PR description. --- ### Frequently asked questions **How do I add reviewers?** This PR will be automatically labeled, and the relevant teams will be notified. For some parts of the project, reviewers may also be added automatically. You can also add reviewers manually using the **Reviewers** section on this page. If you cannot use that section, it is probably because you do not have write permissions for the repository. In that case, you can request a review by tagging reviewers in a comment using `@` followed by their GitHub username. **What if there are no comments?** If you have not received any comments on your PR after a week, you can request a review by pinging the PR with a comment such as “Ping”. The common courtesy ping rate is once a week. Please remember that you are asking for volunteer time from other developers. **Are any special GitHub settings required to contribute to LLVM?** We only require contributors to have a public email address associated with their GitHub commits, see this [section](https://llvm.org/docs/DeveloperPolicy.html#email-addresses) of LLVM Developer Policy for details. --- If you have questions, feel free to leave a comment on this PR, or ask on [LLVM Discord](https://discord.com/invite/xS7Z362) or [LLVM Discourse](https://discourse.llvm.org/). Thank you, The LLVM Community https://github.com/llvm/llvm-project/pull/207705 ___ lldb-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
[Lldb-commits] [lldb] [lldb] handle existing ClassTemplateSpecializationDecl gracefully (PR #207705)
https://github.com/konstantinbo created
https://github.com/llvm/llvm-project/pull/207705
This fixes #207704
Assisted-by: Github Copilot (Claude Opus 4.8)
>From e8db9f9b2b6218a870cc17f45e8e8243cf5b195f Mon Sep 17 00:00:00 2001
From: Konstantin Bolshakov
Date: Mon, 6 Jul 2026 12:43:54 +0200
Subject: [PATCH] [lldb] handle existing ClassTemplateSpecializationDecl
gracefully
Assisted-by: Github Copilot (Claude Opus 4.8)
---
.../SymbolFile/DWARF/DWARFASTParserClang.cpp | 35 +++
.../DWARF/DWARFASTParserClangTests.cpp| 29 +--
2 files changed, 46 insertions(+), 18 deletions(-)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 0506b7d4da40f..f6deb3abd3881 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -1882,22 +1882,27 @@ TypeSP DWARFASTParserClang::ParseStructureLikeDIE(
m_ast.CreateClassTemplateSpecializationDecl(
containing_decl_ctx, GetOwningClangModule(die),
class_template_decl,
tag_decl_kind, template_param_infos);
-if (!class_specialization_decl) {
- if (log) {
-dwarf->GetObjectFile()->GetModule()->LogMessage(
-log,
-"SymbolFileDWARF({0:p}) - Failed to create specialization for "
-"clang::ClassTemplateDecl({1}, {2:p}).",
-this, llvm::StringRef(attrs.name), class_template_decl);
- }
- return TypeSP();
+if (class_specialization_decl) {
+ clang_type =
+
m_ast.CreateClassTemplateSpecializationType(class_specialization_decl);
+
+ m_ast.SetMetadata(class_template_decl, metadata);
+ m_ast.SetMetadata(class_specialization_decl, metadata);
+} else if (log) {
+ // A specialization with identical template arguments already exists.
+ // This happens with malformed/duplicated DWARF, e.g. GCC emits several
+ // reduced copies of a std::tuple<...> instantiation whose only template
+ // child is an empty DW_TAG_GNU_template_parameter_pack, so every copy
+ // collapses to the same (empty) argument list. Failing to parse the type
+ // here would leave members that reference it (such as unique_ptr's _M_t)
+ // with a null type and crash data formatters. Instead, fall through and
+ // build a plain (non-template) record type below.
+ dwarf->GetObjectFile()->GetModule()->LogMessage(
+ log,
+ "SymbolFileDWARF({0:p}) - Specialization for
clang::ClassTemplateDecl"
+ "({1}, {2:p}) already exists; falling back to a non-template
record.",
+ this, llvm::StringRef(attrs.name), class_template_decl);
}
-
-clang_type =
-m_ast.CreateClassTemplateSpecializationType(class_specialization_decl);
-
-m_ast.SetMetadata(class_template_decl, metadata);
-m_ast.SetMetadata(class_specialization_decl, metadata);
}
if (!clang_type) {
diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
index a95d6ecfab790..66b220aa8dc98 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -622,8 +622,15 @@ TEST_F(DWARFASTParserClangTests,
TestDefaultTemplateParamParsing) {
}
TEST_F(DWARFASTParserClangTests, TestSpecDeclExistsError) {
- // Tests that parsing a ClassTemplateSpecializationDecl that already exists
- // is handled gracefully.
+ // Tests that parsing a second class DIE whose template arguments collapse to
+ // an already-existing ClassTemplateSpecializationDecl is handled gracefully.
+ // The malformed input drops DW_TAG_template_value_parameter entries, which
+ // makes two distinct specializations look structurally identical. Rather
than
+ // failing to parse the second type (which would leave members referring to
it
+ // with a null type and crash data formatters), the parser falls back to a
+ // plain, non-template record type. Critically, neither resulting type may
end
+ // up inheriting from itself, which used to cause infinite recursion during
+ // layout.
auto BufferOrError = llvm::MemoryBuffer::getFile(
GetInputFilePath("DW_AT_spec_decl_exists-test.yaml"), /*IsText=*/true);
ASSERT_TRUE(BufferOrError);
@@ -643,7 +650,23 @@ TEST_F(DWARFASTParserClangTests, TestSpecDeclExistsError) {
ASSERT_EQ(specializations.size(), 2U);
ASSERT_NE(specializations[0], nullptr);
- ASSERT_EQ(specializations[1], nullptr);
+ ASSERT_NE(specializations[1], nullptr);
+
+ // Completing each type must not recurse infinitely, and no type may inherit
+ // from itself.
+ for (auto const &type_sp : specializations) {
+CompilerType ct = type_sp->GetFullCompilerType();
+auto const *record = llvm::dyn_cast_or_null(
+ClangUtil::GetAsTagDecl(ct));
+ASSERT_NE(reco
