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