OSDN Git Service

PR c++/45984
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 14 Oct 2010 00:50:26 +0000 (00:50 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 14 Oct 2010 00:50:26 +0000 (00:50 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165443 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/class.c
gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/cp/semantics.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/canon-type-8.C [new file with mode: 0644]

index 683e439..ec89755 100644 (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>
 
        * cp-lang.c (cp_eh_personality): Update call to
index b093ce0..f76c2be 100644 (file)
@@ -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);
     }
 }
-
 \f
 /* Set memoizing fields and bits of T (and its variants) for later
    use.  */
index bfc6fd3..29a4bdb 100644 (file)
@@ -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);
index 84901d3..9ddb4fd 100644 (file)
@@ -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
index b73dffb..787c72c 100644 (file)
@@ -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)
     {
index 5d99bd6..e7d06f0 100644 (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>
 
        * 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 (file)
index 0000000..fd1fe3c
--- /dev/null
@@ -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];
+    }
+};