This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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)
+ {
+ }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]