From 8943989ddaeb040a72840f92a9654235e77470fd Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 13 Oct 2010 20:50:26 -0400 Subject: [PATCH] re PR c++/45984 (ICE: canonical types differ for identical types) PR c++/45984 * class.c (fixup_attribute_variants): New fn. * cp-tree.h: Declare it. * pt.c (instantiate_class_template): Call it. * semantics.c (begin_class_definition): Call it. From-SVN: r165443 --- gcc/cp/ChangeLog | 8 +++++ gcc/cp/class.c | 23 ++++++++++-- gcc/cp/cp-tree.h | 1 + gcc/cp/pt.c | 1 + gcc/cp/semantics.c | 1 + gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/g++.dg/template/canon-type-8.C | 38 ++++++++++++++++++++ 7 files changed, 74 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/canon-type-8.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 683e439ac476..ec897554a226 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2010-10-13 Jason Merrill + + PR c++/45984 + * class.c (fixup_attribute_variants): New fn. + * cp-tree.h: Declare it. + * pt.c (instantiate_class_template): Call it. + * semantics.c (begin_class_definition): Call it. + 2010-10-13 Richard Henderson * cp-lang.c (cp_eh_personality): Update call to diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b093ce0fcc58..f76c2bed3d85 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -1515,12 +1515,31 @@ fixup_type_variants (tree t) TYPE_VFIELD (variants) = TYPE_VFIELD (t); TYPE_METHODS (variants) = TYPE_METHODS (t); TYPE_FIELDS (variants) = TYPE_FIELDS (t); + } +} + +/* Early variant fixups: we apply attributes at the beginning of the class + definition, and we need to fix up any variants that have already been + made via elaborated-type-specifier so that check_qualified_type works. */ + +void +fixup_attribute_variants (tree t) +{ + tree variants; - /* All variants of a class have the same attributes. */ + if (!t) + return; + + for (variants = TYPE_NEXT_VARIANT (t); + variants; + variants = TYPE_NEXT_VARIANT (variants)) + { + /* These are the two fields that check_qualified_type looks at and + are affected by attributes. */ TYPE_ATTRIBUTES (variants) = TYPE_ATTRIBUTES (t); + TYPE_ALIGN (variants) = TYPE_ALIGN (t); } } - /* Set memoizing fields and bits of T (and its variants) for later use. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index bfc6fd3d27b6..29a4bdb01ca7 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4711,6 +4711,7 @@ extern bool type_has_move_assign (tree); extern void defaulted_late_check (tree); extern bool defaultable_fn_check (tree); extern void fixup_type_variants (tree); +extern void fixup_attribute_variants (tree); extern tree* decl_cloned_function_p (const_tree, bool); extern void clone_function_decl (tree, int); extern void adjust_clone_args (tree); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 84901d30673f..9ddb4fd465c0 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -7943,6 +7943,7 @@ instantiate_class_template (tree type) apply_late_template_attributes (&type, TYPE_ATTRIBUTES (pattern), (int) ATTR_FLAG_TYPE_IN_PLACE, args, tf_error, NULL_TREE); + fixup_attribute_variants (type); /* Now that our base classes are set up, enter the scope of the class, so that name lookups into base classes, etc. will work diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index b73dffb0560e..787c72c17fc3 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -2391,6 +2391,7 @@ begin_class_definition (tree t, tree attributes) TYPE_BEING_DEFINED (t) = 1; cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE); + fixup_attribute_variants (t); if (flag_pack_struct) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5d99bd69befc..e7d06f0be0b5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-10-13 Jason Merrill + + * g++.dg/template/canon-type-8.C: New. + 2010-10-13 Eric Botcazou * gcc.c-torture/execute/20101013-1.c: New test. diff --git a/gcc/testsuite/g++.dg/template/canon-type-8.C b/gcc/testsuite/g++.dg/template/canon-type-8.C new file mode 100644 index 000000000000..fd1fe3ce3629 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/canon-type-8.C @@ -0,0 +1,38 @@ +// PR c++/45984 +// We were getting different canonical types for matching types because +// TYPE_ALIGN wasn't propagated to all the variants fast enough. +// { dg-options "" } + +typedef __SIZE_TYPE__ size_t; +enum { chunk_size = 16 }; +typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__)); +typedef float __v4sf __attribute__ ((__vector_size__ (16))); +struct __attribute__((aligned((16)))) float4_t { + typedef float scalar_t; + typedef __m128 type_t; + typedef float4_t return_type_t; + type_t m; + inline __attribute__((artificial, gnu_inline, always_inline)) explicit + float4_t(scalar_t a) : m(((__m128) (__v4sf) { (a), (a), (a), (a) })) { } + inline __attribute__((artificial, gnu_inline, always_inline, pure)) friend + return_type_t operator+(float4_t lhs, float4_t rhs) { } +}; +template class __attribute__((aligned((16)))) chunk_array_t { +public: + typedef float4_t value_type_t; + typedef value_type_t value_array_t[chunk_size/4]; + enum { num_scalars = chunk_size, num_values = num_scalars/4 }; + const value_array_t &chan(size_t c) const { } + value_type_t operator[](size_t i) const { } +}; +typedef chunk_array_t<1> chunk_array_mono_t; +typedef chunk_array_t<2> chunk_array_stereo_t; +class freeverb_stereo_t { + void process(const chunk_array_stereo_t & __restrict__ src, + chunk_array_stereo_t & __restrict__ dst) { + enum { chunk_size = chunk_array_t<1>::num_values }; + chunk_array_mono_t mix; + for (size_t i=0; i