[llvm-branch-commits] [clang] ee4e391 - [clang] Backport: NestedNameSpecifier typo correction fix

Douglas Yung via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sat Feb 28 01:25:10 PST 2026


Author: Matheus Izvekov
Date: 2026-02-28T09:24:49Z
New Revision: ee4e391b2740c01685917328d345061ae0c059d8

URL: https://github.com/llvm/llvm-project/commit/ee4e391b2740c01685917328d345061ae0c059d8
DIFF: https://github.com/llvm/llvm-project/commit/ee4e391b2740c01685917328d345061ae0c059d8.diff

LOG: [clang] Backport: NestedNameSpecifier typo correction fix

This stops typo correction from considering template parameters
as candidates for a NestedNameSpecifier when it has a prefix itself.

I think this is better than the alternative of accepting these candidates,
but otherwise droping the prefix, because it seems more far-fetched that
someone would actually try to refer to a template parameter this way.

Since this regression was never released, there are no release notes.

Backport from #181239

Fixes #167120

Added: 
    clang/test/SemaCXX/GH167120.cpp

Modified: 
    clang/lib/Sema/SemaCXXScopeSpec.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index 17ae7ca5627a9..fdbd46c109243 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -381,11 +381,17 @@ namespace {
 class NestedNameSpecifierValidatorCCC final
     : public CorrectionCandidateCallback {
 public:
-  explicit NestedNameSpecifierValidatorCCC(Sema &SRef)
-      : SRef(SRef) {}
+  explicit NestedNameSpecifierValidatorCCC(Sema &SRef, bool HasQualifier)
+      : SRef(SRef), HasQualifier(HasQualifier) {}
 
   bool ValidateCandidate(const TypoCorrection &candidate) override {
-    return SRef.isAcceptableNestedNameSpecifier(candidate.getCorrectionDecl());
+    const NamedDecl *ND = candidate.getCorrectionDecl();
+    if (!SRef.isAcceptableNestedNameSpecifier(ND))
+      return false;
+    // A template type parameter cannot have a nested name specifier.
+    if (HasQualifier && isa<TemplateTypeParmDecl>(ND))
+      return false;
+    return true;
   }
 
   std::unique_ptr<CorrectionCandidateCallback> clone() override {
@@ -394,6 +400,7 @@ class NestedNameSpecifierValidatorCCC final
 
  private:
   Sema &SRef;
+  bool HasQualifier;
 };
 
 }
@@ -596,7 +603,7 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
     // 
diff erent kind of error, so look for typos.
     DeclarationName Name = Found.getLookupName();
     Found.clear();
-    NestedNameSpecifierValidatorCCC CCC(*this);
+    NestedNameSpecifierValidatorCCC CCC(*this, /*HasQualifier=*/!SS.isEmpty());
     if (TypoCorrection Corrected = CorrectTypo(
             Found.getLookupNameInfo(), Found.getLookupKind(), S, &SS, CCC,
             CorrectTypoKind::ErrorRecovery, LookupCtx, EnteringContext)) {

diff  --git a/clang/test/SemaCXX/GH167120.cpp b/clang/test/SemaCXX/GH167120.cpp
new file mode 100644
index 0000000000000..90251c635cc3d
--- /dev/null
+++ b/clang/test/SemaCXX/GH167120.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace foo {}
+template <class type> foo::typel::x f();
+// expected-error at -1 {{no member named 'typel' in namespace 'foo'}}


        


More information about the llvm-branch-commits mailing list