This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH to merge_types for c++/28659
- From: Jason Merrill <jason at redhat dot com>
- To: "gcc-patches >> GCC Patches" <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 22 Aug 2006 14:26:19 -0400
- Subject: C++ PATCH to merge_types for c++/28659
The problem in this bug was that when comparing the definition of op= to
the declaration in the class, we try to merge the class template itself
with an uninstantiated version of itself. The template has an
attribute, while the uninstantiated version doesn't have the attribute
yet because it hasn't been instantiated. So merge_types ends up calling
cp_build_type_attribute_variant to make a variant of the uninstantiated
type with the attribute added.
Making attribute variants of class types seems like a very bad idea
because it creates a new TYPE_MAIN_VARIANT, and I think it's reasonable
to expect that all versions of a particular class have the same
TYPE_MAIN_VARIANT. And the testcase breaks in this case because
build_type_variant doesn't set TYPE_STUB_DECL.
Fixed by checking in merge_types whether either of the input types have
the desired attributes, and if so returning that one. While I was at it
I also fixed a problem whereby original_type would change the
cv-qualification of a type, and added an assert to
cp_build_type_attribute_variant to catch any future attempts to create
an attribute variant of the class.
Tested x86_64-pc-linux-gnu, applied to trunk.
2006-08-22 Jason Merrill <jason@redhat.com>
PR c++/28659
* typeck.c (merge_types): If either of the types have the right
attributes, return that one.
* tree.c (cp_build_type_attribute_variant): Make sure we aren't
doing this to class types.
* typeck.c (original_type): Deal with type quals properly.
Index: typeck.c
===================================================================
*** typeck.c (revision 116310)
--- typeck.c (working copy)
*************** commonparms (tree p1, tree p2)
*** 228,233 ****
--- 228,234 ----
static tree
original_type (tree t)
{
+ int quals = cp_type_quals (t);
while (t != error_mark_node
&& TYPE_NAME (t) != NULL_TREE)
{
*************** original_type (tree t)
*** 239,245 ****
break;
t = x;
}
! return t;
}
/* T1 and T2 are arithmetic or enumeration types. Return the type
--- 240,246 ----
break;
t = x;
}
! return cp_build_qualified_type (t, quals);
}
/* T1 and T2 are arithmetic or enumeration types. Return the type
*************** merge_types (tree t1, tree t2)
*** 730,736 ****
default:;
}
! return cp_build_type_attribute_variant (t1, attributes);
}
/* Return the common type of two types.
--- 731,743 ----
default:;
}
!
! if (attribute_list_equal (TYPE_ATTRIBUTES (t1), attributes))
! return t1;
! else if (attribute_list_equal (TYPE_ATTRIBUTES (t2), attributes))
! return t2;
! else
! return cp_build_type_attribute_variant (t1, attributes);
}
/* Return the common type of two types.
Index: tree.c
===================================================================
*** tree.c (revision 116310)
--- tree.c (working copy)
*************** cp_build_type_attribute_variant (tree ty
*** 1936,1941 ****
--- 1936,1945 ----
!= TYPE_RAISES_EXCEPTIONS (type)))
new_type = build_exception_variant (new_type,
TYPE_RAISES_EXCEPTIONS (type));
+
+ /* Making a new main variant of a class type is broken. */
+ gcc_assert (!CLASS_TYPE_P (type) || new_type == type);
+
return new_type;
}
Index: ChangeLog
===================================================================
*** ChangeLog (revision 116311)
--- ChangeLog (working copy)
***************
*** 1,3 ****
--- 1,13 ----
+ 2006-08-22 Jason Merrill <jason@redhat.com>
+
+ PR c++/28659
+ * typeck.c (merge_types): If either of the types have the right
+ attributes, return that one.
+
+ * tree.c (cp_build_type_attribute_variant): Make sure we aren't
+ doing this to class types.
+ * typeck.c (original_type): Deal with type quals properly.
+
2006-08-21 Jason Merrill <jason@redhat.com>
PR c++/27115
Index: /home/jason/ged/ext/attrib26.C
===================================================================
*** /home/jason/ged/ext/attrib26.C (revision 0)
--- /home/jason/ged/ext/attrib26.C (revision 0)
***************
*** 0 ****
--- 1,14 ----
+ // PR c++/28659
+ // The attribute was causing us to get confused in merge_types when
+ // combining the template type with an uninstantiated version.
+
+ template<class T>
+ struct __attribute__((aligned(1))) A
+ {
+ A& operator=(const A &t);
+ };
+
+ template<class T>
+ A<T>& A<T>::operator=(const A<T> &t)
+ {
+ }