https://github.com/zyn0217 updated 
https://github.com/llvm/llvm-project/pull/139066

>From a6ee1af04225063bab4d853611c7a57b1db37aa9 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Thu, 8 May 2025 19:42:51 +0800
Subject: [PATCH 01/10] [Clang] Do not eat SFINAE diagnostics for explicit
 template arguments

---
 clang/lib/Sema/SemaOverload.cpp               | 19 ++++++++++++++++++-
 clang/test/AST/ByteCode/builtin-align-cxx.cpp |  3 ++-
 clang/test/AST/ByteCode/cxx20.cpp             |  3 ++-
 .../basic.namespace/namespace.udecl/p12.cpp   | 12 ++++++++----
 clang/test/CXX/drs/cwg2xx.cpp                 |  4 ++++
 clang/test/CXX/drs/cwg3xx.cpp                 |  2 ++
 clang/test/CXX/expr/expr.const/p3-0x.cpp      |  3 ++-
 clang/test/CXX/temp/temp.param/p8-cxx20.cpp   |  3 ++-
 .../test/CXX/temp/temp.res/temp.local/p1.cpp  |  6 ++++--
 clang/test/Modules/cxx-templates.cpp          |  2 ++
 clang/test/SemaCXX/builtin-align-cxx.cpp      |  3 ++-
 clang/test/SemaCXX/calling-conv-compat.cpp    |  3 ++-
 .../constexpr-function-recovery-crash.cpp     |  3 ++-
 clang/test/SemaCXX/cxx2a-template-lambdas.cpp |  6 ++++--
 clang/test/SemaCXX/typo-correction.cpp        |  3 ++-
 .../test/SemaTemplate/concepts-using-decl.cpp |  6 ++++--
 .../test/SemaTemplate/overload-candidates.cpp | 10 ++++++----
 .../SemaTemplate/temp_arg_nontype_cxx11.cpp   |  5 +++--
 18 files changed, 71 insertions(+), 25 deletions(-)

diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 5b224b6c08fef..9b7878434b9ad 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -749,8 +749,16 @@ clang::MakeDeductionFailureInfo(ASTContext &Context,
     break;
 
   case TemplateDeductionResult::Incomplete:
+    Result.Data = Info.Param.getOpaqueValue();
+    break;
   case TemplateDeductionResult::InvalidExplicitArguments:
     Result.Data = Info.Param.getOpaqueValue();
+    if (Info.hasSFINAEDiagnostic()) {
+      PartialDiagnosticAt *Diag = new (Result.Diagnostic) PartialDiagnosticAt(
+          SourceLocation(), PartialDiagnostic::NullDiagnostic());
+      Info.takeSFINAEDiagnostic(*Diag);
+      Result.HasDiagnostic = true;
+    }
     break;
 
   case TemplateDeductionResult::DeducedMismatch:
@@ -822,7 +830,6 @@ void DeductionFailureInfo::Destroy() {
   case TemplateDeductionResult::Incomplete:
   case TemplateDeductionResult::TooManyArguments:
   case TemplateDeductionResult::TooFewArguments:
-  case TemplateDeductionResult::InvalidExplicitArguments:
   case TemplateDeductionResult::CUDATargetMismatch:
   case TemplateDeductionResult::NonDependentConversionFailure:
     break;
@@ -837,6 +844,7 @@ void DeductionFailureInfo::Destroy() {
     Data = nullptr;
     break;
 
+  case TemplateDeductionResult::InvalidExplicitArguments:
   case TemplateDeductionResult::SubstitutionFailure:
     // FIXME: Destroy the template argument list?
     Data = nullptr;
@@ -12166,6 +12174,15 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl 
*Found, Decl *Templated,
              diag::note_ovl_candidate_explicit_arg_mismatch_unnamed)
           << (index + 1);
     }
+
+    if (PartialDiagnosticAt *PDiag = DeductionFailure.getSFINAEDiagnostic()) {
+      unsigned DiagID =
+          S.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Note, "%0");
+      SmallString<128> SFINAEArgString;
+      PDiag->second.EmitToString(S.getDiagnostics(), SFINAEArgString);
+      S.Diag(Templated->getLocation(), DiagID) << SFINAEArgString;
+    }
+
     MaybeEmitInheritedConstructorNote(S, Found);
     return;
 
diff --git a/clang/test/AST/ByteCode/builtin-align-cxx.cpp 
b/clang/test/AST/ByteCode/builtin-align-cxx.cpp
index a1edf307d6c47..973fd1b620525 100644
--- a/clang/test/AST/ByteCode/builtin-align-cxx.cpp
+++ b/clang/test/AST/ByteCode/builtin-align-cxx.cpp
@@ -4,7 +4,8 @@
 
 // Check that we don't crash when using dependent types in __builtin_align:
 template <typename a, a b>
-void *c(void *d) { // both-note{{candidate template ignored}}
+void *c(void *d) { // both-note{{candidate template ignored}} \
+// both-note {{a non-type template parameter cannot have type 'struct x' 
before C++20}}
   return __builtin_align_down(d, b);
 }
 
diff --git a/clang/test/AST/ByteCode/cxx20.cpp 
b/clang/test/AST/ByteCode/cxx20.cpp
index 42e6ae33e92e4..1625f8eee8425 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -753,7 +753,8 @@ namespace FailingDestructor {
     }
   };
   template<D d>
-  void f() {} // both-note {{invalid explicitly-specified argument}}
+  void f() {} // both-note {{invalid explicitly-specified argument}} \
+              // both-note {{non-type template argument is not a constant 
expression}}
 
   void g() {
     f<D{0, false}>(); // both-error {{no matching function}}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp 
b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
index f12e0083fb0c9..ee38418acfb32 100644
--- a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
@@ -113,21 +113,25 @@ namespace test3 {
 
   struct Derived1 : Base {
     using Base::foo;
-    template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note 
{{invalid explicitly-specified argument for template parameter 'n'}}
+    template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note 
{{invalid explicitly-specified argument for template parameter 'n'}} \
+    // expected-note {{template argument for non-type template parameter must 
be an expression}}
   };
 
   struct Derived2 : Base {
-    template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note 
{{invalid explicitly-specified argument for template parameter 'n'}}
+    template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note 
{{invalid explicitly-specified argument for template parameter 'n'}} \
+    // expected-note {{template argument for non-type template parameter must 
be an expression}}
     using Base::foo;
   };
 
   struct Derived3 : Base {
     using Base::foo;
-    template <class T> Opaque<3> foo() { return Opaque<3>(); } // 
expected-note {{invalid explicitly-specified argument for template parameter 
'T'}}
+    template <class T> Opaque<3> foo() { return Opaque<3>(); } // 
expected-note {{invalid explicitly-specified argument for template parameter 
'T'}} \
+    // expected-note {{template argument for template type parameter must be a 
type}}
   };
 
   struct Derived4 : Base {
-    template <class T> Opaque<3> foo() { return Opaque<3>(); } // 
expected-note {{invalid explicitly-specified argument for template parameter 
'T'}}
+    template <class T> Opaque<3> foo() { return Opaque<3>(); } // 
expected-note {{invalid explicitly-specified argument for template parameter 
'T'}} \
+    // expected-note {{template argument for template type parameter must be a 
type}}
     using Base::foo;
   };
 
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index b2ae8f88ead74..604a60c9fa0c9 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -650,14 +650,17 @@ namespace cwg241 { // cwg241: 9
     C::f<3>(b);
     // expected-error@-1 {{no matching function for call to 'f'}}
     //   expected-note@#cwg241-C-f {{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'T'}}
+    //   expected-note@#cwg241-C-f {{template argument for template type 
parameter must be a type}}
     C::g<3>(b);
     // expected-error@-1 {{no matching function for call to 'g'}}
     //   expected-note@#cwg241-C-g {{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'T'}}
+    //   expected-note@#cwg241-C-g {{template argument for template type 
parameter must be a type}}
     using C::f;
     using C::g;
     f<3>(b);
     // expected-error@-1 {{no matching function for call to 'f'}}
     //   expected-note@#cwg241-C-f {{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'T'}}
+    //   expected-note@#cwg241-C-f {{template argument for template type 
parameter must be a type}}
     //   expected-note@#cwg241-A-f {{candidate function template not viable: 
requires 0 arguments, but 1 was provided}}
     g<3>(b);
   }
@@ -952,6 +955,7 @@ namespace cwg258 { // cwg258: 2.8
   int &x = b.g<int>(0);
   // expected-error@-1 {{no matching member function for call to 'g'}}
   //   expected-note@#cwg258-B-g {{candidate template ignored: invalid 
explicitly-specified argument for 1st template parameter}}
+  //   expected-note@#cwg258-B-g {{template argument for non-type template 
parameter must be an expression}}
   int &y = b.h();
   float &z = const_cast<const B&>(b).h();
 
diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp
index 8b035cf6f2370..b1b8d20187dcb 100644
--- a/clang/test/CXX/drs/cwg3xx.cpp
+++ b/clang/test/CXX/drs/cwg3xx.cpp
@@ -985,7 +985,9 @@ namespace cwg354 { // cwg354: 3.1 c++11
   int b1 = both<(int*)0>();
   // cxx98-error@-1 {{no matching function for call to 'both'}}
   //   cxx98-note@#cwg354-both-int-ptr {{candidate template ignored: invalid 
explicitly-specified argument for 1st template parameter}}
+  //   cxx98-note@#cwg354-both-int-ptr {{non-type template argument does not 
refer to any declaration}}
   //   cxx98-note@#cwg354-both-int {{candidate template ignored: invalid 
explicitly-specified argument for 1st template parameter}}
+  //   cxx98-note@#cwg354-both-int {{non-type template argument of type 'int 
*' must have an integral or enumeration type}}
 
   template<int S::*> struct ptr_mem {}; // #cwg354-ptr_mem
   ptr_mem<0> m0; // #cwg354-m0
diff --git a/clang/test/CXX/expr/expr.const/p3-0x.cpp 
b/clang/test/CXX/expr/expr.const/p3-0x.cpp
index 3eedef3cf7712..c7dafc59599dd 100644
--- a/clang/test/CXX/expr/expr.const/p3-0x.cpp
+++ b/clang/test/CXX/expr/expr.const/p3-0x.cpp
@@ -107,7 +107,8 @@ void c() {
     break;
   }
 }
-template <bool B> int f() { return B; } // expected-note {{candidate template 
ignored: invalid explicitly-specified argument for template parameter 'B'}}
+template <bool B> int f() { return B; } // expected-note {{candidate template 
ignored: invalid explicitly-specified argument for template parameter 'B'}} \
+// expected-note {{conversion from 'int (S::*)() const' to 'bool' is not 
allowed in a converted constant expression}}
 template int f<&S::operator int>(); // expected-error {{does not refer to a 
function template}}
 template int f<(bool)&S::operator int>();
 
diff --git a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp 
b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
index a3478c0669661..953b613eeef4a 100644
--- a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
+++ b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
@@ -40,7 +40,8 @@ namespace ConstDestruction {
   };
 
   template<D d>
-  void f() {} // expected-note 2{{invalid explicitly-specified argument}}
+  void f() {} // expected-note 2{{invalid explicitly-specified argument}} \
+  // expected-note 2{{non-type template argument is not a constant expression}}
 
   void g() {
     f<D{0, true}>();
diff --git a/clang/test/CXX/temp/temp.res/temp.local/p1.cpp 
b/clang/test/CXX/temp/temp.res/temp.local/p1.cpp
index faa85cb5fce30..8a49fc39e2d2b 100644
--- a/clang/test/CXX/temp/temp.res/temp.local/p1.cpp
+++ b/clang/test/CXX/temp/temp.res/temp.local/p1.cpp
@@ -10,9 +10,11 @@ template<typename> char id;
 template<typename> struct TempType {};
 template<template<typename> class> struct TempTemp {};
 
-template<typename> void use(int&); // expected-note {{invalid 
explicitly-specified argument}} expected-note {{no known conversion}}
+template<typename> void use(int&); // expected-note {{invalid 
explicitly-specified argument}} expected-note {{no known conversion}} \
+// expected-note {{use of class template 'B::template C' requires template 
arguments}}
 template<template<typename> class> void use(float&); // expected-note 2{{no 
known conversion}}
-template<int> void use(char&); // expected-note 2{{invalid 
explicitly-specified argument}}
+template<int> void use(char&); // expected-note 2{{invalid 
explicitly-specified argument}} \
+// expected-note 2{{template argument for non-type template parameter must be 
an expression}}
 
 template<typename T> struct A {
   template<typename> struct C {};
diff --git a/clang/test/Modules/cxx-templates.cpp 
b/clang/test/Modules/cxx-templates.cpp
index f587af4beb7ce..dce93f866b15c 100644
--- a/clang/test/Modules/cxx-templates.cpp
+++ b/clang/test/Modules/cxx-templates.cpp
@@ -43,11 +43,13 @@ void g() {
 
   template_param_kinds_2<Tmpl_T_C>(); // expected-error {{no matching function 
for call}}
   // expected-note@Inputs/cxx-templates-a.h:11 {{candidate}}
+  // expected-note@Inputs/cxx-templates-a.h:11 {{too many template arguments 
for class template 'Tmpl_T_C'}}
   // expected-note@Inputs/cxx-templates-b.h:11 {{candidate}}
 
   template_param_kinds_2<Tmpl_T_I_I>(); // expected-error {{ambiguous}}
   // expected-note@Inputs/cxx-templates-a.h:11 {{candidate}}
   // expected-note@Inputs/cxx-templates-b.h:11 {{candidate}}
+  // expected-note@Inputs/cxx-templates-b.h:11 {{non-type parameter of 
template template parameter cannot be narrowed from type 'int' to 'char'}}
 
   template_param_kinds_3<Tmpl_T_T_A>();
   template_param_kinds_3<Tmpl_T_T_B>();
diff --git a/clang/test/SemaCXX/builtin-align-cxx.cpp 
b/clang/test/SemaCXX/builtin-align-cxx.cpp
index d18bc2bf66551..a680ac2aaa763 100644
--- a/clang/test/SemaCXX/builtin-align-cxx.cpp
+++ b/clang/test/SemaCXX/builtin-align-cxx.cpp
@@ -3,7 +3,8 @@
 
 // Check that we don't crash when using dependent types in __builtin_align:
 template <typename a, a b>
-void *c(void *d) { // expected-note{{candidate template ignored}}
+void *c(void *d) { // expected-note{{candidate template ignored}} \
+// expected-note {{a non-type template parameter cannot have type 'struct x' 
before C++20}}
   return __builtin_align_down(d, b);
 }
 
diff --git a/clang/test/SemaCXX/calling-conv-compat.cpp 
b/clang/test/SemaCXX/calling-conv-compat.cpp
index 9bb448ffef225..8e67528717c5b 100644
--- a/clang/test/SemaCXX/calling-conv-compat.cpp
+++ b/clang/test/SemaCXX/calling-conv-compat.cpp
@@ -425,6 +425,7 @@ namespace D50526 {
   void h() { g<void, h>(); }
 #if !_M_X64
   // expected-error@-2 {{no matching function for call to}}
-  // expected-note@-4 {{invalid explicitly-specified argument}}
+  // expected-note@-4 {{invalid explicitly-specified argument}} \
+  // expected-note@-4 {{non-type template argument of type 'void ()' cannot be 
converted to a value of type 'void (*)() __attribute__((stdcall))'}}
 #endif
 }
diff --git a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp 
b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
index 90ee7892b2fc2..086bfa15fe0ea 100644
--- a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
+++ b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
@@ -60,7 +60,8 @@ constexpr void test8() {
   throw "bad";
 }
 
-template<int x> constexpr int f(int y) { // expected-note {{candidate template 
ignored}}
+template<int x> constexpr int f(int y) { // expected-note {{candidate template 
ignored}} \
+                                         // expected-note {{non-type template 
argument is not a constant expression}}
   return x * y;
 }
 constexpr int test9(int x) {
diff --git a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp 
b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp
index 00ba291fbd198..413bf7cd09667 100644
--- a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp
+++ b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -std=c++03 -verify -Dstatic_assert=_Static_assert 
-Wno-c++11-extensions -Wno-c++14-extensions -Wno-c++17-extensions 
-Wno-c++20-extensions %s
 // RUN: %clang_cc1 -std=c++11 -verify=expected,cxx11,cxx11-cxx14 
-Wno-c++20-extensions -Wno-c++17-extensions -Wno-c++14-extensions  %s
 // RUN: %clang_cc1 -std=c++14 -verify=expected,cxx11-cxx14,cxx14 
-Wno-c++20-extensions -Wno-c++17-extensions %s
-// RUN: %clang_cc1 -std=c++17 -verify -Wno-c++20-extensions %s
-// RUN: %clang_cc1 -std=c++20 -verify %s
+// RUN: %clang_cc1 -std=c++17 -verify=expected,cxx17,cxx17-cxx20 
-Wno-c++20-extensions %s
+// RUN: %clang_cc1 -std=c++20 -verify=expected,cxx20,cxx17-cxx20 %s
 
 template<typename, typename>
 inline const bool is_same = false;
@@ -47,6 +47,8 @@ constexpr T outer() {
   return []<T x>() { return x; }.template operator()<123>(); // expected-error 
{{no matching member function}}  \
                                                                 expected-note 
{{candidate template ignored}}    \
         cxx11-note {{non-literal type '<dependent type>' cannot be used in a 
constant expression}} \
+        cxx11-cxx14-note {{non-type template argument does not refer to any 
declaration}} \
+        cxx17-cxx20-note {{value of type 'int' is not implicitly convertible 
to 'int *'}} \
         cxx14-note {{non-literal type}}
 }
 static_assert(outer<int>() == 123); // cxx11-cxx14-error {{not an integral 
constant expression}} cxx11-cxx14-note {{in call}}
diff --git a/clang/test/SemaCXX/typo-correction.cpp 
b/clang/test/SemaCXX/typo-correction.cpp
index 45f42c4260358..c25d01eade890 100644
--- a/clang/test/SemaCXX/typo-correction.cpp
+++ b/clang/test/SemaCXX/typo-correction.cpp
@@ -614,7 +614,8 @@ int bar() {
 
 namespace testIncludeTypeInTemplateArgument {
 template <typename T, typename U>
-void foo(T t = {}, U = {}); // expected-note {{candidate template ignored}}
+void foo(T t = {}, U = {}); // expected-note {{candidate template ignored}} \
+                            // expected-note {{template argument for template 
type parameter must be a type}}
 
 class AddObservation {}; // expected-note {{declared here}}
 int bar1() {
diff --git a/clang/test/SemaTemplate/concepts-using-decl.cpp 
b/clang/test/SemaTemplate/concepts-using-decl.cpp
index fca69dea5c88f..cad160fd585c0 100644
--- a/clang/test/SemaTemplate/concepts-using-decl.cpp
+++ b/clang/test/SemaTemplate/concepts-using-decl.cpp
@@ -165,8 +165,10 @@ struct base {
 
 struct bar : public base {
   using base::foo;
-  template <int N> 
-  int foo() { return 2; }; // expected-note {{candidate template ignored: 
substitution failure: too many template arguments for function template 'foo'}}
+  template <int N>
+  int foo() { return 2; };
+  // expected-note@-1 {{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'N'}} \
+  // expected-note@-1 {{too many template arguments for function template 
'foo'}}
 };
 
 void func() {
diff --git a/clang/test/SemaTemplate/overload-candidates.cpp 
b/clang/test/SemaTemplate/overload-candidates.cpp
index de998d74f9af6..25f0492a71729 100644
--- a/clang/test/SemaTemplate/overload-candidates.cpp
+++ b/clang/test/SemaTemplate/overload-candidates.cpp
@@ -16,10 +16,12 @@ void test_dyn_cast(int* ptr) {
   (void)dyn_cast(ptr); // expected-error{{no matching function for call to 
'dyn_cast'}}
 }
 
-template<int I, typename T> 
-  void get(const T&); // expected-note{{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'I'}}
-template<template<class T> class, typename T> 
-  void get(const T&); // expected-note{{candidate template ignored: invalid 
explicitly-specified argument for 1st template parameter}}
+template<int I, typename T>
+  void get(const T&); // expected-note{{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'I'}} \
+  // expected-note {{template argument for non-type template parameter must be 
an expression}}
+template<template<class T> class, typename T>
+  void get(const T&); // expected-note{{candidate template ignored: invalid 
explicitly-specified argument for 1st template parameter}} \
+  // expected-note {{template argument for template template parameter must be 
a class template}}
 
 void test_get(void *ptr) {
   get<int>(ptr); // expected-error{{no matching function for call to 'get'}}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp 
b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
index 5752cbac0291d..44bc5b7642f76 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
@@ -42,8 +42,9 @@ template <int a, unsigned b, int c>
 void TempFunc() {}
 
 void Useage() {
-  //expected-error@+2 {{no matching function}}
-  //expected-note@-4 {{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'b'}}
+  //expected-error@+3 {{no matching function}}
+  //expected-note@-4 {{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'b'}} \
+  //expected-note@-4 {{non-type template argument evaluates to -1, which 
cannot be narrowed to type 'unsigned int'}}
   TempFunc<1, -1, 1>();
 }
 }

>From 9fa53c12cee111d6a219705c917af8261d856a60 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Fri, 9 May 2025 14:32:30 +0800
Subject: [PATCH 02/10] Fix tests

---
 clang/test/Modules/cxx-templates.cpp            | 2 +-
 clang/test/SemaTemplate/concepts-using-decl.cpp | 4 +---
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/clang/test/Modules/cxx-templates.cpp 
b/clang/test/Modules/cxx-templates.cpp
index dce93f866b15c..cc3ce41fbdf61 100644
--- a/clang/test/Modules/cxx-templates.cpp
+++ b/clang/test/Modules/cxx-templates.cpp
@@ -43,7 +43,7 @@ void g() {
 
   template_param_kinds_2<Tmpl_T_C>(); // expected-error {{no matching function 
for call}}
   // expected-note@Inputs/cxx-templates-a.h:11 {{candidate}}
-  // expected-note@Inputs/cxx-templates-a.h:11 {{too many template arguments 
for class template 'Tmpl_T_C'}}
+  // expected-note@Inputs/cxx-templates-a.h:11 {{non-type parameter of 
template template parameter cannot be narrowed from type 'int' to 'char'}}
   // expected-note@Inputs/cxx-templates-b.h:11 {{candidate}}
 
   template_param_kinds_2<Tmpl_T_I_I>(); // expected-error {{ambiguous}}
diff --git a/clang/test/SemaTemplate/concepts-using-decl.cpp 
b/clang/test/SemaTemplate/concepts-using-decl.cpp
index cad160fd585c0..6e9c21dab70bc 100644
--- a/clang/test/SemaTemplate/concepts-using-decl.cpp
+++ b/clang/test/SemaTemplate/concepts-using-decl.cpp
@@ -166,9 +166,7 @@ struct base {
 struct bar : public base {
   using base::foo;
   template <int N>
-  int foo() { return 2; };
-  // expected-note@-1 {{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'N'}} \
-  // expected-note@-1 {{too many template arguments for function template 
'foo'}}
+  int foo() { return 2; }; // expected-note {{candidate template ignored: 
substitution failure: too many template arguments for function template 'foo'}}
 };
 
 void func() {

>From a007101158976d957e9d63330f3a8723dc1467a0 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Sat, 10 May 2025 18:59:03 +0800
Subject: [PATCH 03/10] [Clang] Don't ditch typo-corrected lookup result

For a member function call like 'foo.bar<int>()', there are two
typo-correction points after parsing the dot. The first occurs in
ParseOptionalCXXScopeSpecifier, which tries to annotate the template
name following any scope specifiers.

If the template name bar is not found within 'foo', the parser was
previously instructed to drop any function templates found outside of
the scope. This was intended to prevent ambiguity in expressions
like 'foo->bar < 7', as explained in commit 50a3cddd. However, it's
unnecessary to discard typo-corrected results that were strictly
resolved within the scope 'foo'.

We won't perform a second typo-correction in ParseUnqualifiedId after
the name being annotated.
---
 clang/docs/ReleaseNotes.rst                         |  3 +++
 clang/lib/Sema/SemaTemplate.cpp                     |  3 +++
 .../basic/basic.lookup/basic.lookup.classref/p1.cpp | 13 +++++++++++++
 3 files changed, 19 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5ccd346a93b4f..246e10a0bc953 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -412,6 +412,9 @@ Improvements to Clang's diagnostics
   the ``-Wc99-designator`` diagnostic group, as they also are about the
   behavior of the C99 feature as it was introduced into C++20. Fixes #GH47037
 
+- Fixed a duplicate diagnostic when performing typo correction on function 
template
+  calls with explicit template arguments. Fixes #GH139226.
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 894f072d84989..af1556059f09f 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -523,6 +523,9 @@ bool Sema::LookupTemplateName(LookupResult &Found, Scope 
*S, CXXScopeSpec &SS,
       if (Found.isAmbiguous()) {
         Found.clear();
       } else if (!Found.empty()) {
+        // Do not erase the typo-corrected result to avoid duplicating the typo
+        // correction in future.
+        AllowFunctionTemplatesInLookup = true;
         Found.setLookupName(Corrected.getCorrection());
         if (LookupCtx) {
           std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp 
b/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
index e3599db18350b..3633ef1c293e2 100644
--- a/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
+++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.classref/p1.cpp
@@ -98,3 +98,16 @@ namespace PR11856 {
     }
   }
 }
+
+namespace GH139226 {
+
+struct Foo {
+  template <class T> void LookupWithID(); // expected-note {{declared here}}
+};
+
+void test(Foo &f) {
+  f.LookupWithId<int>();
+  // expected-error@-1 {{did you mean 'LookupWithID'}}
+}
+
+}

>From 6fc2e25691d4feef8311e7b85debf6e3ef5faec0 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Wed, 23 Jul 2025 18:57:27 +0800
Subject: [PATCH 04/10] TODO

---
 clang/lib/Sema/SemaOverload.cpp | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 15a40fb20cc3f..08171465fefaf 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -12320,12 +12320,13 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl 
*Found, Decl *Templated,
           << (index + 1);
     }
 
+    // FIXME: Attach this diagnostic to the parent error.
     if (PartialDiagnosticAt *PDiag = DeductionFailure.getSFINAEDiagnostic()) {
       unsigned DiagID =
           S.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Note, "%0");
-      SmallString<128> SFINAEArgString;
-      PDiag->second.EmitToString(S.getDiagnostics(), SFINAEArgString);
-      S.Diag(Templated->getLocation(), DiagID) << SFINAEArgString;
+      SmallString<128> DiagContent;
+      PDiag->second.EmitToString(S.getDiagnostics(), DiagContent);
+      S.Diag(Templated->getLocation(), DiagID) << DiagContent;
     }
 
     MaybeEmitInheritedConstructorNote(S, Found);

>From 172585ad2a6d5d80646629797221db58c86e0606 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Wed, 30 Jul 2025 13:16:28 +0800
Subject: [PATCH 05/10] [Clang] Don't allow implicit this access when checking
 function constraints

We allowed implicit this access when checking associated constraints after
CWG2369. As a result, some of the invalid function call expressions were
not properly SFINAE'ed out and ended up as hard errors at evaluation time.

We tried fixing that by mucking around the CurContext, but that spawned
additional breakages and I think it's probably safe to revert to the
previous behavior to avoid churns.

Though there is CWG2589, which justifies the previous change, it's not
what we're pursuing now.
---
 clang/docs/ReleaseNotes.rst          |  1 -
 clang/lib/Sema/SemaConcept.cpp       |  4 ----
 clang/lib/Sema/SemaTemplate.cpp      |  2 --
 clang/test/SemaTemplate/concepts.cpp | 34 ++++++++++++++--------------
 4 files changed, 17 insertions(+), 24 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 99e587ac8d145..a827cabf1f5aa 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -960,7 +960,6 @@ Bug Fixes to C++ Support
 - Fixed an access checking bug when initializing non-aggregates in default 
arguments (#GH62444), (#GH83608)
 - Fixed a pack substitution bug in deducing class template partial 
specializations. (#GH53609)
 - Fixed a crash when constant evaluating some explicit object member 
assignment operators. (#GH142835)
-- Fixed an access checking bug when substituting into concepts (#GH115838)
 - Fix a bug where private access specifier of overloaded function not 
respected. (#GH107629)
 - Correctly handles calling an explicit object member function template 
overload set
   through its address (``(&Foo::bar<baz>)()``).
diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp
index 834417f8e15ac..20567a6d9d1a8 100644
--- a/clang/lib/Sema/SemaConcept.cpp
+++ b/clang/lib/Sema/SemaConcept.cpp
@@ -1097,10 +1097,6 @@ static bool CheckFunctionConstraintsWithoutInstantiation(
   }
 
   Sema::ContextRAII SavedContext(SemaRef, FD);
-  std::optional<Sema::CXXThisScopeRAII> ThisScope;
-  if (auto *Method = dyn_cast<CXXMethodDecl>(FD))
-    ThisScope.emplace(SemaRef, /*Record=*/Method->getParent(),
-                      /*ThisQuals=*/Method->getMethodQualifiers());
   return SemaRef.CheckConstraintSatisfaction(
       Template, TemplateAC, MLTAL, PointOfInstantiation, Satisfaction);
 }
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index b76619fc50268..f067aedf1cc9f 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -4749,8 +4749,6 @@ Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,
   EnterExpressionEvaluationContext EECtx{
       *this, ExpressionEvaluationContext::Unevaluated, CSD};
 
-  ContextRAII CurContext(*this, CSD->getDeclContext(),
-                         /*NewThisContext=*/false);
   if (!AreArgsDependent &&
       CheckConstraintSatisfaction(
           NamedConcept, 
AssociatedConstraint(NamedConcept->getConstraintExpr()),
diff --git a/clang/test/SemaTemplate/concepts.cpp 
b/clang/test/SemaTemplate/concepts.cpp
index 62a4f95d79c74..6d6052791507d 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1228,25 +1228,25 @@ template <KnownKind T> struct KnownType {
 
 }
 
-namespace GH115838 {
+namespace CWG2369_Regression_2 {
 
-template<typename T> concept has_x = requires(T t) {{ t.x };};
-
-class Publ { public:    int x = 0; };
-class Priv { private:   int x = 0; };
-class Prot { protected: int x = 0; };
-class Same { protected: int x = 0; };
-
-template<typename T> class D;
-template<typename T> requires ( has_x<T>) class D<T>: public T { public: 
static constexpr bool has = 1; };
-template<typename T> requires (!has_x<T>) class D<T>: public T { public: 
static constexpr bool has = 0; };
+template <typename T>
+concept HasFastPropertyForAttribute =
+    requires(T element, int name) { element.propertyForAttribute(name); };
+
+template <typename OwnerType>
+struct SVGPropertyOwnerRegistry {
+  static int fastAnimatedPropertyLookup() {
+    static_assert (HasFastPropertyForAttribute<OwnerType>);
+    return 1;
+  }
+};
 
-// "Same" is identical to "Prot" but queried before used.
-static_assert(!has_x<Same>,  "Protected should be invisible.");
-static_assert(!D<Same>::has, "Protected should be invisible.");
+class SVGCircleElement {
+  friend SVGPropertyOwnerRegistry<SVGCircleElement>;
+  void propertyForAttribute(int);
+};
 
-static_assert( D<Publ>::has, "Public should be visible.");
-static_assert(!D<Priv>::has, "Private should be invisible.");
-static_assert(!D<Prot>::has, "Protected should be invisible.");
+int i = 
SVGPropertyOwnerRegistry<SVGCircleElement>::fastAnimatedPropertyLookup();
 
 }

>From 7b2ced91ebb719a8ce4a3d1fc17d26ab64aa1da8 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Fri, 8 May 2026 18:16:46 +0800
Subject: [PATCH 06/10] Update tests

---
 clang/test/SemaSYCL/sycl-kernel-launch.cpp      | 2 +-
 clang/test/SemaTemplate/overload-candidates.cpp | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/test/SemaSYCL/sycl-kernel-launch.cpp 
b/clang/test/SemaSYCL/sycl-kernel-launch.cpp
index 20d9becb81929..06713bb2225af 100644
--- a/clang/test/SemaSYCL/sycl-kernel-launch.cpp
+++ b/clang/test/SemaSYCL/sycl-kernel-launch.cpp
@@ -327,7 +327,7 @@ namespace bad7 {
   // expected-note@+2 {{candidate template ignored: invalid 
explicitly-specified argument for 1st template parameter}}
   template<int, typename... Ts>
   void sycl_kernel_launch(const char *, Ts...);
-  // expected-error@+4 {{no matching function for call to 
'sycl_kernel_launch'}}
+  // expected-error@+4 {{no matching function for call to 
'sycl_kernel_launch'}} expected-note@-1 {{template argument for non-type 
template parameter must be an expression}}
   // expected-note@+2 {{this indicates a problem with the SYCL runtime header 
files; please consider reporting this to your SYCL runtime provider}}
   // expected-note-re@+1 {{in implicit call to 'sycl_kernel_launch' with 
template argument 'BADKN<7>' and function arguments (lvalue of type 'const 
char[{{[0-9]*}}]', xvalue of type 'BADKT<7>') required here}}
   [[clang::sycl_kernel_entry_point(BADKN<7>)]]
diff --git a/clang/test/SemaTemplate/overload-candidates.cpp 
b/clang/test/SemaTemplate/overload-candidates.cpp
index a9c86b2118fbb..ef48456adf72f 100644
--- a/clang/test/SemaTemplate/overload-candidates.cpp
+++ b/clang/test/SemaTemplate/overload-candidates.cpp
@@ -18,8 +18,10 @@ void test_dyn_cast(int* ptr) {
 
 template<int I, typename T>
   void get(const T&); // expected-note{{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'I'}}
+  // expected-note@-1{{template argument for non-type template parameter must 
be an expression}}
 template<template<class T> class, typename T>
   void get(const T&); // expected-note{{candidate template ignored: invalid 
explicitly-specified argument for 1st template parameter}}
+  // expected-note@-1{{template argument for template template parameter must 
be a class template}}
 
 void test_get(void *ptr) {
   get<int>(ptr); // expected-error{{no matching function for call to 'get'}}

>From c96fa86b2b24503032ae3af7aa7b1932f8dfce9b Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Fri, 8 May 2026 18:18:54 +0800
Subject: [PATCH 07/10] release note

---
 clang/docs/ReleaseNotes.rst | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 8b03039fc122a..d70c6f6eca512 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -366,8 +366,7 @@ Improvements to Clang's diagnostics
   code can automatically be made portable to other host platforms that don't
   support backslashes.
 
-- Fixed a duplicate diagnostic when performing typo correction on function 
template
-  calls with explicit template arguments. Fixes #GH139226.
+- Clang now explains why template deduction fails for explicit template 
arguments.
 
 Improvements to Clang's time-trace
 ----------------------------------

>From 69ff8a574ba6a50b7fd992f0fa9bdfe389c18ff2 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Fri, 8 May 2026 19:40:03 +0800
Subject: [PATCH 08/10] Consolidate the notes

---
 .../clang/Basic/DiagnosticSemaKinds.td        | 12 +++---
 clang/lib/Sema/SemaOverload.cpp               | 37 +++++++------------
 2 files changed, 20 insertions(+), 29 deletions(-)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c69b2ce3648f8..2894fb55734f0 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5231,14 +5231,14 @@ def note_ovl_candidate_inconsistent_deduction_types : 
Note<
     "candidate template ignored: deduced values %diff{"
     "of conflicting types for parameter %0 (%1 of type $ vs. %3 of type $)|"
     "%1 and %3 of conflicting types for parameter %0}2,4">;
-def note_ovl_candidate_explicit_arg_mismatch_named : Note<
-    "candidate template ignored: invalid explicitly-specified argument "
-    "for template parameter %0">;
 def note_ovl_candidate_unsatisfied_constraints : Note<
     "candidate template ignored: constraints not satisfied%0">;
-def note_ovl_candidate_explicit_arg_mismatch_unnamed : Note<
-    "candidate template ignored: invalid explicitly-specified argument "
-    "for %ordinal0 template parameter">;
+def note_ovl_candidate_explicit_arg_mismatch : Note<
+    "candidate template ignored: %enum_select<ExplicitArgMismatchReasonKind>{"
+    "%Vague{invalid explicitly-specified argument}|"
+    "%Detailed{%3}}2 for %enum_select<ExplicitArgMismatchNameKind>{"
+    "%Named{template parameter %1}|"
+    "%Unnamed{%ordinal1 template parameter}}0">;
 def note_ovl_candidate_instantiation_depth : Note<
     "candidate template ignored: substitution exceeded maximum template "
     "instantiation depth">;
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 9b69ee79d9024..09e938b9eed12 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -22,6 +22,7 @@
 #include "clang/AST/Type.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
+#include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/SourceManager.h"
@@ -44,6 +45,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include <algorithm>
 #include <cassert>
+#include <clang/Sema/SemaInternal.h>
 #include <cstddef>
 #include <cstdlib>
 #include <optional>
@@ -12487,38 +12489,27 @@ static void DiagnoseBadDeduction(Sema &S, NamedDecl 
*Found, Decl *Templated,
     return;
   }
 
-  case TemplateDeductionResult::InvalidExplicitArguments:
+  case TemplateDeductionResult::InvalidExplicitArguments: {
     assert(ParamD && "no parameter found for invalid explicit arguments");
-    if (ParamD->getDeclName())
-      S.Diag(Templated->getLocation(),
-             diag::note_ovl_candidate_explicit_arg_mismatch_named)
-          << ParamD->getDeclName();
-    else {
-      int index = 0;
-      if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(ParamD))
-        index = TTP->getIndex();
-      else if (NonTypeTemplateParmDecl *NTTP
-                                  = dyn_cast<NonTypeTemplateParmDecl>(ParamD))
-        index = NTTP->getIndex();
-      else
-        index = cast<TemplateTemplateParmDecl>(ParamD)->getIndex();
-      S.Diag(Templated->getLocation(),
-             diag::note_ovl_candidate_explicit_arg_mismatch_unnamed)
-          << (index + 1);
-    }
 
-    // FIXME: Attach this diagnostic to the parent error.
+    auto Diag = S.Diag(Templated->getLocation(),
+                       diag::note_ovl_candidate_explicit_arg_mismatch);
+    if (ParamD->getDeclName())
+      Diag << diag::ExplicitArgMismatchNameKind::Named << 
ParamD->getDeclName();
+    else
+      Diag << diag::ExplicitArgMismatchNameKind::Unnamed
+           << (getDepthAndIndex(ParamD).second + 1);
     if (PartialDiagnosticAt *PDiag = DeductionFailure.getSFINAEDiagnostic()) {
-      unsigned DiagID =
-          S.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Note, "%0");
       SmallString<128> DiagContent;
       PDiag->second.EmitToString(S.getDiagnostics(), DiagContent);
-      S.Diag(Templated->getLocation(), DiagID) << DiagContent;
+      Diag << diag::ExplicitArgMismatchReasonKind::Detailed << DiagContent;
+    } else {
+      Diag << diag::ExplicitArgMismatchReasonKind::Vague;
     }
 
     MaybeEmitInheritedConstructorNote(S, Found);
     return;
-
+  }
   case TemplateDeductionResult::ConstraintsNotSatisfied: {
     // Format the template argument list into the argument string.
     SmallString<128> TemplateArgString;

>From 01caabe714c532b055f65dd3d22c387948a33643 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Fri, 8 May 2026 19:45:19 +0800
Subject: [PATCH 09/10] cleanup headers

---
 clang/lib/Sema/SemaOverload.cpp | 2 --
 1 file changed, 2 deletions(-)

diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 09e938b9eed12..b70303226fa34 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -22,7 +22,6 @@
 #include "clang/AST/Type.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticOptions.h"
-#include "clang/Basic/DiagnosticSema.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/SourceManager.h"
@@ -45,7 +44,6 @@
 #include "llvm/ADT/SmallVector.h"
 #include <algorithm>
 #include <cassert>
-#include <clang/Sema/SemaInternal.h>
 #include <cstddef>
 #include <cstdlib>
 #include <optional>

>From cdff7d6ac95f748397f5f38993f97ec08c1bd1e0 Mon Sep 17 00:00:00 2001
From: Younan Zhang <[email protected]>
Date: Sat, 9 May 2026 11:23:25 +0800
Subject: [PATCH 10/10] Fix build

---
 clang/lib/Sema/SemaOverload.cpp                      |  1 +
 clang/test/AST/ByteCode/cxx20.cpp                    |  3 +--
 .../dcl.dcl/basic.namespace/namespace.udecl/p12.cpp  | 12 ++++--------
 clang/test/CXX/drs/cwg2xx.cpp                        | 12 ++++--------
 clang/test/CXX/drs/cwg3xx.cpp                        |  6 ++----
 clang/test/CXX/expr/expr.const/p3-0x.cpp             |  3 +--
 clang/test/CXX/temp/temp.param/p8-cxx20.cpp          |  3 +--
 clang/test/CXX/temp/temp.res/temp.local/p1.cpp       |  6 ++----
 clang/test/Modules/cxx-templates.cpp                 |  2 --
 clang/test/SemaCXX/builtin-align-cxx.cpp             |  3 +--
 clang/test/SemaCXX/calling-conv-compat.cpp           |  1 -
 .../SemaCXX/constexpr-function-recovery-crash.cpp    |  3 +--
 clang/test/SemaCXX/cxx2a-template-lambdas.cpp        |  1 -
 clang/test/SemaCXX/typo-correction.cpp               |  3 +--
 clang/test/SemaSYCL/sycl-kernel-launch.cpp           |  4 ++--
 clang/test/SemaTemplate/overload-candidates.cpp      |  6 ++----
 clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp   |  5 ++---
 17 files changed, 25 insertions(+), 49 deletions(-)

diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index b70303226fa34..693aae757eb5a 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -33,6 +33,7 @@
 #include "clang/Sema/SemaAMDGPU.h"
 #include "clang/Sema/SemaARM.h"
 #include "clang/Sema/SemaCUDA.h"
+#include "clang/Sema/SemaInternal.h"
 #include "clang/Sema/SemaObjC.h"
 #include "clang/Sema/Template.h"
 #include "clang/Sema/TemplateDeduction.h"
diff --git a/clang/test/AST/ByteCode/cxx20.cpp 
b/clang/test/AST/ByteCode/cxx20.cpp
index bc1234ee9ccc7..d67357459653a 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -775,8 +775,7 @@ namespace FailingDestructor {
     }
   };
   template<D d>
-  void f() {} // both-note {{invalid explicitly-specified argument}} \
-              // both-note {{non-type template argument is not a constant 
expression}}
+  void f() {} // both-note {{non-type template argument is not a constant 
expression}}
 
   void g() {
     f<D{0, false}>(); // both-error {{no matching function}}
diff --git a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp 
b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
index ee38418acfb32..8805e8f10dbdd 100644
--- a/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
+++ b/clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
@@ -113,25 +113,21 @@ namespace test3 {
 
   struct Derived1 : Base {
     using Base::foo;
-    template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note 
{{invalid explicitly-specified argument for template parameter 'n'}} \
-    // expected-note {{template argument for non-type template parameter must 
be an expression}}
+    template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note 
{{template argument for non-type template parameter must be an expression for 
template parameter 'n'}}
   };
 
   struct Derived2 : Base {
-    template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note 
{{invalid explicitly-specified argument for template parameter 'n'}} \
-    // expected-note {{template argument for non-type template parameter must 
be an expression}}
+    template <int n> Opaque<2> foo() { return Opaque<2>(); } // expected-note 
{{template argument for non-type template parameter must be an expression for 
template parameter 'n'}}
     using Base::foo;
   };
 
   struct Derived3 : Base {
     using Base::foo;
-    template <class T> Opaque<3> foo() { return Opaque<3>(); } // 
expected-note {{invalid explicitly-specified argument for template parameter 
'T'}} \
-    // expected-note {{template argument for template type parameter must be a 
type}}
+    template <class T> Opaque<3> foo() { return Opaque<3>(); } // 
expected-note {{template argument for template type parameter must be a type 
for template parameter 'T'}}
   };
 
   struct Derived4 : Base {
-    template <class T> Opaque<3> foo() { return Opaque<3>(); } // 
expected-note {{invalid explicitly-specified argument for template parameter 
'T'}} \
-    // expected-note {{template argument for template type parameter must be a 
type}}
+    template <class T> Opaque<3> foo() { return Opaque<3>(); } // 
expected-note {{template argument for template type parameter must be a type 
for template parameter 'T'}}
     using Base::foo;
   };
 
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index 2f7d9a44fd4ba..f81ab02e7d748 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -681,18 +681,15 @@ namespace cwg241 { // cwg241: 9
     A::g<3>(b);
     C::f<3>(b);
     // expected-error@-1 {{no matching function for call to 'f'}}
-    //   expected-note@#cwg241-C-f {{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'T'}}
-    //   expected-note@#cwg241-C-f {{template argument for template type 
parameter must be a type}}
+    //   expected-note@#cwg241-C-f {{candidate template ignored: template 
argument for template type parameter must be a type for template parameter 'T'}}
     C::g<3>(b);
     // expected-error@-1 {{no matching function for call to 'g'}}
-    //   expected-note@#cwg241-C-g {{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'T'}}
-    //   expected-note@#cwg241-C-g {{template argument for template type 
parameter must be a type}}
+    //   expected-note@#cwg241-C-g {{candidate template ignored: template 
argument for template type parameter must be a type for template parameter 'T'}}
     using C::f;
     using C::g;
     f<3>(b);
     // expected-error@-1 {{no matching function for call to 'f'}}
-    //   expected-note@#cwg241-C-f {{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'T'}}
-    //   expected-note@#cwg241-C-f {{template argument for template type 
parameter must be a type}}
+    //   expected-note@#cwg241-C-f {{candidate template ignored: template 
argument for template type parameter must be a type for template parameter 'T'}}
     //   expected-note@#cwg241-A-f {{candidate function template not viable: 
requires 0 arguments, but 1 was provided}}
     g<3>(b);
   }
@@ -986,8 +983,7 @@ namespace cwg258 { // cwg258: 2.8
   int &w = b.f(0);
   int &x = b.g<int>(0);
   // expected-error@-1 {{no matching member function for call to 'g'}}
-  //   expected-note@#cwg258-B-g {{candidate template ignored: invalid 
explicitly-specified argument for 1st template parameter}}
-  //   expected-note@#cwg258-B-g {{template argument for non-type template 
parameter must be an expression}}
+  //   expected-note@#cwg258-B-g {{candidate template ignored: template 
argument for non-type template parameter must be an expression for 1st template 
parameter}}
   int &y = b.h();
   float &z = const_cast<const B&>(b).h();
 
diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp
index 21a79063f1a07..10bf57e422f33 100644
--- a/clang/test/CXX/drs/cwg3xx.cpp
+++ b/clang/test/CXX/drs/cwg3xx.cpp
@@ -975,10 +975,8 @@ namespace cwg354 { // cwg354: 3.1 c++11
   int b0 = both<0>();
   int b1 = both<(int*)0>();
   // cxx98-error@-1 {{no matching function for call to 'both'}}
-  //   cxx98-note@#cwg354-both-int-ptr {{candidate template ignored: invalid 
explicitly-specified argument for 1st template parameter}}
-  //   cxx98-note@#cwg354-both-int-ptr {{non-type template argument does not 
refer to any declaration}}
-  //   cxx98-note@#cwg354-both-int {{candidate template ignored: invalid 
explicitly-specified argument for 1st template parameter}}
-  //   cxx98-note@#cwg354-both-int {{non-type template argument of type 'int 
*' must have an integral or enumeration type}}
+  //   cxx98-note@#cwg354-both-int-ptr {{candidate template ignored: non-type 
template argument does not refer to any declaration for 1st template parameter}}
+  //   cxx98-note@#cwg354-both-int {{candidate template ignored: non-type 
template argument of type 'int *' must have an integral or enumeration type for 
1st template parameter}}
 
   template<int S::*> struct ptr_mem {}; // #cwg354-ptr_mem
   ptr_mem<0> m0; // #cwg354-m0
diff --git a/clang/test/CXX/expr/expr.const/p3-0x.cpp 
b/clang/test/CXX/expr/expr.const/p3-0x.cpp
index c7dafc59599dd..eb7d59f679e6b 100644
--- a/clang/test/CXX/expr/expr.const/p3-0x.cpp
+++ b/clang/test/CXX/expr/expr.const/p3-0x.cpp
@@ -107,8 +107,7 @@ void c() {
     break;
   }
 }
-template <bool B> int f() { return B; } // expected-note {{candidate template 
ignored: invalid explicitly-specified argument for template parameter 'B'}} \
-// expected-note {{conversion from 'int (S::*)() const' to 'bool' is not 
allowed in a converted constant expression}}
+template <bool B> int f() { return B; } // expected-note {{candidate template 
ignored: conversion from 'int (S::*)() const' to 'bool' is not allowed in a 
converted constant expression for template parameter 'B'}}
 template int f<&S::operator int>(); // expected-error {{does not refer to a 
function template}}
 template int f<(bool)&S::operator int>();
 
diff --git a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp 
b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
index 953b613eeef4a..9b1d697cd9805 100644
--- a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
+++ b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
@@ -40,8 +40,7 @@ namespace ConstDestruction {
   };
 
   template<D d>
-  void f() {} // expected-note 2{{invalid explicitly-specified argument}} \
-  // expected-note 2{{non-type template argument is not a constant expression}}
+  void f() {} // expected-note 2{{non-type template argument is not a constant 
expression}}
 
   void g() {
     f<D{0, true}>();
diff --git a/clang/test/CXX/temp/temp.res/temp.local/p1.cpp 
b/clang/test/CXX/temp/temp.res/temp.local/p1.cpp
index 8a49fc39e2d2b..c6d7f194182dd 100644
--- a/clang/test/CXX/temp/temp.res/temp.local/p1.cpp
+++ b/clang/test/CXX/temp/temp.res/temp.local/p1.cpp
@@ -10,11 +10,9 @@ template<typename> char id;
 template<typename> struct TempType {};
 template<template<typename> class> struct TempTemp {};
 
-template<typename> void use(int&); // expected-note {{invalid 
explicitly-specified argument}} expected-note {{no known conversion}} \
-// expected-note {{use of class template 'B::template C' requires template 
arguments}}
+template<typename> void use(int&); // expected-note {{use of class template 
'B::template C' requires template arguments}} expected-note {{no known 
conversion}}
 template<template<typename> class> void use(float&); // expected-note 2{{no 
known conversion}}
-template<int> void use(char&); // expected-note 2{{invalid 
explicitly-specified argument}} \
-// expected-note 2{{template argument for non-type template parameter must be 
an expression}}
+template<int> void use(char&); // expected-note 2{{template argument for 
non-type template parameter must be an expression}}
 
 template<typename T> struct A {
   template<typename> struct C {};
diff --git a/clang/test/Modules/cxx-templates.cpp 
b/clang/test/Modules/cxx-templates.cpp
index c6590ba7492a4..15f6091774424 100644
--- a/clang/test/Modules/cxx-templates.cpp
+++ b/clang/test/Modules/cxx-templates.cpp
@@ -42,14 +42,12 @@ void g() {
   template_param_kinds_1<int>(); // ok, from cxx-templates-b.h
 
   template_param_kinds_2<Tmpl_T_C>(); // expected-error {{no matching function 
for call}}
-  // expected-note@Inputs/cxx-templates-a.h:11 {{candidate}}
   // expected-note@Inputs/cxx-templates-a.h:11 {{non-type parameter of 
template template parameter cannot be narrowed from type 'int' to 'char'}}
   // expected-note@Inputs/cxx-templates-b.h:11 {{candidate}}
 
   template_param_kinds_2<Tmpl_T_I_I>(); // expected-error {{ambiguous}}
   // expected-note@Inputs/cxx-templates-a.h:11 {{candidate}}
   // expected-note@Inputs/cxx-templates-b.h:11 {{candidate}}
-  // expected-note@Inputs/cxx-templates-b.h:11 {{non-type parameter of 
template template parameter cannot be narrowed from type 'int' to 'char'}}
 
   template_param_kinds_3<Tmpl_T_T_A>();
   template_param_kinds_3<Tmpl_T_T_B>();
diff --git a/clang/test/SemaCXX/builtin-align-cxx.cpp 
b/clang/test/SemaCXX/builtin-align-cxx.cpp
index 3e1036dd6572e..51e610ccc0cd1 100644
--- a/clang/test/SemaCXX/builtin-align-cxx.cpp
+++ b/clang/test/SemaCXX/builtin-align-cxx.cpp
@@ -4,8 +4,7 @@
 
 // Check that we don't crash when using dependent types in __builtin_align:
 template <typename a, a b>
-void *c(void *d) { // expected-note{{candidate template ignored}} \
-// expected-note {{a non-type template parameter cannot have type 'struct x' 
before C++20}}
+void *c(void *d) { // expected-note{{a non-type template parameter cannot have 
type 'struct x' before C++20}}
   return __builtin_align_down(d, b);
 }
 
diff --git a/clang/test/SemaCXX/calling-conv-compat.cpp 
b/clang/test/SemaCXX/calling-conv-compat.cpp
index 8e67528717c5b..abd595df7663a 100644
--- a/clang/test/SemaCXX/calling-conv-compat.cpp
+++ b/clang/test/SemaCXX/calling-conv-compat.cpp
@@ -425,7 +425,6 @@ namespace D50526 {
   void h() { g<void, h>(); }
 #if !_M_X64
   // expected-error@-2 {{no matching function for call to}}
-  // expected-note@-4 {{invalid explicitly-specified argument}} \
   // expected-note@-4 {{non-type template argument of type 'void ()' cannot be 
converted to a value of type 'void (*)() __attribute__((stdcall))'}}
 #endif
 }
diff --git a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp 
b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
index 086bfa15fe0ea..de8fe057893d5 100644
--- a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
+++ b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
@@ -60,8 +60,7 @@ constexpr void test8() {
   throw "bad";
 }
 
-template<int x> constexpr int f(int y) { // expected-note {{candidate template 
ignored}} \
-                                         // expected-note {{non-type template 
argument is not a constant expression}}
+template<int x> constexpr int f(int y) { // expected-note {{non-type template 
argument is not a constant expression}}
   return x * y;
 }
 constexpr int test9(int x) {
diff --git a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp 
b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp
index 413bf7cd09667..45d265e2cdc2b 100644
--- a/clang/test/SemaCXX/cxx2a-template-lambdas.cpp
+++ b/clang/test/SemaCXX/cxx2a-template-lambdas.cpp
@@ -45,7 +45,6 @@ template<typename T>
 constexpr T outer() {
   // FIXME: The C++11 error seems wrong
   return []<T x>() { return x; }.template operator()<123>(); // expected-error 
{{no matching member function}}  \
-                                                                expected-note 
{{candidate template ignored}}    \
         cxx11-note {{non-literal type '<dependent type>' cannot be used in a 
constant expression}} \
         cxx11-cxx14-note {{non-type template argument does not refer to any 
declaration}} \
         cxx17-cxx20-note {{value of type 'int' is not implicitly convertible 
to 'int *'}} \
diff --git a/clang/test/SemaCXX/typo-correction.cpp 
b/clang/test/SemaCXX/typo-correction.cpp
index e7678501588f4..6aac3981bb1a1 100644
--- a/clang/test/SemaCXX/typo-correction.cpp
+++ b/clang/test/SemaCXX/typo-correction.cpp
@@ -612,8 +612,7 @@ int bar() {
 
 namespace testIncludeTypeInTemplateArgument {
 template <typename T, typename U>
-void foo(T t = {}, U = {}); // expected-note {{candidate template ignored}} \
-                            // expected-note {{template argument for template 
type parameter must be a type}}
+void foo(T t = {}, U = {}); // expected-note {{template argument for template 
type parameter must be a type}}
 
 class AddObservation {}; // expected-note {{declared here}}
 int bar1() {
diff --git a/clang/test/SemaSYCL/sycl-kernel-launch.cpp 
b/clang/test/SemaSYCL/sycl-kernel-launch.cpp
index 06713bb2225af..b673025f03b40 100644
--- a/clang/test/SemaSYCL/sycl-kernel-launch.cpp
+++ b/clang/test/SemaSYCL/sycl-kernel-launch.cpp
@@ -324,10 +324,10 @@ namespace bad6 {
 
 // No matching function for call to sycl_kernel_launch; mismatched template 
parameter kind.
 namespace bad7 {
-  // expected-note@+2 {{candidate template ignored: invalid 
explicitly-specified argument for 1st template parameter}}
+  // expected-note@+2 {{candidate template ignored: template argument for 
non-type template parameter must be an expression}}
   template<int, typename... Ts>
   void sycl_kernel_launch(const char *, Ts...);
-  // expected-error@+4 {{no matching function for call to 
'sycl_kernel_launch'}} expected-note@-1 {{template argument for non-type 
template parameter must be an expression}}
+  // expected-error@+4 {{no matching function for call to 
'sycl_kernel_launch'}}
   // expected-note@+2 {{this indicates a problem with the SYCL runtime header 
files; please consider reporting this to your SYCL runtime provider}}
   // expected-note-re@+1 {{in implicit call to 'sycl_kernel_launch' with 
template argument 'BADKN<7>' and function arguments (lvalue of type 'const 
char[{{[0-9]*}}]', xvalue of type 'BADKT<7>') required here}}
   [[clang::sycl_kernel_entry_point(BADKN<7>)]]
diff --git a/clang/test/SemaTemplate/overload-candidates.cpp 
b/clang/test/SemaTemplate/overload-candidates.cpp
index ef48456adf72f..3a5bedca938bd 100644
--- a/clang/test/SemaTemplate/overload-candidates.cpp
+++ b/clang/test/SemaTemplate/overload-candidates.cpp
@@ -17,11 +17,9 @@ void test_dyn_cast(int* ptr) {
 }
 
 template<int I, typename T>
-  void get(const T&); // expected-note{{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'I'}}
-  // expected-note@-1{{template argument for non-type template parameter must 
be an expression}}
+  void get(const T&); // expected-note{{candidate template ignored: template 
argument for non-type template parameter must be an expression for template 
parameter 'I'}}
 template<template<class T> class, typename T>
-  void get(const T&); // expected-note{{candidate template ignored: invalid 
explicitly-specified argument for 1st template parameter}}
-  // expected-note@-1{{template argument for template template parameter must 
be a class template}}
+  void get(const T&); // expected-note{{candidate template ignored: template 
argument for template template parameter must be a class template}}
 
 void test_get(void *ptr) {
   get<int>(ptr); // expected-error{{no matching function for call to 'get'}}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp 
b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
index 159612e944618..ea86227d8f569 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
@@ -42,9 +42,8 @@ template <int a, unsigned b, int c>
 void TempFunc() {}
 
 void Useage() {
-  //expected-error@+3 {{no matching function}}
-  //expected-note@-4 {{candidate template ignored: invalid 
explicitly-specified argument for template parameter 'b'}} \
-  //expected-note@-4 {{non-type template argument evaluates to -1, which 
cannot be narrowed to type 'unsigned int'}}
+  //expected-error@+2 {{no matching function}}
+  //expected-note@-4 {{candidate template ignored: non-type template argument 
evaluates to -1, which cannot be narrowed to type 'unsigned int' for template 
parameter 'b'}}
   TempFunc<1, -1, 1>();
 }
 }

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

Reply via email to