re PR c++/33977 (internal compiler error: canonical types differ for identical types...
authorDouglas Gregor <doug.gregor@gmail.com>
Tue, 6 Nov 2007 14:39:41 +0000 (14:39 +0000)
committerDoug Gregor <dgregor@gcc.gnu.org>
Tue, 6 Nov 2007 14:39:41 +0000 (14:39 +0000)
2007-11-06  Douglas Gregor  <doug.gregor@gmail.com>

PR c++/33977
PR c++/33886
* tree.c (c_build_qualified_type): Define bridge to
cp_build_qualified_type.

2007-11-06  Douglas Gregor  <doug.gregor@gmail.com>

PR c++/33977
PR c++/33886
* c-common.c (c_build_qualified_type): Moved to c-typeck.c.
(complete_array_type): Set canonical type appropriately.
* c-typeck.c (c_build_qualified_type): Moved from c-common.c. The
C and C++ front ends now have different versions of this function,
because the C++ version needs to maintain canonical types here.

2007-11-06  Douglas Gregor  <doug.gregor@gmail.com>

PR c++/33977
PR c++/33886
* g++.dg/other/canon-array.C: New.

From-SVN: r129929

gcc/ChangeLog
gcc/c-common.c
gcc/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/testsuite/ChangeLog

index ccfa88e..6c8c570 100644 (file)
@@ -1,3 +1,13 @@
+2007-11-06  Douglas Gregor  <doug.gregor@gmail.com>
+
+       PR c++/33977
+       PR c++/33886
+       * c-common.c (c_build_qualified_type): Moved to c-typeck.c.
+       (complete_array_type): Set canonical type appropriately.
+       * c-typeck.c (c_build_qualified_type): Moved from c-common.c. The
+       C and C++ front ends now have different versions of this function,
+       because the C++ version needs to maintain canonical types here.
+
 2007-11-04  Razya Ladelsky  <razya@il.ibm.com>
        
        * tree-parloops.c (reduction_info): Remove reduction_init field.
index bdb8d80..763745a 100644 (file)
@@ -3086,70 +3086,6 @@ static void def_builtin_1  (enum built_in_function fncode,
                            bool both_p, bool fallback_p, bool nonansi_p,
                            tree fnattrs, bool implicit_p);
 
-/* Make a variant type in the proper way for C/C++, propagating qualifiers
-   down to the element type of an array.  */
-
-tree
-c_build_qualified_type (tree type, int type_quals)
-{
-  if (type == error_mark_node)
-    return type;
-
-  if (TREE_CODE (type) == ARRAY_TYPE)
-    {
-      tree t;
-      tree element_type = c_build_qualified_type (TREE_TYPE (type),
-                                                 type_quals);
-
-      /* See if we already have an identically qualified type.  */
-      for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
-       {
-         if (TYPE_QUALS (strip_array_types (t)) == type_quals
-             && TYPE_NAME (t) == TYPE_NAME (type)
-             && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
-             && attribute_list_equal (TYPE_ATTRIBUTES (t),
-                                      TYPE_ATTRIBUTES (type)))
-           break;
-       }
-      if (!t)
-       {
-          tree domain = TYPE_DOMAIN (type);
-
-         t = build_variant_type_copy (type);
-         TREE_TYPE (t) = element_type;
-
-          if (TYPE_STRUCTURAL_EQUALITY_P (element_type)
-              || (domain && TYPE_STRUCTURAL_EQUALITY_P (domain)))
-            SET_TYPE_STRUCTURAL_EQUALITY (t);
-          else if (TYPE_CANONICAL (element_type) != element_type
-                   || (domain && TYPE_CANONICAL (domain) != domain))
-            {
-              tree unqualified_canon 
-                = build_array_type (TYPE_CANONICAL (element_type),
-                                    domain? TYPE_CANONICAL (domain) 
-                                          : NULL_TREE);
-              TYPE_CANONICAL (t) 
-                = c_build_qualified_type (unqualified_canon, type_quals);
-            }
-          else
-            TYPE_CANONICAL (t) = t;
-       }
-      return t;
-    }
-
-  /* A restrict-qualified pointer type must be a pointer to object or
-     incomplete type.  Note that the use of POINTER_TYPE_P also allows
-     REFERENCE_TYPEs, which is appropriate for C++.  */
-  if ((type_quals & TYPE_QUAL_RESTRICT)
-      && (!POINTER_TYPE_P (type)
-         || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
-    {
-      error ("invalid use of %<restrict%>");
-      type_quals &= ~TYPE_QUAL_RESTRICT;
-    }
-
-  return build_qualified_type (type, type_quals);
-}
 
 /* Apply the TYPE_QUALS to the new DECL.  */
 
@@ -7044,6 +6980,19 @@ complete_array_type (tree *ptype, tree initial_value, bool do_default)
                                    hashcode);
   main_type = type_hash_canon (hashcode, main_type);
 
+  /* Fix the canonical type.  */
+  if (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (main_type))
+      || TYPE_STRUCTURAL_EQUALITY_P (TYPE_DOMAIN (main_type)))
+    SET_TYPE_STRUCTURAL_EQUALITY (main_type);
+  else if (TYPE_CANONICAL (TREE_TYPE (main_type)) != TREE_TYPE (main_type)
+          || (TYPE_CANONICAL (TYPE_DOMAIN (main_type))
+              != TYPE_DOMAIN (main_type)))
+    TYPE_CANONICAL (main_type) 
+      = build_array_type (TYPE_CANONICAL (TREE_TYPE (main_type)),
+                         TYPE_CANONICAL (TYPE_DOMAIN (main_type)));
+  else
+    TYPE_CANONICAL (main_type) = main_type;
+
   if (quals == 0)
     type = main_type;
   else
index 9f3d9cb..eee5789 100644 (file)
@@ -8896,3 +8896,68 @@ c_finish_omp_clauses (tree clauses)
   bitmap_obstack_release (NULL);
   return clauses;
 }
+
+/* Make a variant type in the proper way for C/C++, propagating qualifiers
+   down to the element type of an array.  */
+
+tree
+c_build_qualified_type (tree type, int type_quals)
+{
+  if (type == error_mark_node)
+    return type;
+
+  if (TREE_CODE (type) == ARRAY_TYPE)
+    {
+      tree t;
+      tree element_type = c_build_qualified_type (TREE_TYPE (type),
+                                                 type_quals);
+
+      /* See if we already have an identically qualified type.  */
+      for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+       {
+         if (TYPE_QUALS (strip_array_types (t)) == type_quals
+             && TYPE_NAME (t) == TYPE_NAME (type)
+             && TYPE_CONTEXT (t) == TYPE_CONTEXT (type)
+             && attribute_list_equal (TYPE_ATTRIBUTES (t),
+                                      TYPE_ATTRIBUTES (type)))
+           break;
+       }
+      if (!t)
+       {
+          tree domain = TYPE_DOMAIN (type);
+
+         t = build_variant_type_copy (type);
+         TREE_TYPE (t) = element_type;
+
+          if (TYPE_STRUCTURAL_EQUALITY_P (element_type)
+              || (domain && TYPE_STRUCTURAL_EQUALITY_P (domain)))
+            SET_TYPE_STRUCTURAL_EQUALITY (t);
+          else if (TYPE_CANONICAL (element_type) != element_type
+                   || (domain && TYPE_CANONICAL (domain) != domain))
+            {
+              tree unqualified_canon 
+                = build_array_type (TYPE_CANONICAL (element_type),
+                                    domain? TYPE_CANONICAL (domain) 
+                                          : NULL_TREE);
+              TYPE_CANONICAL (t) 
+                = c_build_qualified_type (unqualified_canon, type_quals);
+            }
+          else
+            TYPE_CANONICAL (t) = t;
+       }
+      return t;
+    }
+
+  /* A restrict-qualified pointer type must be a pointer to object or
+     incomplete type.  Note that the use of POINTER_TYPE_P also allows
+     REFERENCE_TYPEs, which is appropriate for C++.  */
+  if ((type_quals & TYPE_QUAL_RESTRICT)
+      && (!POINTER_TYPE_P (type)
+         || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
+    {
+      error ("invalid use of %<restrict%>");
+      type_quals &= ~TYPE_QUAL_RESTRICT;
+    }
+
+  return build_qualified_type (type, type_quals);
+}
index 9fff78d..96d2dd7 100644 (file)
@@ -1,5 +1,12 @@
 2007-11-06  Douglas Gregor  <doug.gregor@gmail.com>
 
+       PR c++/33977
+       PR c++/33886
+       * tree.c (c_build_qualified_type): Define bridge to
+       cp_build_qualified_type.
+
+2007-11-06  Douglas Gregor  <doug.gregor@gmail.com>
+
        PR c++/31439
        PR c++/32114
        PR c++/32115
index fba7c22..c2b4af0 100644 (file)
@@ -649,6 +649,14 @@ cp_build_reference_type (tree to_type, bool rval)
 
 }
 
+/* Used by the C++ front end to build qualified array types.  However,
+   the C version of this function does not properly maintain canonical
+   types (which are not used in C).  */
+tree
+c_build_qualified_type (tree type, int type_quals)
+{
+  return cp_build_qualified_type (type, type_quals);
+}
 
 \f
 /* Make a variant of TYPE, qualified with the TYPE_QUALS.  Handles
index 6689530..76b42c9 100644 (file)
@@ -1,5 +1,11 @@
 2007-11-06  Douglas Gregor  <doug.gregor@gmail.com>
 
+       PR c++/33977
+       PR c++/33886
+       * g++.dg/other/canon-array.C: New.
+       
+2007-11-06  Douglas Gregor  <doug.gregor@gmail.com>
+
        * testsuite/g++.dg/parser/crash36.C: Tweak expected errors.
        * testsuite/g++.dg/cpp0x/pr31439.C: New.
        * testsuite/g++.dg/cpp0x/pr32114.C: New.