Hi! 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).
Unfortunately, this patch regresses FAIL: g++.dg/ext/visibility/template8.C -std=gnu++{11,14,98} scan-hidden hidden[ \\t_]*_Z1gI1AI1BEEvT_ It expects that the visibility attribute from the template never makes it to the implementation or something, is that correct? Or do we need to handle visibility in some special way? Regarding the first hunk, it is just a wild guess, I couldn't trigger that code by make check-c++-all. Is there a way to get it through some partial instantiation of scoped enum with/without attributes or something similar? Anyway, except for that template8.C the patch passed bootstrap/regtest on x86_64-linux and i686-linux. But it really puzzles me that the attributes aren't instantiated, what happens e.g. with abi_tag attribute? 2017-02-14 Jakub Jelinek <ja...@redhat.com> PR c++/79502 * pt.c (lookup_template_class_1): Set TYPE_ATTRIBUTES on class instantiations as well as dependent enumeral instantiations. Set ENUM_UNDERLYING_TYPE on the latter too. * g++.dg/cpp1z/nodiscard4.C: New test. --- gcc/cp/pt.c.jj 2017-02-10 21:35:30.000000000 +0100 +++ gcc/cp/pt.c 2017-02-14 08:36:35.459265103 +0100 @@ -8759,7 +8759,13 @@ lookup_template_class_1 (tree d1, tree a template parameters. And, no one should be interested in the enumeration constants for such a type. */ t = cxx_make_type (ENUMERAL_TYPE); + ENUM_UNDERLYING_TYPE (t) + = tsubst (ENUM_UNDERLYING_TYPE (template_type), + arglist, complain, in_decl); SET_SCOPED_ENUM_P (t, SCOPED_ENUM_P (template_type)); + TYPE_ATTRIBUTES (t) + = tsubst_attributes (TYPE_ATTRIBUTES (template_type), + arglist, complain, in_decl); } SET_OPAQUE_ENUM_P (t, OPAQUE_ENUM_P (template_type)); ENUM_FIXED_UNDERLYING_TYPE_P (t) @@ -8786,6 +8792,10 @@ lookup_template_class_1 (tree d1, tree a equality testing, so this template class requires structural equality testing. */ SET_TYPE_STRUCTURAL_EQUALITY (t); + + TYPE_ATTRIBUTES (t) + = tsubst_attributes (TYPE_ATTRIBUTES (template_type), + arglist, complain, in_decl); } else gcc_unreachable (); --- gcc/testsuite/g++.dg/cpp1z/nodiscard4.C.jj 2017-02-14 08:42:12.275765748 +0100 +++ gcc/testsuite/g++.dg/cpp1z/nodiscard4.C 2017-02-14 08:40:00.000000000 +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