r206444 - PR19340: If we see a declaration of a member of an unspecialized class template

Richard Smith richard at metafoo.co.uk
Thu Apr 17 01:33:45 PDT 2014


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.
On 17 Apr 2014 01:13, "Timur Iskhodzhanov" <timurrrr at google.com> wrote:

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


More information about the cfe-commits mailing list