c++: Revert dependent-array changes [PR 98116]
authorNathan Sidwell <nathan@acm.org>
Fri, 4 Dec 2020 16:34:41 +0000 (08:34 -0800)
committerNathan Sidwell <nathan@acm.org>
Fri, 4 Dec 2020 16:38:57 +0000 (08:38 -0800)
The changes reverted here are exposing an existing problem with alias
template comparisons.  The typename_type changes are also incomplete,
possibly for similar reasons.  It seems safer to revert them, fix the
underlying issue and then move forwards.

The testcases is adjusted to more robustly check the specialization
table, and ICEs with and without the c++ changes.

Revert:
62fb1b9e0da c++: Fix array type dependency [PR 98107]
07589ca2b2c c++: typename_type structural comparison
29ae1d7751 c++: Extend build_array_type API

PR c++/98116
gcc/cp/
* cp-tree.h (comparing_typenames): Delete.
(cplus_build_array_type): Remove default parm.
* pt.c (comparing_typenames): Delete.
(spec_hasher::equal): Don't increment it.
* tree.c (set_array_type_canon): Remove dep parm.
(build_cplus_array_type): Remove dep parm changes.
(cp_build_qualified_type_real): Remove dependent array type
changes.
(strip_typedefs): Likewise.
* typeck.c (structural_comptypes): Revert comparing_typename
changes.
gcc/testsuite/
* g++.dg/template/pr98116.C: Enable robust checking.

gcc/cp/cp-tree.h
gcc/cp/pt.c
gcc/cp/tree.c
gcc/cp/typeck.c
gcc/testsuite/g++.dg/template/pr98116.C

index c7f8371c6650c35d8c6f932dcdacfe5840f14008..00901fe42d40225e38a86e092c03d02be5ac5358 100644 (file)
@@ -5422,10 +5422,6 @@ extern int function_depth;
    in structrual_comptypes.  */
 extern int comparing_specializations;
 
-/* Nonzero if we are inside eq_specializations, which affects
-   resolving of typenames in structural_comptypes.  */
-extern int comparing_typenames;
-
 /* In parser.c.  */
 
 /* Nonzero if we are parsing an unevaluated operand: an operand to
@@ -7563,7 +7559,7 @@ extern bool is_local_temp                 (tree);
 extern tree build_aggr_init_expr               (tree, tree);
 extern tree get_target_expr                    (tree);
 extern tree get_target_expr_sfinae             (tree, tsubst_flags_t);
-extern tree build_cplus_array_type             (tree, tree, int is_dep = -1);
+extern tree build_cplus_array_type             (tree, tree);
 extern tree build_array_of_n_type              (tree, int);
 extern bool array_of_runtime_bound_p           (tree);
 extern bool vla_type_p                         (tree);
index 08931823d576052b8788c20ecf2d57161bb7b49e..9e8113d51a3e0ce90f27f0a2c3dbfcd3b262b19b 100644 (file)
@@ -1704,19 +1704,16 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend,
   return spec;
 }
 
-/* Restricts tree and type comparisons.  */
-int comparing_specializations;
-int comparing_typenames;
-
 /* Returns true iff two spec_entry nodes are equivalent.  */
 
+int comparing_specializations;
+
 bool
 spec_hasher::equal (spec_entry *e1, spec_entry *e2)
 {
   int equal;
 
   ++comparing_specializations;
-  ++comparing_typenames;
   equal = (e1->tmpl == e2->tmpl
           && comp_template_args (e1->args, e2->args));
   if (equal && flag_concepts
@@ -1732,7 +1729,6 @@ spec_hasher::equal (spec_entry *e1, spec_entry *e2)
       equal = equivalent_constraints (c1, c2);
     }
   --comparing_specializations;
-  --comparing_typenames;
 
   return equal;
 }
index d9fa505041f5495cd59e28458bb64b16b17bc16c..4e6bf9abba66ccc918f9cac92b13c4e02bb94399 100644 (file)
@@ -998,7 +998,7 @@ build_min_array_type (tree elt_type, tree index_type)
    build_cplus_array_type.  */
 
 static void
-set_array_type_canon (tree t, tree elt_type, tree index_type, bool dep)
+set_array_type_canon (tree t, tree elt_type, tree index_type)
 {
   /* Set the canonical type for this new node.  */
   if (TYPE_STRUCTURAL_EQUALITY_P (elt_type)
@@ -1009,33 +1009,30 @@ set_array_type_canon (tree t, tree elt_type, tree index_type, bool dep)
     TYPE_CANONICAL (t)
       = build_cplus_array_type (TYPE_CANONICAL (elt_type),
                                index_type
-                               ? TYPE_CANONICAL (index_type) : index_type,
-                               dep);
+                               ? TYPE_CANONICAL (index_type) : index_type);
   else
     TYPE_CANONICAL (t) = t;
 }
 
 /* Like build_array_type, but handle special C++ semantics: an array of a
    variant element type is a variant of the array of the main variant of
-   the element type.  IS_DEPENDENT is -ve if we should determine the
-   dependency.  Otherwise its bool value indicates dependency.  */
+   the element type.  */
 
 tree
-build_cplus_array_type (tree elt_type, tree index_type, int dependent)
+build_cplus_array_type (tree elt_type, tree index_type)
 {
   tree t;
 
   if (elt_type == error_mark_node || index_type == error_mark_node)
     return error_mark_node;
 
-  if (dependent < 0)
-    dependent = (uses_template_parms (elt_type)
-                || (index_type && uses_template_parms (index_type)));
+  bool dependent = (uses_template_parms (elt_type)
+                   || (index_type && uses_template_parms (index_type)));
 
   if (elt_type != TYPE_MAIN_VARIANT (elt_type))
     /* Start with an array of the TYPE_MAIN_VARIANT.  */
     t = build_cplus_array_type (TYPE_MAIN_VARIANT (elt_type),
-                               index_type, dependent);
+                               index_type);
   else if (dependent)
     {
       /* Since type_hash_canon calls layout_type, we need to use our own
@@ -1065,20 +1062,13 @@ build_cplus_array_type (tree elt_type, tree index_type, int dependent)
          *e = t;
 
          /* Set the canonical type for this new node.  */
-         set_array_type_canon (t, elt_type, index_type, dependent);
-
-         /* Mark it as dependent now, this saves time later.  */
-         TYPE_DEPENDENT_P_VALID (t) = true;
-         TYPE_DEPENDENT_P (t) = true;
+         set_array_type_canon (t, elt_type, index_type);
        }
     }
   else
     {
       bool typeless_storage = is_byte_access_type (elt_type);
       t = build_array_type (elt_type, index_type, typeless_storage);
-
-      /* Mark as non-dependenty now, this will save time later.  */
-      TYPE_DEPENDENT_P_VALID (t) = true;
     }
 
   /* Now check whether we already have this array variant.  */
@@ -1093,10 +1083,7 @@ build_cplus_array_type (tree elt_type, tree index_type, int dependent)
       if (!t)
        {
          t = build_min_array_type (elt_type, index_type);
-         /* Mark dependency now, this saves time later.  */
-         TYPE_DEPENDENT_P_VALID (t) = true;
-         TYPE_DEPENDENT_P (t) = dependent;
-         set_array_type_canon (t, elt_type, index_type, dependent);
+         set_array_type_canon (t, elt_type, index_type);
          if (!dependent)
            {
              layout_type (t);
@@ -1332,10 +1319,7 @@ cp_build_qualified_type_real (tree type,
 
       if (!t)
        {
-         gcc_checking_assert (TYPE_DEPENDENT_P_VALID (type)
-                              || !dependent_type_p (type));
-         t = build_cplus_array_type (element_type, TYPE_DOMAIN (type),
-                                     TYPE_DEPENDENT_P (type));
+         t = build_cplus_array_type (element_type, TYPE_DOMAIN (type));
 
          /* Keep the typedef name.  */
          if (TYPE_NAME (t) != TYPE_NAME (type))
@@ -1571,9 +1555,7 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags)
     case ARRAY_TYPE:
       type = strip_typedefs (TREE_TYPE (t), remove_attributes, flags);
       t0  = strip_typedefs (TYPE_DOMAIN (t), remove_attributes, flags);
-      gcc_checking_assert (TYPE_DEPENDENT_P_VALID (t)
-                          || !dependent_type_p (t));
-      result = build_cplus_array_type (type, t0, TYPE_DEPENDENT_P (t));
+      result = build_cplus_array_type (type, t0);
       break;
     case FUNCTION_TYPE:
     case METHOD_TYPE:
index 6294a787b5a7c823e88403c03383979a38da5624..267b284ea40fad3c985ed520e7f7eab91ea19fc8 100644 (file)
@@ -1256,15 +1256,16 @@ structural_comptypes (tree t1, tree t2, int strict)
 
   gcc_assert (TYPE_P (t1) && TYPE_P (t2));
 
-  /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
-     current instantiation, and we don't care about typename
-     structural equality.  The comparing_typenames check is after the
-     code check, in order to early-out the common case.  */
-  if (TREE_CODE (t1) == TYPENAME_TYPE && !comparing_typenames)
-    t1 = resolve_typename_type (t1, /*only_current_p=*/true);
-
-  if (TREE_CODE (t2) == TYPENAME_TYPE && !comparing_typenames)
-    t2 = resolve_typename_type (t2, /*only_current_p=*/true);
+  if (!comparing_specializations)
+    {
+      /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
+        current instantiation.  */
+      if (TREE_CODE (t1) == TYPENAME_TYPE)
+       t1 = resolve_typename_type (t1, /*only_current_p=*/true);
+
+      if (TREE_CODE (t2) == TYPENAME_TYPE)
+       t2 = resolve_typename_type (t2, /*only_current_p=*/true);
+    }
 
   if (TYPE_PTRMEMFUNC_P (t1))
     t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
index d3398d2238c4b2c1be9f41bf6490ef72a2a3edd7..874c590f9d238295bc99a72e46c52e7ea776652c 100644 (file)
@@ -1,5 +1,11 @@
 // PR 98116, ICE with stripping typedef array type
 // { dg-do compile { target c++11 } }
+// { dg-additional-options {--param=hash-table-verification-limit=10000000 -fchecking=2} }
+// { dg-ice "spec_hasher::equal" }
+
+// We get confused by alias templates that alias the same type.
+// { dg-prune-output "hash table checking failed" }
+
 namespace std {
 struct is_convertible;
 template <typename _Tp> using remove_pointer_t = typename _Tp ::type;