On 02/16/2017 12:49 PM, Jason Merrill wrote:
On Thu, Feb 16, 2017 at 11:33 AM, Jakub Jelinek <ja...@redhat.com> wrote:
        PR c++/79502
        * pt.c (apply_late_template_attributes): If there are
        no dependent attributes, set *p to attributes.  If there were
        some attributes in *p previously with or without dependent
        attributes, chain them after the new attributes.

Here's the variant of your patch that I'm applying.

Sorry to butt in but I feel like I'm missing something basic.  Are
these attributes (nodiscard, noreturn, maybe_unused, and deprecated)
meant to apply to templates?  The text in for nodiscard suggests
they're not:

  The attribute-token nodiscard may be applied to the declarator-id
  in a function declaration or to the declaration of a class or
  enumeration.

Noreturn also doesn't mention templates:

  The attribute may be applied to the declarator-id in a function
  declaration.

Deprecated explicitly mentions template specializations but not
primary templates:

  The attribute may be applied to the declaration of a class,
   a typedef-name, a variable, a non-static data member, a function,
   a namespace, an enumeration, an enumerator, or a template
   specialization.

I can certainly see how applying attributes to the primary template
would be useful so it's puzzling to me that the standard seems to
preclude it.

I ask also because I was just looking at bug 79021 and scratching
my head about what to thing about it.   While trying to understand
how GCC handles attributes for the primary template I came across
what doesn't make sense to me.   Why would it apply the attribute
from the primary to the explicit specialization when the two are
distinct entities?  Is that a bug?

template <class T>
[[noreturn]] int f () { throw ""; }

template <> int f<void> () { return 0; }
t.C: In function ‘int f() [with T = void]’:
t.C:4:37: warning: function declared ‘noreturn’ has a ‘return’ statement
 template <> int f<void> () { return 0; }
                                     ^
t.C:4:37: warning: ‘noreturn’ function does return
 template <> int f<void> () { return 0; }
                                     ^

Clang complains on this too with similar errors, but then GCC
silently accepts this code (which makes sense to me) which Clang
5 rejects with what looks like a bug:

template <class T>
int g () { return 0; }

template <> [[noreturn]] int g<void> () { throw ""; }
template <> [[noreturn]] int g<int> () { throw ""; }

Thanks
Martin

Reply via email to