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] Canonical type fixes for arrays of cv-qualified vectors (PR c++/35113)


The new test g++.dg/ext/vector13.C, which came in through PR
c++/35096, is currently failing on mainline. This is a 4.3 regression
due to the canonical types system, where we are failing to properly
deal with certain cv-qualified array types, in particular, those that
are arrays of vectors. This patch fixes the problem by simplifying the
C++ code that builds qualified array types: instead of duplicating the
logic of build_cplus_array_type_1, we reuse build_cplus_array_type_1
to build the new array type, then link up the main variants of the
newly-built cv-qualified type and the original (unqualified) array
type. Without this fix, we could end up building two cv-qualified
array nodes from different hash tables: one stored in the C/C++ common
hash table (via type_hash_canon) and one maintained by
build_cplus_array_type (that was intended deal only with dependent
types). In retrospect, this is the obvious implementation.

Tested i686-pc-linux-gnu and i386-apple-darwin9.1.0. Okay for mainline?

  - Doug

2008-02-07  Douglas Gregor  <doug.gregor@gmail.com>

	PR c++/35113
	* tree.c (cp_build_qualified_type_real): When building a
	cv-qualified array type, build it as a unique type with
	build_cplus_array_type_1 and then adopt the unqualified type's
	main variant.
Index: tree.c
===================================================================
--- tree.c	(revision 132168)
+++ tree.c	(working copy)
@@ -724,47 +724,33 @@ cp_build_qualified_type_real (tree type,
 	  break;
 
       if (!t)
-	{
-	  tree index_type = TYPE_DOMAIN (type);
-	  void **e;
-	  cplus_array_info cai;
-	  hashval_t hash;
-
-	  if (cplus_array_htab == NULL)
-	    cplus_array_htab = htab_create_ggc (61, &cplus_array_hash,
-						&cplus_array_compare, 
-						NULL);
-
-	  hash = (htab_hash_pointer (element_type)
-		  ^ htab_hash_pointer (index_type));
-	  cai.type = element_type;
-	  cai.domain = index_type;
-	  
-	  e = htab_find_slot_with_hash (cplus_array_htab, &cai, hash, INSERT);
-	  if (*e)
-	    /* We have found the type: we're done. */
-	    return (tree) *e;
-
-	  /* Build a new array type and add it into the table.  */
-	  t = build_variant_type_copy (type);
-	  TREE_TYPE (t) = element_type;
-	  *e = t;
-
-	  /* Set the canonical type for this new node.  */
-	  if (TYPE_STRUCTURAL_EQUALITY_P (element_type)
-	      || (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type)))
-	    SET_TYPE_STRUCTURAL_EQUALITY (t);
-	  else if (TYPE_CANONICAL (element_type) != element_type
-		   || (index_type 
-		       && TYPE_CANONICAL (index_type) != index_type)
-		   || TYPE_CANONICAL (type) != type)
-	    TYPE_CANONICAL (t)
-	      = build_cplus_array_type
-	         (TYPE_CANONICAL (element_type),
-		  index_type? TYPE_CANONICAL (index_type) : index_type);
-	  else
-	    TYPE_CANONICAL (t) = t;
-	}
+      {
+	t = build_cplus_array_type_1 (element_type, TYPE_DOMAIN (type));
+
+	if (TYPE_MAIN_VARIANT (t) != TYPE_MAIN_VARIANT (type))
+	  {
+	    /* Set the main variant of the newly-created ARRAY_TYPE
+	       (with cv-qualified element type) to the main variant of
+	       the unqualified ARRAY_TYPE we started with.  */
+	    tree last_variant = t;
+	    tree m = TYPE_MAIN_VARIANT (type);
+
+	    /* Find the last variant on the new ARRAY_TYPEs list of
+	       variants, setting the main variant of each of the other
+	       types to the main variant of our unqualified
+	       ARRAY_TYPE.  */
+	    while (TYPE_NEXT_VARIANT (last_variant))
+	      {
+		TYPE_MAIN_VARIANT (last_variant) = m;
+		last_variant = TYPE_NEXT_VARIANT (last_variant);
+	      }
+
+	    /* Splice in the newly-created variants.  */
+	    TYPE_NEXT_VARIANT (last_variant) = TYPE_NEXT_VARIANT (m);
+	    TYPE_NEXT_VARIANT (m) = t;
+	    TYPE_MAIN_VARIANT (last_variant) = m;
+	  }
+      }
 
       /* Even if we already had this variant, we update
 	 TYPE_NEEDS_CONSTRUCTING and TYPE_HAS_NONTRIVIAL_DESTRUCTOR in case

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