The attached is a minimal patch to avoid the ICE.  The patch doesn't
fix the type substitution of flexible array members as that seems
more involved and is, strictly speaking, outside the scope of this
bug.

Type substitution of flexible array is wrong in 5.3.0 (which treats
flexible array members the same as zero-length arrays). It's also
wrong in 6.0 but for a different reason (one having to do with their
domain, unlike the domain of arrays of unspecified bound which have
no domain, having no upper bound.  Fixing that will require more
time and surgery than just fixing the ICE and might also be more
intrusive than is appropriate at this stage.

Jason, please let me know whether or not you would like to see
the substitution failure fixed before the upcoming release as well.

Martin
gcc/testsuite/ChangeLog:
2016-01-18  Martin Sebor  <mse...@redhat.com>

	PR target/69318
	* g++.dg/ext/flexarray-subst.C: New test.

gcc/cp/ChangeLog:
2016-01-18  Martin Sebor  <mse...@redhat.com>

	PR target/69318
	* pt.c (unify): Handle flexible array members somewhat more gracefully.

Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 232526)
+++ gcc/cp/pt.c	(working copy)
@@ -19657,12 +19657,17 @@ unify (tree tparms, tree targs, tree par
     case ARRAY_TYPE:
       if (TREE_CODE (arg) != ARRAY_TYPE)
 	return unify_type_mismatch (explain_p, parm, arg);
+
+      /* Flexible array members have no upper bound.  Have them match
+         template parameters of unspecified bounds (which have a null
+         domain).  */
       if ((TYPE_DOMAIN (parm) == NULL_TREE)
-	  != (TYPE_DOMAIN (arg) == NULL_TREE))
-	return unify_type_mismatch (explain_p, parm, arg);
+          != (TYPE_DOMAIN (arg) == NULL_TREE
+              || TYPE_MAX_VALUE (TYPE_DOMAIN (arg)) == NULL_TREE))
+        return unify_type_mismatch (explain_p, parm, arg);
       RECUR_AND_CHECK_FAILURE (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg),
 			       strict & UNIFY_ALLOW_MORE_CV_QUAL, explain_p);
-      if (TYPE_DOMAIN (parm) != NULL_TREE)
+      if (TYPE_DOMAIN (parm))
 	return unify_array_domain (tparms, targs, TYPE_DOMAIN (parm),
 				   TYPE_DOMAIN (arg), explain_p);
       return unify_success (explain_p);
Index: gcc/testsuite/g++.dg/ext/flexarray-subst.C
===================================================================
--- gcc/testsuite/g++.dg/ext/flexarray-subst.C	(revision 0)
+++ gcc/testsuite/g++.dg/ext/flexarray-subst.C	(working copy)
@@ -0,0 +1,33 @@
+// PR c++/69251 - [6 Regression] ICE (segmentation fault) in unify_array_domain
+// on i686-linux-gnu
+// { dg-do compile }
+
+struct A { int n; char a[]; };
+
+template <class>
+struct B;
+
+// The following definition shouldn't be needed but is provided to prevent
+// the test from failing with an error due to PR c++/69349 - template
+// substitution error for flexible array members.  (This doesn't compromise
+// the validity of this test since all it tests for is the absennce of
+// the ICE.)
+template <class>
+struct B { typedef int X; };
+
+template <class T>
+struct B<T[]> { typedef int X; };
+
+template <class T>
+struct C { typedef typename B<T>::X X; };
+
+template <class T>
+int foo (T&, typename C<T>::X = 0)
+{
+  return 0;
+}
+
+void bar (A *a)
+{
+  foo (a->a);
+}

Reply via email to