<p dir="ltr">Thanks for letting me know. Should be straightforward to remove the default argument here. Please feel free to revert (or fix); otherwise I'll fix it in the morning.</p>
<div class="gmail_quote">On 17 Apr 2014 01:13, "Timur Iskhodzhanov" <<a href="mailto:timurrrr@google.com">timurrrr@google.com</a>> wrote:<br type="attribution"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
FYI this doesn't build with VS2013<br>
<br>
tools\clang\lib\Sema\SemaTemplate.cpp(1736) : error C3486: a parameter<br>
for a lambda cannot have a default argument<br>
<br>
tools\clang\lib\Sema\SemaTemplate.cpp(1826) : error C2064: term does<br>
not evaluate to a function taking 1 arguments<br>
class does not define an 'operator()' or a user defined<br>
conversion operator to a pointer-to-function or reference-to-function<br>
that takes appropriate number of arguments<br>
<br>
tools\clang\lib\Sema\SemaTemplate.cpp(1962) : error C2064: term does<br>
not evaluate to a function taking 1 arguments<br>
class does not define an 'operator()' or a user defined<br>
conversion operator to a pointer-to-function or reference-to-function<br>
that takes appropriate number of arguments<br>
<br>
2014-04-17 7:52 GMT+04:00 Richard Smith <<a href="mailto:richard-llvm@metafoo.co.uk">richard-llvm@metafoo.co.uk</a>>:<br>
> Author: rsmith<br>
> Date: Wed Apr 16 22:52:20 2014<br>
> New Revision: 206444<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=206444&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=206444&view=rev</a><br>
> Log:<br>
> PR19340: If we see a declaration of a member of an unspecialized class template<br>
> that looks like it might be an explicit specialization, don't recover as an<br>
> explicit specialization (bypassing the check that would reject that).<br>
><br>
> Modified:<br>
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
> cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
> cfe/trunk/test/SemaTemplate/explicit-specialization-member.cpp<br>
><br>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=206444&r1=206443&r2=206444&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=206444&r1=206443&r2=206444&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br>
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Apr 16 22:52:20 2014<br>
> @@ -3267,8 +3267,8 @@ def err_template_qualified_declarator_no<br>
> "nested name specifier '%0' for declaration does not refer into a class, "<br>
> "class template or class template partial specialization">;<br>
> def err_specialize_member_of_template : Error<<br>
> - "cannot specialize (with 'template<>') a member of an unspecialized "<br>
> - "template">;<br>
> + "cannot specialize %select{|(with 'template<>') }0a member of an "<br>
> + "unspecialized template">;<br>
><br>
> // C++ Class Template Partial Specialization<br>
> def err_default_arg_in_partial_spec : Error<<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=206444&r1=206443&r2=206444&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=206444&r1=206443&r2=206444&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Apr 16 22:52:20 2014<br>
> @@ -1721,6 +1721,38 @@ TemplateParameterList *Sema::MatchTempla<br>
> // template<> for each enclosing class template that is<br>
> // explicitly specialized.<br>
> bool SawNonEmptyTemplateParameterList = false;<br>
> +<br>
> + auto CheckExplicitSpecialization = [&](SourceRange Range,<br>
> + bool Recovery = false) {<br>
> + if (SawNonEmptyTemplateParameterList) {<br>
> + Diag(DeclLoc, diag::err_specialize_member_of_template)<br>
> + << !Recovery << Range;<br>
> + Invalid = true;<br>
> + IsExplicitSpecialization = false;<br>
> + return true;<br>
> + }<br>
> +<br>
> + return false;<br>
> + };<br>
> +<br>
> + auto DiagnoseMissingExplicitSpecialization = [&] (SourceRange Range) {<br>
> + // Check that we can have an explicit specialization here.<br>
> + if (CheckExplicitSpecialization(Range, true))<br>
> + return true;<br>
> +<br>
> + // We don't have a template header, but we should.<br>
> + SourceLocation ExpectedTemplateLoc;<br>
> + if (!ParamLists.empty())<br>
> + ExpectedTemplateLoc = ParamLists[0]->getTemplateLoc();<br>
> + else<br>
> + ExpectedTemplateLoc = DeclStartLoc;<br>
> +<br>
> + Diag(DeclLoc, diag::err_template_spec_needs_header)<br>
> + << Range<br>
> + << FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> ");<br>
> + return false;<br>
> + };<br>
> +<br>
> unsigned ParamIdx = 0;<br>
> for (unsigned TypeIdx = 0, NumTypes = NestedTypes.size(); TypeIdx != NumTypes;<br>
> ++TypeIdx) {<br>
> @@ -1791,13 +1823,8 @@ TemplateParameterList *Sema::MatchTempla<br>
> // are not explicitly specialized as well.<br>
> if (ParamIdx < ParamLists.size()) {<br>
> if (ParamLists[ParamIdx]->size() == 0) {<br>
> - if (SawNonEmptyTemplateParameterList) {<br>
> - Diag(DeclLoc, diag::err_specialize_member_of_template)<br>
> - << ParamLists[ParamIdx]->getSourceRange();<br>
> - Invalid = true;<br>
> - IsExplicitSpecialization = false;<br>
> + if (CheckExplicitSpecialization(ParamLists[ParamIdx]->getSourceRange()))<br>
> return 0;<br>
> - }<br>
> } else<br>
> SawNonEmptyTemplateParameterList = true;<br>
> }<br>
> @@ -1820,29 +1847,20 @@ TemplateParameterList *Sema::MatchTempla<br>
> Invalid = true;<br>
> return 0;<br>
> }<br>
> -<br>
> +<br>
> // Consume this template header.<br>
> ++ParamIdx;<br>
> continue;<br>
> - }<br>
> -<br>
> - if (!IsFriend) {<br>
> - // We don't have a template header, but we should.<br>
> - SourceLocation ExpectedTemplateLoc;<br>
> - if (!ParamLists.empty())<br>
> - ExpectedTemplateLoc = ParamLists[0]->getTemplateLoc();<br>
> - else<br>
> - ExpectedTemplateLoc = DeclStartLoc;<br>
> -<br>
> - // FIXME: Don't recover this way if we SawNonEmptyTemplateParameterList.<br>
> - Diag(DeclLoc, diag::err_template_spec_needs_header)<br>
> - << getRangeOfTypeInNestedNameSpecifier(Context, T, SS)<br>
> - << FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> ");<br>
> }<br>
> -<br>
> +<br>
> + if (!IsFriend)<br>
> + if (DiagnoseMissingExplicitSpecialization(<br>
> + getRangeOfTypeInNestedNameSpecifier(Context, T, SS)))<br>
> + return 0;<br>
> +<br>
> continue;<br>
> }<br>
> -<br>
> +<br>
> if (NeedNonemptyTemplateHeader) {<br>
> // In friend declarations we can have template-ids which don't<br>
> // depend on the corresponding template parameter lists. But<br>
> @@ -1886,18 +1904,11 @@ TemplateParameterList *Sema::MatchTempla<br>
> // the declaration itself.<br>
> if (ParamIdx >= ParamLists.size()) {<br>
> if (TemplateId && !IsFriend) {<br>
> - // FIXME: Don't recover this way if we SawNonEmptyTemplateParameterList.<br>
> // We don't have a template header for the declaration itself, but we<br>
> // should.<br>
> - SourceLocation ExpectedTemplateLoc;<br>
> - if (!ParamLists.empty())<br>
> - ExpectedTemplateLoc = ParamLists[0]->getTemplateLoc();<br>
> - else<br>
> - ExpectedTemplateLoc = DeclStartLoc;<br>
> - Diag(DeclLoc, diag::err_template_spec_needs_header)<br>
> - << SourceRange(TemplateId->LAngleLoc, TemplateId->RAngleLoc)<br>
> - << FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> ");<br>
> IsExplicitSpecialization = true;<br>
> + DiagnoseMissingExplicitSpecialization(SourceRange(TemplateId->LAngleLoc,<br>
> + TemplateId->RAngleLoc));<br>
><br>
> // Fabricate an empty template parameter list for the invented header.<br>
> return TemplateParameterList::Create(Context, SourceLocation(),<br>
> @@ -1947,14 +1958,10 @@ TemplateParameterList *Sema::MatchTempla<br>
> // unspecialized, except that the declaration shall not explicitly<br>
> // specialize a class member template if its en- closing class templates<br>
> // are not explicitly specialized as well.<br>
> - if (ParamLists.back()->size() == 0 && SawNonEmptyTemplateParameterList) {<br>
> - Diag(DeclLoc, diag::err_specialize_member_of_template)<br>
> - << ParamLists[ParamIdx]->getSourceRange();<br>
> - Invalid = true;<br>
> - IsExplicitSpecialization = false;<br>
> + if (ParamLists.back()->size() == 0 &&<br>
> + CheckExplicitSpecialization(ParamLists[ParamIdx]->getSourceRange()))<br>
> return 0;<br>
> - }<br>
> -<br>
> +<br>
> // Return the last template parameter list, which corresponds to the<br>
> // entity being declared.<br>
> return ParamLists.back();<br>
><br>
> Modified: cfe/trunk/test/SemaTemplate/explicit-specialization-member.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/explicit-specialization-member.cpp?rev=206444&r1=206443&r2=206444&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/explicit-specialization-member.cpp?rev=206444&r1=206443&r2=206444&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/SemaTemplate/explicit-specialization-member.cpp (original)<br>
> +++ cfe/trunk/test/SemaTemplate/explicit-specialization-member.cpp Wed Apr 16 22:52:20 2014<br>
> @@ -38,12 +38,22 @@ namespace PR18246 {<br>
><br>
> template<typename T><br>
> template<int N><br>
> - void Baz<T>::bar() {<br>
> + void Baz<T>::bar() { // expected-note {{couldn't infer template argument 'N'}}<br>
> }<br>
><br>
> - // FIXME: Don't suggest the 'template<>' correction here, because this cannot<br>
> - // be an explicit specialization.<br>
> + // FIXME: We shouldn't try to match this against a prior declaration if<br>
> + // template parameter matching failed.<br>
> template<typename T><br>
> - void Baz<T>::bar<0>() { // expected-error {{requires 'template<>'}}<br>
> + void Baz<T>::bar<0>() { // expected-error {{cannot specialize a member of an unspecialized template}} \<br>
> + // expected-error {{no function template matches}}<br>
> }<br>
> }<br>
> +<br>
> +namespace PR19340 {<br>
> +template<typename T> struct Helper {<br>
> + template<int N> static void func(const T *m) {} // expected-note {{failed template argument deduction}}<br>
> +};<br>
> +<br>
> +template<typename T> void Helper<T>::func<2>() {} // expected-error {{cannot specialize a member}} \<br>
> + // expected-error {{no function template matches}}<br>
> +}<br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div>