diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fa7d6bc0e65..22dbdba6936 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2006-08-22 Jason Merrill + + 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 PR c++/27115 diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index bb579a6f739..1cedec55f8d 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1936,6 +1936,10 @@ cp_build_type_attribute_variant (tree type, tree attributes) != 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; } diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index f337328cfcd..c07a78d1ef4 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -228,6 +228,7 @@ commonparms (tree p1, tree p2) static tree original_type (tree t) { + int quals = cp_type_quals (t); while (t != error_mark_node && TYPE_NAME (t) != NULL_TREE) { @@ -239,7 +240,7 @@ original_type (tree t) break; t = x; } - return t; + return cp_build_qualified_type (t, quals); } /* T1 and T2 are arithmetic or enumeration types. Return the type @@ -730,7 +731,13 @@ merge_types (tree t1, tree t2) default:; } - return cp_build_type_attribute_variant (t1, attributes); + + 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. diff --git a/gcc/testsuite/g++.dg/ext/attrib26.C b/gcc/testsuite/g++.dg/ext/attrib26.C new file mode 100644 index 00000000000..dedf43a0246 --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/attrib26.C @@ -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 +struct __attribute__((aligned(1))) A +{ + A& operator=(const A &t); +}; + +template +A& A::operator=(const A &t) +{ +}