OK.
On Wed, Feb 15, 2017 at 12:30 PM, Jakub Jelinek <ja...@redhat.com> wrote: > On Wed, Feb 15, 2017 at 11:56:30AM -0500, Jason Merrill wrote: >> On Tue, Feb 14, 2017 at 3:13 PM, Jakub Jelinek <ja...@redhat.com> wrote: >> > The following testcase fails, because while we have the nodiscard >> > attribute on the template, we actually never propagate it to the >> > instantiation, which is where it is checked (I'm really surprised about >> > this). >> >> Normally we propagate attributes when instantiating the class; see the >> call to apply_late_template_attributes in >> instantiate_class_template_1. I'm not sure why that wouldn't be > > Yes, instantiate_class_template_1 calls apply_late_template_attributes, > but that actually does nothing if there are no dependent attributes. > If there are any, it sets TYPE_ATTRIBUTES (or DECL_ATTRIBUTES) to > a copy of the attributes list, removes all the dependent attributes > from there and calls cplus_decl_attributes on the late attrs (after > tsubst_attribute them). So setting {TYPE,DECL}_ATTRIBUTES to the > attributes list unmodified if there are no dependent ones matches > the behavior for non-dependent ones if there is at least one dependent. > > So, does the following patch look better? > > 2017-02-15 Jakub Jelinek <ja...@redhat.com> > > PR c++/79502 > * pt.c (apply_late_template_attributes): If there are > no dependent attributes, set *p to attributes. > > * g++.dg/cpp1z/nodiscard4.C: New test. > > --- gcc/cp/pt.c.jj 2017-02-14 09:23:49.000000000 +0100 > +++ gcc/cp/pt.c 2017-02-15 18:21:45.581055915 +0100 > @@ -10113,6 +10113,8 @@ apply_late_template_attributes (tree *de > > cplus_decl_attributes (decl_p, late_attrs, attr_flags); > } > + else > + *p = attributes; > } > > /* Perform (or defer) access check for typedefs that were referenced > --- gcc/testsuite/g++.dg/cpp1z/nodiscard4.C.jj 2017-02-15 18:11:33.281135469 > +0100 > +++ gcc/testsuite/g++.dg/cpp1z/nodiscard4.C 2017-02-15 18:11:33.281135469 > +0100 > @@ -0,0 +1,14 @@ > +// PR c++/79502 > +// { dg-do compile { target c++11 } } > + > +template<typename> > +struct [[nodiscard]] missiles {}; > + > +missiles<void> make() { return {}; } > +missiles<void> (*fnptr)() = make; > + > +int main() > +{ > + make(); // { dg-warning "ignoring returned value of type" } > + fnptr(); // { dg-warning "ignoring returned value of type" } > +} > > > Jakub