c++: Fix qualified array-type construction [PR 98538]
authorNathan Sidwell <nathan@acm.org>
Fri, 15 Jan 2021 19:38:43 +0000 (11:38 -0800)
committerNathan Sidwell <nathan@acm.org>
Fri, 15 Jan 2021 20:45:18 +0000 (12:45 -0800)
This was an assert that was too picky.  The reason I had to alter
array construction was that on stream in, we cannot dynamically determine
a type's dependentness.  Thus on stream out of the 'problematic' types,
we save the dependentness for reconstruction.  Fortunately the paths into
cp_build_qualified_type_real from streamin with arrays do have the array's
dependentess set as needed.

PR c++/98538
gcc/cp/
* tree.c (cp_build_qualified_type_real): Propagate an array's
dependentness to the copy, if known.
gcc/testsuite/
* g++.dg/template/pr98538.C: New.

gcc/cp/tree.c
gcc/testsuite/g++.dg/template/pr98538.C [new file with mode: 0644]

index 290e73bad83799c38e3c4763207b1a8da101da0f..7dcb453ba6ae9cd2629ac908a16abe29cfcec5e6 100644 (file)
@@ -1340,10 +1340,12 @@ cp_build_qualified_type_real (tree type,
 
       if (!t)
        {
-         gcc_checking_assert (TYPE_DEPENDENT_P_VALID (type)
-                              || !dependent_type_p (type));
+         /* If we already know the dependentness, tell the array type
+            constructor.  This is important for module streaming, as we cannot
+            dynamically determine that on read in.  */
          t = build_cplus_array_type (element_type, TYPE_DOMAIN (type),
-                                     TYPE_DEPENDENT_P (type));
+                                     TYPE_DEPENDENT_P_VALID (type)
+                                     ? int (TYPE_DEPENDENT_P (type)) : -1);
 
          /* Keep the typedef name.  */
          if (TYPE_NAME (t) != TYPE_NAME (type))
diff --git a/gcc/testsuite/g++.dg/template/pr98538.C b/gcc/testsuite/g++.dg/template/pr98538.C
new file mode 100644 (file)
index 0000000..b62e8a9
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/98538
+// { dg-do compile { target c++11 } }
+// ICE bulding a dependent array type variant
+
+template<typename T> using A = int[1];
+template<typename T, const A<T>> struct X { };
+
+template<typename T>
+void
+f (const A<T>)
+{
+  const A<T> a;
+}
+
+template<typename T>
+struct Y {
+  const A<T> a;
+};