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
This commit is contained in:
Jason Merrill 2010-10-13 20:50:26 -04:00 committed by Jason Merrill
parent b477c9658b
commit 8943989dda
7 changed files with 75 additions and 3 deletions

View File

@ -1,3 +1,11 @@
2010-10-13 Jason Merrill <jason@redhat.com>
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 <rth@redhat.com> 2010-10-13 Richard Henderson <rth@redhat.com>
* cp-lang.c (cp_eh_personality): Update call to * cp-lang.c (cp_eh_personality): Update call to

View File

@ -1515,12 +1515,31 @@ fixup_type_variants (tree t)
TYPE_VFIELD (variants) = TYPE_VFIELD (t); TYPE_VFIELD (variants) = TYPE_VFIELD (t);
TYPE_METHODS (variants) = TYPE_METHODS (t); TYPE_METHODS (variants) = TYPE_METHODS (t);
TYPE_FIELDS (variants) = TYPE_FIELDS (t); TYPE_FIELDS (variants) = TYPE_FIELDS (t);
/* All variants of a class have the same attributes. */
TYPE_ATTRIBUTES (variants) = TYPE_ATTRIBUTES (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;
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 /* Set memoizing fields and bits of T (and its variants) for later
use. */ use. */

View File

@ -4711,6 +4711,7 @@ extern bool type_has_move_assign (tree);
extern void defaulted_late_check (tree); extern void defaulted_late_check (tree);
extern bool defaultable_fn_check (tree); extern bool defaultable_fn_check (tree);
extern void fixup_type_variants (tree); extern void fixup_type_variants (tree);
extern void fixup_attribute_variants (tree);
extern tree* decl_cloned_function_p (const_tree, bool); extern tree* decl_cloned_function_p (const_tree, bool);
extern void clone_function_decl (tree, int); extern void clone_function_decl (tree, int);
extern void adjust_clone_args (tree); extern void adjust_clone_args (tree);

View File

@ -7943,6 +7943,7 @@ instantiate_class_template (tree type)
apply_late_template_attributes (&type, TYPE_ATTRIBUTES (pattern), apply_late_template_attributes (&type, TYPE_ATTRIBUTES (pattern),
(int) ATTR_FLAG_TYPE_IN_PLACE, (int) ATTR_FLAG_TYPE_IN_PLACE,
args, tf_error, NULL_TREE); args, tf_error, NULL_TREE);
fixup_attribute_variants (type);
/* Now that our base classes are set up, enter the scope of the /* Now that our base classes are set up, enter the scope of the
class, so that name lookups into base classes, etc. will work class, so that name lookups into base classes, etc. will work

View File

@ -2391,6 +2391,7 @@ begin_class_definition (tree t, tree attributes)
TYPE_BEING_DEFINED (t) = 1; TYPE_BEING_DEFINED (t) = 1;
cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE); cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE);
fixup_attribute_variants (t);
if (flag_pack_struct) if (flag_pack_struct)
{ {

View File

@ -1,3 +1,7 @@
2010-10-13 Jason Merrill <jason@redhat.com>
* g++.dg/template/canon-type-8.C: New.
2010-10-13 Eric Botcazou <ebotcazou@adacore.com> 2010-10-13 Eric Botcazou <ebotcazou@adacore.com>
* gcc.c-torture/execute/20101013-1.c: New test. * gcc.c-torture/execute/20101013-1.c: New test.

View File

@ -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<size_t NumChans> 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<chunk_size; ++i)
mix[i] = src.chan(0)[i] + src.chan(1)[i];
}
};