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