[clang-tools-extra] [clangd] Avoid crash on pseudo-destructor selection (PR #195939)
via cfe-commits
cfe-commits at lists.llvm.org
Thu May 7 01:16:16 PDT 2026
https://github.com/nataliakokoromyti updated https://github.com/llvm/llvm-project/pull/195939
>From 2fb9ea754fb290ad0d98cc75515042e3c709bde2 Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Tue, 5 May 2026 13:52:18 -0700
Subject: [PATCH 1/2] [clangd] Avoid crash on pseudo-destructor selection
---
clang-tools-extra/clangd/Selection.cpp | 12 ++++++++----
.../clangd/unittests/SelectionTests.cpp | 18 ++++++++++++++++++
2 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp
index b79ffc7d5a6e9..0babe71ce4788 100644
--- a/clang-tools-extra/clangd/Selection.cpp
+++ b/clang-tools-extra/clangd/Selection.cpp
@@ -895,13 +895,17 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
// rather than the TypeLoc nested inside it.
// We still traverse the TypeLoc, because it may contain other targeted
// things like the T in ~Foo<T>().
- if (const auto *CDD = N.get<CXXDestructorDecl>())
- return CDD->getNameInfo().getNamedTypeInfo()->getTypeLoc().getBeginLoc();
+ if (const auto *CDD = N.get<CXXDestructorDecl>()) {
+ if (auto *TypeInfo = CDD->getNameInfo().getNamedTypeInfo())
+ return TypeInfo->getTypeLoc().getBeginLoc();
+ }
if (const auto *ME = N.get<MemberExpr>()) {
auto NameInfo = ME->getMemberNameInfo();
if (NameInfo.getName().getNameKind() ==
- DeclarationName::CXXDestructorName)
- return NameInfo.getNamedTypeInfo()->getTypeLoc().getBeginLoc();
+ DeclarationName::CXXDestructorName) {
+ if (auto *TypeInfo = NameInfo.getNamedTypeInfo())
+ return TypeInfo->getTypeLoc().getBeginLoc();
+ }
}
return SourceRange();
diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
index 5e897fae79df4..5b325d7a6a387 100644
--- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -665,6 +665,24 @@ TEST(SelectionTest, InjectedClassName) {
EXPECT_FALSE(D->isInjectedClassName());
}
+TEST(SelectionTest, PseudoDestructorMissingTypeInfo) {
+ llvm::StringLiteral Code = R"cpp(
+ /*error-ok*/
+ struct A { ~A(); };
+ void b(const A *y) {
+ y->~decltype(A())();
+ }
+ )cpp";
+ auto AST = TestTU::withCode(Code).build();
+ bool Seen = false;
+ SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), 0,
+ Code.size(), [&](SelectionTree) {
+ Seen = true;
+ return true;
+ });
+ EXPECT_TRUE(Seen);
+}
+
TEST(SelectionTree, Metrics) {
const char *Code = R"cpp(
// error-ok: testing behavior on recovery expression
>From ea4cd9fd0b977ee499882ed62f62807a49854658 Mon Sep 17 00:00:00 2001
From: nataliakokoromyti <nataliakokoromyti at gmail.com>
Date: Thu, 7 May 2026 01:16:05 -0700
Subject: [PATCH 2/2] add FIXME
---
clang-tools-extra/clangd/Selection.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp
index 0babe71ce4788..21c9e71d3db65 100644
--- a/clang-tools-extra/clangd/Selection.cpp
+++ b/clang-tools-extra/clangd/Selection.cpp
@@ -895,6 +895,8 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
// rather than the TypeLoc nested inside it.
// We still traverse the TypeLoc, because it may contain other targeted
// things like the T in ~Foo<T>().
+ // FIXME: Investigate if getNamedTypeInfo() can still return null for
+ // invalid cases, and drop these checks when it never returns null.
if (const auto *CDD = N.get<CXXDestructorDecl>()) {
if (auto *TypeInfo = CDD->getNameInfo().getNamedTypeInfo())
return TypeInfo->getTypeLoc().getBeginLoc();
More information about the cfe-commits
mailing list