On Thu, Feb 16, 2017 at 04:57:54PM +0100, Jakub Jelinek wrote: > Unfortunately it broke bootstrap, *p can already contain some > other attributes (like abi_tag) and then we ICE in > apply_identity_attributes. Note the attrib54.C testcase ICEs even > on vanilla trunk, so if there are any dependent attribute, it is preexisting > issue. > > The following patch bootstrapped successfully, but I see > +FAIL: g++.dg/ext/vector32.C -std=c++* (internal compiler error) > +FAIL: g++.dg/ext/vector32a.C -std=c++* (internal compiler error) > +FAIL: g++.dg/gomp/declare-simd-1.C -std=gnu++* (internal compiler error) > +FAIL: g++.dg/gomp/declare-simd-1.C -std=gnu++* (test for excess errors) > +FAIL: g++.dg/lto/20091219 cp_lto_20091219_0.o assemble, -O3 -flto (internal > compiler error) > +FAIL: g++.dg/vect/simd-clone-4.cc -std=c++* (test for excess errors) > +FAIL: g++.dg/vect/simd-clone-5.cc -std=c++* (test for excess errors) > on i686-linux (x86_64-linux regtest still running). So there are further > issues.
The issue with the above is that all those are DECL_ATTRIBUTES which are copied over through copy_node inside of tsubst_decl or so. Preserving the previous attributes in that case is harmful, they can contain dependent attributes etc. That compared to TYPE_ATTRIBUTES which start empty (at least for classes, for enums there is that t = start_enum (TYPE_IDENTIFIER (template_type), NULL_TREE, tsubst (ENUM_UNDERLYING_TYPE (template_type), arglist, complain, in_decl), tsubst_attributes (TYPE_ATTRIBUTES (template_type), arglist, complain, in_decl), SCOPED_ENUM_P (template_type), NULL); ) and then sometimes have something added there (such as the abi_tag attributes) before apply_late_template_attributes is called. With the following patch I have: make check-g++ RUNTESTFLAGS="--target_board=unix\{-m32,-m64\} dg.exp='vector*.C attrib* nodiscard*' gomp.exp=declare-simd* lto.exp=20091219* vect.exp=simd-clone-*.cc" without any FAILs. Not sure about the enums, wonder if the abi_tags attributes couldn't be added even for those. 2017-02-16 Jakub Jelinek <ja...@redhat.com> 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. * g++.dg/cpp1z/nodiscard4.C: New test. * g++.dg/ext/attrib53.C: New test. * g++.dg/ext/attrib54.C: New test. * g++.dg/ext/attrib55.C: New test. --- gcc/cp/pt.c.jj 2017-02-16 12:00:20.044455757 +0100 +++ gcc/cp/pt.c 2017-02-16 15:07:31.678727294 +0100 @@ -10086,6 +10086,7 @@ apply_late_template_attributes (tree *de if (TREE_TYPE (*decl_p) == error_mark_node) return; p = &DECL_ATTRIBUTES (*decl_p); + *p = NULL_TREE; } else p = &TYPE_ATTRIBUTES (*decl_p); @@ -10094,6 +10095,7 @@ apply_late_template_attributes (tree *de { tree late_attrs = NULL_TREE; tree *q = &late_attrs; + tree prev = *p; for (*p = attributes; *p; ) { @@ -10110,9 +10112,14 @@ apply_late_template_attributes (tree *de else p = &TREE_CHAIN (t); } + *p = prev; cplus_decl_attributes (decl_p, late_attrs, attr_flags); } + else if (*p == NULL) + *p = attributes; + else if (attributes) + *p = chainon (copy_list (attributes), *p); } /* Perform (or defer) access check for typedefs that were referenced --- gcc/testsuite/g++.dg/cpp1z/nodiscard4.C.jj 2017-02-16 14:04:22.602748039 +0100 +++ gcc/testsuite/g++.dg/cpp1z/nodiscard4.C 2017-02-16 14:04:22.601748053 +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" } +} --- gcc/testsuite/g++.dg/ext/attrib53.C.jj 2017-02-16 15:08:18.635107840 +0100 +++ gcc/testsuite/g++.dg/ext/attrib53.C 2017-02-16 15:09:50.210899761 +0100 @@ -0,0 +1,21 @@ +// { dg-do compile { target c++11 } } + +inline namespace N __attribute__((__abi_tag__ ("foo"))) {} +template <typename> struct A; +namespace N { +template <typename> class B; +} +template <typename> class C {}; +template <typename> struct D { + template <typename _Up> using G = C<_Up>; +}; +template <typename T> struct F { + template <typename U> struct H { + typedef typename D<T>::template G<U> I; + }; +}; +template <typename T, typename = C<T>> struct J { + C<A<const B<char>>> L; + typedef F<C<int>>::H<A<const B<char>>>::I M; + J<M> *a; +}; --- gcc/testsuite/g++.dg/cpp0x/attrib54.C.jj 2017-02-16 15:08:21.739066892 +0100 +++ gcc/testsuite/g++.dg/cpp0x/attrib54.C 2017-02-16 15:10:02.461738146 +0100 @@ -0,0 +1,21 @@ +// { dg-do compile { target c++11 } } + +inline namespace N __attribute__((__abi_tag__ ("foo"))) {} +template <typename> struct A {}; +namespace N { +template <typename> class B {}; +} +template <typename T> class __attribute__((__aligned__ (sizeof (T)))) C {}; +template <typename> struct D { + template <typename _Up> using G = C<_Up>; +}; +template <typename T> struct F { + template <typename U> struct H { + typedef typename D<T>::template G<U> I; + }; +}; +template <typename T, typename = C<T>> struct J { + C<A<const B<char>>> L; + typedef F<C<int>>::H<A<const B<char>>>::I M; + J<M> *a; +}; --- gcc/testsuite/g++.dg/cpp0x/attrib55.C.jj 2017-02-16 15:08:26.801000114 +0100 +++ gcc/testsuite/g++.dg/cpp0x/attrib55.C 2017-02-16 15:10:11.422619933 +0100 @@ -0,0 +1,21 @@ +// { dg-do compile { target c++11 } } + +inline namespace N __attribute__((__abi_tag__ ("foo"))) {} +template <typename> struct A {}; +namespace N { +template <typename> class B {}; +} +template <typename T> class __attribute__((__unused__)) C {}; +template <typename> struct D { + template <typename _Up> using G = C<_Up>; +}; +template <typename T> struct F { + template <typename U> struct H { + typedef typename D<T>::template G<U> I; + }; +}; +template <typename T, typename = C<T>> struct J { + C<A<const B<char>>> L; + typedef F<C<int>>::H<A<const B<char>>>::I M; + J<M> *a; +}; Jakub