https://github.com/mizvekov created 
https://github.com/llvm/llvm-project/pull/206180

This also prevents error-recovery from forming a member specialization which is 
not a class member, which leads to crashes-on-invalid.

Fixes #204561

>From 1d92a057094e0eec5326b30630531573c24465e0 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <[email protected]>
Date: Fri, 26 Jun 2026 17:00:42 -0300
Subject: [PATCH] [clang] use typo-corrected name qualifier for template names

This also prevents error-recovery from forming a member specialization which is
not a class member, which leads to crashes-on-invalid.

Fixes #204561
---
 clang/docs/ReleaseNotes.rst                          |  1 +
 clang/lib/Sema/SemaTemplate.cpp                      |  8 ++++++++
 .../cxx1z-class-template-argument-deduction.cpp      |  5 +++--
 clang/test/SemaCXX/typo-correction.cpp               | 12 ++++++++++++
 4 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 42c5dc16ea2e1..d64428148bf6d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -776,6 +776,7 @@ Bug Fixes to C++ Support
 - Fixed crash instantiating class member specializations.
 - Fix a problem where a substitution failure when evaluating a type requirement
   could directly make the program ill-formed.
+- Typo correction now corrects the name qualifier for invalid template names.
 - Fix a problem where pack index expressions where incorrectly being regarded 
as equivalent.
 - Fixed a bug where captured variables in non-mutable lambdas were incorrectly 
treated as mutable
   when used inside decltype in the return type. (#GH180460)
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 556fa716d61e7..544bb2795a462 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -547,6 +547,14 @@ bool Sema::LookupTemplateName(LookupResult &Found, Scope 
*S, CXXScopeSpec &SS,
         } else {
           diagnoseTypo(Corrected, PDiag(diag::err_no_template_suggest) << 
Name);
         }
+
+        if (Corrected.WillReplaceSpecifier()) {
+          NestedNameSpecifier NNS = Corrected.getCorrectionSpecifier();
+          // In order to be valid, a non-empty CXXScopeSpec needs a source
+          // range.
+          SS.MakeTrivial(Context, NNS,
+                         NNS ? Found.getNameLoc() : SourceRange());
+        }
       }
     }
   }
diff --git a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp 
b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
index ece00a08954b9..b1320a8924f73 100644
--- a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
+++ b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
@@ -259,9 +259,10 @@ void f() {
 namespace GH107887 {
 
 namespace a {
-template <class> struct pair; // expected-note 3{{declared here}}
+template <class> struct pair; // expected-note 2{{declared here}}
 }
-template <class T2> pair() -> pair<T2>;   // expected-error 2{{no template 
named 'pair'}} \
+template <class T2> pair() -> pair<T2>;   // expected-error {{no template 
named 'pair'}} \
+                                          // expected-error {{out-of-line 
declaration of '<deduction guide for pair>' does not match any declaration}} \
                                           // expected-error {{deduction guide 
must be declared in the same scope}} \
                                           // expected-error {{cannot be 
deduced}} \
                                           // expected-note {{non-deducible 
template parameter 'T2'}}
diff --git a/clang/test/SemaCXX/typo-correction.cpp 
b/clang/test/SemaCXX/typo-correction.cpp
index 6aac3981bb1a1..7bf5daacbc7b7 100644
--- a/clang/test/SemaCXX/typo-correction.cpp
+++ b/clang/test/SemaCXX/typo-correction.cpp
@@ -786,4 +786,16 @@ void function() {
 }
 }
 
+namespace GH204561 {
+  template <class> struct A {
+    int B { 0; // expected-error {{expected '}'}} expected-note {{to match 
this '{'}}
+  };
+  template struct A<int>;
+
+  template <class> int x = 0; // expected-note {{'x' declared here}}
+  template <> template <class U> int A<int>::x<U &> = 4;
+  // expected-error@-1 {{no template named 'x' in 'GH204561::A<int>'; did you 
mean simply 'x'?}}
+  // expected-error@-2 {{extraneous template parameter list in template 
specialization}}
 
+  template int x<int &>;
+} // namespace GH204561

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

Reply via email to