From 790ecf853295e25cdd3f92113bc9dca1cf143040 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 16 Feb 2017 20:49:19 +0100 Subject: [PATCH] PR c++/79502 - lost nodiscard attribute * pt.c (apply_late_template_attributes): Do apply non-dependent attributes to types. Co-Authored-By: Jason Merrill From-SVN: r245516 --- gcc/cp/ChangeLog | 7 ++++++ gcc/cp/pt.c | 32 ++++++++++++++++++------- gcc/testsuite/g++.dg/cpp0x/attrib54.C | 21 ++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/attrib55.C | 21 ++++++++++++++++ gcc/testsuite/g++.dg/cpp1z/nodiscard4.C | 14 +++++++++++ gcc/testsuite/g++.dg/ext/attrib53.C | 21 ++++++++++++++++ 6 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/attrib54.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/attrib55.C create mode 100644 gcc/testsuite/g++.dg/cpp1z/nodiscard4.C create mode 100644 gcc/testsuite/g++.dg/ext/attrib53.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 66c491e1bf8..11ef3209519 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2017-02-16 Jakub Jelinek + Jason Merrill + + PR c++/79502 - lost nodiscard attribute + * pt.c (apply_late_template_attributes): Do apply non-dependent + attributes to types. + 2017-02-16 Jason Merrill PR c++/78572 - ICE with self-modifying array initializer diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 712fb691903..73d6be3598f 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10073,29 +10073,43 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags, tree t; tree *p; - for (t = attributes; t; t = TREE_CHAIN (t)) - if (ATTR_IS_DEPENDENT (t)) - { - last_dep = t; - attributes = copy_list (attributes); - break; - } + if (attributes == NULL_TREE) + return; if (DECL_P (*decl_p)) { if (TREE_TYPE (*decl_p) == error_mark_node) return; p = &DECL_ATTRIBUTES (*decl_p); + /* DECL_ATTRIBUTES comes from copy_node in tsubst_decl, and is identical + to our attributes parameter. */ + gcc_assert (*p == attributes); } else - p = &TYPE_ATTRIBUTES (*decl_p); + { + p = &TYPE_ATTRIBUTES (*decl_p); + /* TYPE_ATTRIBUTES was set up (with abi_tag and may_alias) in + lookup_template_class_1, and should be preserved. */ + gcc_assert (*p != attributes); + while (*p) + p = &TREE_CHAIN (*p); + } + + for (t = attributes; t; t = TREE_CHAIN (t)) + if (ATTR_IS_DEPENDENT (t)) + { + last_dep = t; + attributes = copy_list (attributes); + break; + } + *p = attributes; if (last_dep) { tree late_attrs = NULL_TREE; tree *q = &late_attrs; - for (*p = attributes; *p; ) + for (; *p; ) { t = *p; if (ATTR_IS_DEPENDENT (t)) diff --git a/gcc/testsuite/g++.dg/cpp0x/attrib54.C b/gcc/testsuite/g++.dg/cpp0x/attrib54.C new file mode 100644 index 00000000000..e5817c3d9fa --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/attrib54.C @@ -0,0 +1,21 @@ +// { dg-do compile { target c++11 } } + +inline namespace N __attribute__((__abi_tag__ ("foo"))) {} +template struct A {}; +namespace N { +template class B {}; +} +template class __attribute__((__aligned__ (sizeof (T)))) C {}; +template struct D { + template using G = C<_Up>; +}; +template struct F { + template struct H { + typedef typename D::template G I; + }; +}; +template > struct J { + C>> L; + typedef F>::H>>::I M; + J *a; +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/attrib55.C b/gcc/testsuite/g++.dg/cpp0x/attrib55.C new file mode 100644 index 00000000000..79d0c8ccc46 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/attrib55.C @@ -0,0 +1,21 @@ +// { dg-do compile { target c++11 } } + +inline namespace N __attribute__((__abi_tag__ ("foo"))) {} +template struct A {}; +namespace N { +template class B {}; +} +template class __attribute__((__unused__)) C {}; +template struct D { + template using G = C<_Up>; +}; +template struct F { + template struct H { + typedef typename D::template G I; + }; +}; +template > struct J { + C>> L; + typedef F>::H>>::I M; + J *a; +}; diff --git a/gcc/testsuite/g++.dg/cpp1z/nodiscard4.C b/gcc/testsuite/g++.dg/cpp1z/nodiscard4.C new file mode 100644 index 00000000000..8a95c947798 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/nodiscard4.C @@ -0,0 +1,14 @@ +// PR c++/79502 +// { dg-do compile { target c++11 } } + +template +struct [[nodiscard]] missiles {}; + +missiles make() { return {}; } +missiles (*fnptr)() = make; + +int main() +{ + make(); // { dg-warning "ignoring returned value of type" } + fnptr(); // { dg-warning "ignoring returned value of type" } +} diff --git a/gcc/testsuite/g++.dg/ext/attrib53.C b/gcc/testsuite/g++.dg/ext/attrib53.C new file mode 100644 index 00000000000..408433dd2f2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib53.C @@ -0,0 +1,21 @@ +// { dg-do compile { target c++11 } } + +inline namespace N __attribute__((__abi_tag__ ("foo"))) {} +template struct A; +namespace N { +template class B; +} +template class C {}; +template struct D { + template using G = C<_Up>; +}; +template struct F { + template struct H { + typedef typename D::template G I; + }; +}; +template > struct J { + C>> L; + typedef F>::H>>::I M; + J *a; +}; -- 2.30.2