<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>