PR c++/79502 - lost nodiscard attribute
* pt.c (apply_late_template_attributes): Do apply non-dependent attributes to types. Co-Authored-By: Jason Merrill <jason@redhat.com> From-SVN: r245516
This commit is contained in:
parent
dbd0ef6d89
commit
790ecf8532
6 changed files with 108 additions and 10 deletions
|
@ -1,3 +1,10 @@
|
|||
2017-02-16 Jakub Jelinek <jakub@redhat.com>
|
||||
Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/79502 - lost nodiscard attribute
|
||||
* pt.c (apply_late_template_attributes): Do apply non-dependent
|
||||
attributes to types.
|
||||
|
||||
2017-02-16 Jason Merrill <jason@redhat.com>
|
||||
|
||||
PR c++/78572 - ICE with self-modifying array initializer
|
||||
|
|
34
gcc/cp/pt.c
34
gcc/cp/pt.c
|
@ -10073,6 +10073,28 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
|
|||
tree t;
|
||||
tree *p;
|
||||
|
||||
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);
|
||||
/* 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))
|
||||
{
|
||||
|
@ -10081,21 +10103,13 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags,
|
|||
break;
|
||||
}
|
||||
|
||||
if (DECL_P (*decl_p))
|
||||
{
|
||||
if (TREE_TYPE (*decl_p) == error_mark_node)
|
||||
return;
|
||||
p = &DECL_ATTRIBUTES (*decl_p);
|
||||
}
|
||||
else
|
||||
p = &TYPE_ATTRIBUTES (*decl_p);
|
||||
|
||||
*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))
|
||||
|
|
21
gcc/testsuite/g++.dg/cpp0x/attrib54.C
Normal file
21
gcc/testsuite/g++.dg/cpp0x/attrib54.C
Normal file
|
@ -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;
|
||||
};
|
21
gcc/testsuite/g++.dg/cpp0x/attrib55.C
Normal file
21
gcc/testsuite/g++.dg/cpp0x/attrib55.C
Normal file
|
@ -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;
|
||||
};
|
14
gcc/testsuite/g++.dg/cpp1z/nodiscard4.C
Normal file
14
gcc/testsuite/g++.dg/cpp1z/nodiscard4.C
Normal file
|
@ -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" }
|
||||
}
|
21
gcc/testsuite/g++.dg/ext/attrib53.C
Normal file
21
gcc/testsuite/g++.dg/ext/attrib53.C
Normal file
|
@ -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;
|
||||
};
|
Loading…
Add table
Reference in a new issue