[clang] 6f2df1c - [Clang] Do not eat SFINAE diagnostics for explicit template arguments (#139066)
via cfe-commits
cfe-commits at lists.llvm.org
Fri May 8 22:50:32 PDT 2026
Author: Younan Zhang
Date: 2026-05-09T13:50:27+08:00
New Revision: 6f2df1cb20cc4e6625a86670903bca6852474cb6
URL: https://github.com/llvm/llvm-project/commit/6f2df1cb20cc4e6625a86670903bca6852474cb6
DIFF: https://github.com/llvm/llvm-project/commit/6f2df1cb20cc4e6625a86670903bca6852474cb6.diff
LOG: [Clang] Do not eat SFINAE diagnostics for explicit template arguments (#139066)
Instead of merely suggesting the template arguments are invalid, we now
provide an explanation of why the explicit template argument is invalid.
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaOverload.cpp
clang/test/AST/ByteCode/cxx20.cpp
clang/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p12.cpp
clang/test/CXX/drs/cwg2xx.cpp
clang/test/CXX/drs/cwg3xx.cpp
clang/test/CXX/expr/expr.const/p3-0x.cpp
clang/test/CXX/temp/temp.param/p8-cxx20.cpp
clang/test/CXX/temp/temp.res/temp.local/p1.cpp
clang/test/Modules/cxx-templates.cpp
clang/test/SemaCXX/builtin-align-cxx.cpp
clang/test/SemaCXX/calling-conv-compat.cpp
clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
clang/test/SemaCXX/cxx2a-template-lambdas.cpp
clang/test/SemaCXX/typo-correction.cpp
clang/test/SemaSYCL/sycl-kernel-launch.cpp
clang/test/SemaTemplate/concepts-using-decl.cpp
clang/test/SemaTemplate/overload-candidates.cpp
clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 2a7c315192f2d..fa19d4b576575 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -476,6 +476,8 @@ Improvements to Clang's diagnostics
code can automatically be made portable to other host platforms that don't
support backslashes.
+- Clang now explains why template deduction fails for explicit template arguments.
+
- No longer emitting a ``-Wpre-c2y-compat`` or extension diagnostic about use
of octal literals with a ``0o`` prefix, and no longer emitting a
``-Wdeprecated-octal-literals`` diagnostic for use of octal literals without
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9605c02b819d4..c638c23f24bb5 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 96c4ce489fe04..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"
@@ -764,8 +765,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:
@@ -837,7 +846,6 @@ void DeductionFailureInfo::Destroy() {
case TemplateDeductionResult::Incomplete:
case TemplateDeductionResult::TooManyArguments:
case TemplateDeductionResult::TooFewArguments:
- case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::CUDATargetMismatch:
case TemplateDeductionResult::NonDependentConversionFailure:
break;
@@ -852,6 +860,7 @@ void DeductionFailureInfo::Destroy() {
Data = nullptr;
break;
+ case TemplateDeductionResult::InvalidExplicitArguments:
case TemplateDeductionResult::SubstitutionFailure:
// FIXME: Destroy the template argument list?
Data = nullptr;
@@ -12479,28 +12488,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");
+
+ auto Diag = S.Diag(Templated->getLocation(),
+ diag::note_ovl_candidate_explicit_arg_mismatch);
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);
+ Diag << diag::ExplicitArgMismatchNameKind::Named << ParamD->getDeclName();
+ else
+ Diag << diag::ExplicitArgMismatchNameKind::Unnamed
+ << (getDepthAndIndex(ParamD).second + 1);
+ if (PartialDiagnosticAt *PDiag = DeductionFailure.getSFINAEDiagnostic()) {
+ SmallString<128> DiagContent;
+ PDiag->second.EmitToString(S.getDiagnostics(), 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;
diff --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp
index b051c3a4984d9..d67357459653a 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -775,7 +775,7 @@ namespace FailingDestructor {
}
};
template<D d>
- void f() {} // both-note {{invalid explicitly-specified argument}}
+ 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 f12e0083fb0c9..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,21 +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'}}
+ 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'}}
+ 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'}}
+ 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'}}
+ 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 427320082a450..f81ab02e7d748 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -681,15 +681,15 @@ namespace cwg241 { // cwg241: 9
A::g<3>(b);
C::f<3>(b);
// expected-error at -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 {{candidate template ignored: template argument for template type parameter must be a type for template parameter 'T'}}
C::g<3>(b);
// expected-error at -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 {{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 at -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 {{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);
}
@@ -983,7 +983,7 @@ namespace cwg258 { // cwg258: 2.8
int &w = b.f(0);
int &x = b.g<int>(0);
// expected-error at -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 {{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 1b7b273f76b66..10bf57e422f33 100644
--- a/clang/test/CXX/drs/cwg3xx.cpp
+++ b/clang/test/CXX/drs/cwg3xx.cpp
@@ -975,8 +975,8 @@ namespace cwg354 { // cwg354: 3.1 c++11
int b0 = both<0>();
int b1 = both<(int*)0>();
// cxx98-error at -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 {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+ // 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 3eedef3cf7712..eb7d59f679e6b 100644
--- a/clang/test/CXX/expr/expr.const/p3-0x.cpp
+++ b/clang/test/CXX/expr/expr.const/p3-0x.cpp
@@ -107,7 +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'}}
+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 a3478c0669661..9b1d697cd9805 100644
--- a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
+++ b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
@@ -40,7 +40,7 @@ namespace ConstDestruction {
};
template<D d>
- void f() {} // expected-note 2{{invalid explicitly-specified argument}}
+ 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 faa85cb5fce30..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,9 +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}}
+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}}
+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 1537682f37438..15f6091774424 100644
--- a/clang/test/Modules/cxx-templates.cpp
+++ b/clang/test/Modules/cxx-templates.cpp
@@ -42,7 +42,7 @@ 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 at Inputs/cxx-templates-a.h:11 {{candidate}}
+ // expected-note at Inputs/cxx-templates-a.h:11 {{non-type parameter of template template parameter cannot be narrowed from type 'int' to 'char'}}
// expected-note at Inputs/cxx-templates-b.h:11 {{candidate}}
template_param_kinds_2<Tmpl_T_I_I>(); // expected-error {{ambiguous}}
diff --git a/clang/test/SemaCXX/builtin-align-cxx.cpp b/clang/test/SemaCXX/builtin-align-cxx.cpp
index 213a285e23eb2..51e610ccc0cd1 100644
--- a/clang/test/SemaCXX/builtin-align-cxx.cpp
+++ b/clang/test/SemaCXX/builtin-align-cxx.cpp
@@ -4,7 +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}}
+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 9bb448ffef225..abd595df7663a 100644
--- a/clang/test/SemaCXX/calling-conv-compat.cpp
+++ b/clang/test/SemaCXX/calling-conv-compat.cpp
@@ -425,6 +425,6 @@ namespace D50526 {
void h() { g<void, h>(); }
#if !_M_X64
// expected-error at -2 {{no matching function for call to}}
- // expected-note at -4 {{invalid explicitly-specified argument}}
+ // expected-note at -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..de8fe057893d5 100644
--- a/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
+++ b/clang/test/SemaCXX/constexpr-function-recovery-crash.cpp
@@ -60,7 +60,7 @@ 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 {{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..45d265e2cdc2b 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;
@@ -45,8 +45,9 @@ 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 *'}} \
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 e4dadf83e0a08..6aac3981bb1a1 100644
--- a/clang/test/SemaCXX/typo-correction.cpp
+++ b/clang/test/SemaCXX/typo-correction.cpp
@@ -612,7 +612,7 @@ 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 {{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 20d9becb81929..b673025f03b40 100644
--- a/clang/test/SemaSYCL/sycl-kernel-launch.cpp
+++ b/clang/test/SemaSYCL/sycl-kernel-launch.cpp
@@ -324,7 +324,7 @@ namespace bad6 {
// No matching function for call to sycl_kernel_launch; mismatched template parameter kind.
namespace bad7 {
- // expected-note at +2 {{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+ // expected-note at +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 at +4 {{no matching function for call to 'sycl_kernel_launch'}}
diff --git a/clang/test/SemaTemplate/concepts-using-decl.cpp b/clang/test/SemaTemplate/concepts-using-decl.cpp
index 41f7b6d2f8faa..26bd0b60b691c 100644
--- a/clang/test/SemaTemplate/concepts-using-decl.cpp
+++ b/clang/test/SemaTemplate/concepts-using-decl.cpp
@@ -165,7 +165,7 @@ struct base {
struct bar : public base {
using base::foo;
- template <int N>
+ template <int N>
int foo() { return 2; }; // expected-note {{candidate template ignored: substitution failure: too many template arguments for function template 'foo'}}
};
diff --git a/clang/test/SemaTemplate/overload-candidates.cpp b/clang/test/SemaTemplate/overload-candidates.cpp
index a9c86b2118fbb..3a5bedca938bd 100644
--- a/clang/test/SemaTemplate/overload-candidates.cpp
+++ b/clang/test/SemaTemplate/overload-candidates.cpp
@@ -17,9 +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'}}
+ 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}}
+ 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 0b785700ee238..ea86227d8f569 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
@@ -43,7 +43,7 @@ void TempFunc() {}
void Useage() {
//expected-error at +2 {{no matching function}}
- //expected-note at -4 {{candidate template ignored: invalid explicitly-specified argument for template parameter 'b'}}
+ //expected-note at -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>();
}
}
More information about the cfe-commits
mailing list