[clang-tools-extra] [clangd] Avoid invalid include-fixer fuzzy-find queries (PR #212134)
Macro Terra via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 29 09:24:01 PDT 2026
https://github.com/hongtaihu updated https://github.com/llvm/llvm-project/pull/212134
>From 4a676329523c8fc3b997762154105a6a31bec6dd Mon Sep 17 00:00:00 2001
From: hongtaihu <13541229370 at qq.com>
Date: Mon, 27 Jul 2026 01:07:59 +0800
Subject: [PATCH 1/2] [clangd] Avoid invalid include-fixer fuzzy-find queries
---
clang-tools-extra/clangd/IncludeFixer.cpp | 7 +++++++
.../clangd/unittests/DiagnosticsTests.cpp | 13 +++++++++++++
2 files changed, 20 insertions(+)
diff --git a/clang-tools-extra/clangd/IncludeFixer.cpp b/clang-tools-extra/clangd/IncludeFixer.cpp
index 5ecf853524a3f..40b82902576f4 100644
--- a/clang-tools-extra/clangd/IncludeFixer.cpp
+++ b/clang-tools-extra/clangd/IncludeFixer.cpp
@@ -397,6 +397,13 @@ std::optional<std::string> getSpelledSpecifier(const CXXScopeSpec &SS,
std::optional<CheapUnresolvedName> extractUnresolvedNameCheaply(
const SourceManager &SM, const DeclarationNameInfo &Unresolved,
CXXScopeSpec *SS, const LangOptions &LangOpts, bool UnresolvedIsSpecifier) {
+ // A conversion function name contains a type rather than an unqualified
+ // symbol name. The type may itself be qualified, and cannot be represented
+ // by Name + Scopes.
+ if (Unresolved.getName().getNameKind() ==
+ DeclarationName::CXXConversionFunctionName)
+ return std::nullopt;
+
CheapUnresolvedName Result;
Result.Name = Unresolved.getAsString();
if (SS && SS->isNotEmpty()) { // "::" or "ns::"
diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
index 6d91ac1ef1e8e..cb1612fbd318b 100644
--- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
+++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
@@ -1560,6 +1560,19 @@ TEST(IncludeFixerTest, NoCrashMemberAccess) {
UnorderedElementsAre(Diag(Test.range(), "no member named 'xy' in 'X'")));
}
+TEST(IncludeFixerTest, IgnoreSpecialDeclarationName) {
+ auto TU = TestTU::withCode(R"cpp(// error-ok
+namespace std {}
+void f() { operator new[](0, operator::align_val_t{}); }
+ )cpp");
+ TU.ExtraArgs.push_back("-std=c++17");
+ auto Index = buildIndexWithSymbol(
+ SymbolWithHeader{"std::align_val_t", "unittest:///new.h", "<new>"});
+ TU.ExternalIndex = Index.get();
+
+ EXPECT_THAT(TU.build().getDiagnostics(), Not(IsEmpty()));
+}
+
TEST(IncludeFixerTest, UseCachedIndexResults) {
// As index results for the identical request are cached, more than 5 fixes
// are generated.
>From ae7064804871a4495006aa0e2450b18aa73f058e Mon Sep 17 00:00:00 2001
From: hongtaihu <13541229370 at qq.com>
Date: Mon, 27 Jul 2026 01:07:59 +0800
Subject: [PATCH 2/2] [clangd] Avoid invalid include-fixer fuzzy-find queries
---
clang-tools-extra/clangd/IncludeFixer.cpp | 6 ++--
.../clangd/unittests/DiagnosticsTests.cpp | 28 ++++++++++++++++++-
2 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clangd/IncludeFixer.cpp b/clang-tools-extra/clangd/IncludeFixer.cpp
index 40b82902576f4..2f056575702e0 100644
--- a/clang-tools-extra/clangd/IncludeFixer.cpp
+++ b/clang-tools-extra/clangd/IncludeFixer.cpp
@@ -397,9 +397,9 @@ std::optional<std::string> getSpelledSpecifier(const CXXScopeSpec &SS,
std::optional<CheapUnresolvedName> extractUnresolvedNameCheaply(
const SourceManager &SM, const DeclarationNameInfo &Unresolved,
CXXScopeSpec *SS, const LangOptions &LangOpts, bool UnresolvedIsSpecifier) {
- // A conversion function name contains a type rather than an unqualified
- // symbol name. The type may itself be qualified, and cannot be represented
- // by Name + Scopes.
+ // Sema reports an unresolved conversion target type separately. Don't
+ // overwrite that record with the enclosing conversion function name, whose
+ // type cannot be represented by Name + Scopes.
if (Unresolved.getName().getNameKind() ==
DeclarationName::CXXConversionFunctionName)
return std::nullopt;
diff --git a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
index cb1612fbd318b..e438477f82e8a 100644
--- a/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
+++ b/clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
@@ -1560,7 +1560,7 @@ TEST(IncludeFixerTest, NoCrashMemberAccess) {
UnorderedElementsAre(Diag(Test.range(), "no member named 'xy' in 'X'")));
}
-TEST(IncludeFixerTest, IgnoreSpecialDeclarationName) {
+TEST(IncludeFixerTest, NoCrashOnQualifiedConversionFunctionName) {
auto TU = TestTU::withCode(R"cpp(// error-ok
namespace std {}
void f() { operator new[](0, operator::align_val_t{}); }
@@ -1573,6 +1573,32 @@ void f() { operator new[](0, operator::align_val_t{}); }
EXPECT_THAT(TU.build().getDiagnostics(), Not(IsEmpty()));
}
+TEST(IncludeFixerTest, FixConversionFunctionTargetType) {
+ Annotations Test(R"cpp(// error-ok
+$insert[[]]struct Wrapper {
+ template <typename T>
+ operator T() const { return T(); }
+};
+
+void f() {
+ Wrapper W;
+ auto V = W.operator::$target[[Something]]();
+}
+ )cpp");
+ auto TU = TestTU::withCode(Test.code());
+ auto Index =
+ buildIndexWithSymbol(SymbolWithHeader{"Something", "unittest:///test.h",
+ "\"test.h\""});
+ TU.ExternalIndex = Index.get();
+
+ EXPECT_THAT(
+ TU.build().getDiagnostics(),
+ Contains(Field(&Diag::Fixes,
+ Contains(Fix(Test.range("insert"),
+ "#include \"test.h\"\n",
+ "Include \"test.h\" for symbol Something")))));
+}
+
TEST(IncludeFixerTest, UseCachedIndexResults) {
// As index results for the identical request are cached, more than 5 fixes
// are generated.
More information about the cfe-commits
mailing list