diff options
author | Marek Polacek <polacek@redhat.com> | 2017-03-09 08:35:37 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2017-03-09 08:35:37 +0000 |
commit | 423aec8b5756c73681dadd10aec25e28dc18eb99 (patch) | |
tree | 6f5ceb49588acca1f4f4d463e536488ff47b8073 | |
parent | dd01cd0ca29b687337661abd9870c32a287de94b (diff) | |
download | gcc-423aec8b5756c73681dadd10aec25e28dc18eb99.zip gcc-423aec8b5756c73681dadd10aec25e28dc18eb99.tar.gz gcc-423aec8b5756c73681dadd10aec25e28dc18eb99.tar.bz2 |
PR c++/79900 - ICE in strip_typedefs
PR c++/79900 - ICE in strip_typedefs
* tree.c (strip_typedefs): Skip the attribute handling if T is
a variant type which hasn't been updated yet.
* g++.dg/warn/Wpadded-1.C: New test.
From-SVN: r245988
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/tree.c | 47 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/warn/Wpadded-1.C | 22 |
4 files changed, 62 insertions, 18 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5bd8322..caf0322 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2017-03-09 Marek Polacek <polacek@redhat.com> + + PR c++/79900 - ICE in strip_typedefs + * tree.c (strip_typedefs): Skip the attribute handling if T is + a variant type which hasn't been updated yet. + 2017-03-08 Jason Merrill <jason@redhat.com> PR c++/79797 - ICE with self-reference in array DMI. diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index d3c63b8..2757af6 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1548,29 +1548,40 @@ strip_typedefs (tree t, bool *remove_attributes) result = TYPE_MAIN_VARIANT (t); } gcc_assert (!typedef_variant_p (result)); - if (TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (result) - || TYPE_ALIGN (t) != TYPE_ALIGN (result)) + + if (COMPLETE_TYPE_P (result) && !COMPLETE_TYPE_P (t)) + /* If RESULT is complete and T isn't, it's likely the case that T + is a variant of RESULT which hasn't been updated yet. Skip the + attribute handling. */; + else { - gcc_assert (TYPE_USER_ALIGN (t)); - if (remove_attributes) - *remove_attributes = true; - else + if (TYPE_USER_ALIGN (t) != TYPE_USER_ALIGN (result) + || TYPE_ALIGN (t) != TYPE_ALIGN (result)) { - if (TYPE_ALIGN (t) == TYPE_ALIGN (result)) - result = build_variant_type_copy (result); + gcc_assert (TYPE_USER_ALIGN (t)); + if (remove_attributes) + *remove_attributes = true; else - result = build_aligned_type (result, TYPE_ALIGN (t)); - TYPE_USER_ALIGN (result) = true; + { + if (TYPE_ALIGN (t) == TYPE_ALIGN (result)) + result = build_variant_type_copy (result); + else + result = build_aligned_type (result, TYPE_ALIGN (t)); + TYPE_USER_ALIGN (result) = true; + } + } + + if (TYPE_ATTRIBUTES (t)) + { + if (remove_attributes) + result = apply_identity_attributes (result, TYPE_ATTRIBUTES (t), + remove_attributes); + else + result = cp_build_type_attribute_variant (result, + TYPE_ATTRIBUTES (t)); } } - if (TYPE_ATTRIBUTES (t)) - { - if (remove_attributes) - result = apply_identity_attributes (result, TYPE_ATTRIBUTES (t), - remove_attributes); - else - result = cp_build_type_attribute_variant (result, TYPE_ATTRIBUTES (t)); - } + return cp_build_qualified_type (result, cp_type_quals (t)); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 396ab3a..6c8ab1d 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2017-03-09 Marek Polacek <polacek@redhat.com> + + PR c++/79900 - ICE in strip_typedefs + * g++.dg/warn/Wpadded-1.C: New test. + 2017-03-08 Marek Polacek <polacek@redhat.com> * g++.dg/Walloca1.C: Adjust dg-warning. diff --git a/gcc/testsuite/g++.dg/warn/Wpadded-1.C b/gcc/testsuite/g++.dg/warn/Wpadded-1.C new file mode 100644 index 0000000..b3f0581 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wpadded-1.C @@ -0,0 +1,22 @@ +// PR c++/79900 - ICE in strip_typedefs +// { dg-do compile } +// { dg-options "-Wpadded" } + +template <class> struct A; +template <typename> struct B { // { dg-warning "padding struct size to alignment boundary" } + long _M_off; + int _M_state; +}; +template <> struct A<char> { typedef B<int> pos_type; }; +enum _Ios_Openmode {}; +struct C { + typedef _Ios_Openmode openmode; +}; +template <typename, typename _Traits> struct D { + typedef typename _Traits::pos_type pos_type; + pos_type m_fn1(pos_type, C::openmode); +}; +template class D<char, A<char> >; +template <typename _CharT, typename _Traits> +typename D<_CharT, _Traits>::pos_type D<_CharT, _Traits>::m_fn1(pos_type x, + C::openmode) { return x; } |