Author: Matheus Izvekov
Date: 2026-02-13T09:44:05-03:00
New Revision: aac8885d323172475fca41a8c03dea495187d10f

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

LOG: [clang] NestedNameSpecifier typo correction fix (#181239)

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.

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@-1 {{no member named 'typel' in namespace 'foo'}}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to