gcc/testsuite/ChangeLog:
2016-01-18 Martin Sebor <msebor@redhat.com>
PR target/69318
* g++.dg/ext/flexarray-subst.C: New test.
gcc/cp/ChangeLog:
2016-01-18 Martin Sebor <msebor@redhat.com>
PR target/69318
* pt.c (unify): Handle flexible array members somewhat more gracefully.
===================================================================
@@ -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);
===================================================================
@@ -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);
+}