public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
@ 2016-01-19  2:30 Martin Sebor
  2016-01-21 23:19 ` Jason Merrill
  0 siblings, 1 reply; 16+ messages in thread
From: Martin Sebor @ 2016-01-19  2:30 UTC (permalink / raw)
  To: Gcc Patch List, Jason Merrill

[-- Attachment #1: Type: text/plain, Size: 794 bytes --]

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

[-- Attachment #2: gcc-69251.patch --]
[-- Type: text/x-patch, Size: 2510 bytes --]

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.

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);
+}

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-01-19  2:30 [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member Martin Sebor
@ 2016-01-21 23:19 ` Jason Merrill
  2016-01-21 23:32   ` Martin Sebor
  0 siblings, 1 reply; 16+ messages in thread
From: Jason Merrill @ 2016-01-21 23:19 UTC (permalink / raw)
  To: Martin Sebor, Gcc Patch List

Can we reconsider the representation of flexible arrays?  Following the 
example of the C front-end is causing a lot of trouble, and using a null 
TYPE_DOMAIN seems more intuitive.

Jason

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-01-21 23:19 ` Jason Merrill
@ 2016-01-21 23:32   ` Martin Sebor
  2016-01-25 16:55     ` Martin Sebor
  0 siblings, 1 reply; 16+ messages in thread
From: Martin Sebor @ 2016-01-21 23:32 UTC (permalink / raw)
  To: Jason Merrill, Gcc Patch List

On 01/21/2016 04:19 PM, Jason Merrill wrote:
> Can we reconsider the representation of flexible arrays?  Following the
> example of the C front-end is causing a lot of trouble, and using a null
> TYPE_DOMAIN seems more intuitive.

I remember running into at least one ICE in the middle end with
the alternate representation (null TYPE_DOMAIN).  At this late
stage I would worry about the fallout from that. It seems that
outside of 69251 and 69277 the problems are mostly triggered by
ill-formed code that wasn't being tested and I'm hoping that
the problems in the well-formed cases have been reported (and
with the patches I've sent fixed).

At the same time, based on some debugging I had to do for 69251
(ICE in unify_array_domain on a flexible array member) it seems
that it might make handling them in template easier.

Martin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-01-21 23:32   ` Martin Sebor
@ 2016-01-25 16:55     ` Martin Sebor
  2016-02-01  2:01       ` PING " Martin Sebor
  2016-02-02 12:28       ` Jason Merrill
  0 siblings, 2 replies; 16+ messages in thread
From: Martin Sebor @ 2016-01-25 16:55 UTC (permalink / raw)
  To: Jason Merrill, Gcc Patch List

[-- Attachment #1: Type: text/plain, Size: 2438 bytes --]

On 01/21/2016 04:32 PM, Martin Sebor wrote:
> On 01/21/2016 04:19 PM, Jason Merrill wrote:
>> Can we reconsider the representation of flexible arrays?  Following the
>> example of the C front-end is causing a lot of trouble, and using a null
>> TYPE_DOMAIN seems more intuitive.
>
> I remember running into at least one ICE in the middle end with
> the alternate representation (null TYPE_DOMAIN).  At this late
> stage I would worry about the fallout from that. It seems that
> outside of 69251 and 69277 the problems are mostly triggered by
> ill-formed code that wasn't being tested and I'm hoping that
> the problems in the well-formed cases have been reported (and
> with the patches I've sent fixed).
>
> At the same time, based on some debugging I had to do for 69251
> (ICE in unify_array_domain on a flexible array member) it seems
> that it might make handling them in template easier.

In a discussion with Jason in IRC I agreed to submit a patch
changing the representation of flexible array members in the C++
front end to use a null domain rather than a domain with a null
upper bound.  Attached is a patch making the requested change.
It fixes the following bugs:

c++/69251 - [6 Regression] ICE in unify_array_domain on a flexible
   array member
   (the bug in the Subject)
c++/69253 - [6 Regression] ICE in cxx_incomplete_type_diagnostic
   initializing a flexible array member with empty string
   with the original patch here:
   https://gcc.gnu.org/ml/gcc-patches/2016-01/msg01325.htm
and
c++/69290 - [6 Regression] ICE on invalid initialization
   of a flexible array member
   with the original patch here:
   https://gcc.gnu.org/ml/gcc-patches/2016-01/msg01685.html
as well as
c++/69277 - [6 Regression] ICE mangling a flexible array member
   with its final patch posted here
   https://gcc.gnu.org/ml/gcc-patches/2016-01/msg01233.html

The downside of this approach is that it prevents everything but
the front end from distinguishing flexible array members from
arrays of unspecified or unknown bounds.  The immediate impact
is that prevents us from maintaining ABI compatibility with GCC
5 (with -fabi-version=9) and from diagnosing the mangling change.
This means should we decide to adopt this approach, the final
version of the patch for c++/69277 mentioned above that's still
pending approval will need to be tweaked to have the ABI checks
removed.

I successfully tested the new patch on x86_64.

Martin


[-- Attachment #2: gcc-69251.patch --]
[-- Type: text/x-patch, Size: 9322 bytes --]

PR c++/69251 - [6 Regression] ICE in unify_array_domain on a flexible array
	member
PR c++/69253 - [6 Regression] ICE in cxx_incomplete_type_diagnostic
	initializing a flexible array member with empty string
PR c++/69290 - [6 Regression] ICE on invalid initialization of a flexible
	array member

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

	PR c++/69253
	PR c++/69251
	PR c++/69290
	* g++.dg/ext/flexarray-subst.C: New test.
	* g++.dg/ext/flexary11.C: New test.
	* g++.dg/ext/flexary12.C: New test.
	* g++.dg/ext/flexary13.C: New test.
	* g++.dg/ext/flexary14.C: New test.
	* g++.dg/other/dump-ada-spec-2.C: Adjust.

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

	PR c++/69253
	PR c++/69251
	PR c++/69290
	* decl.c (compute_array_index_type): Return null for flexible array
	members.
	* tree.c (array_of_runtime_bound_p): Handle gracefully array types
	with null TYPE_MAX_VALUE.
	(build_ctor_subob_ref): Loosen debug checking to handle flexible
	array members.

diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index ceeef60..beb7c58 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8638,8 +8638,9 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
   tree itype;
   tree osize = size;
 
+  /* Flexible array members have no domain.  */
   if (size == NULL_TREE)
-    return build_index_type (NULL_TREE);
+    return NULL_TREE;
 
   if (error_operand_p (size))
     return error_mark_node;
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index e2123ac..779652c 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -937,9 +937,10 @@ array_of_runtime_bound_p (tree t)
   tree dom = TYPE_DOMAIN (t);
   if (!dom)
     return false;
-  tree max = TYPE_MAX_VALUE (dom);
-  return (!potential_rvalue_constant_expression (max)
-	  || (!value_dependent_expression_p (max) && !TREE_CONSTANT (max)));
+  if (tree max = TYPE_MAX_VALUE (dom))
+    return (!potential_rvalue_constant_expression (max)
+	    || (!value_dependent_expression_p (max) && !TREE_CONSTANT (max)));
+  return false;
 }
 
 /* Return a reference type node referring to TO_TYPE.  If RVAL is
@@ -2556,8 +2557,21 @@ build_ctor_subob_ref (tree index, tree type, tree obj)
     obj = build_class_member_access_expr (obj, index, NULL_TREE,
 					  /*reference*/false, tf_none);
   if (obj)
-    gcc_assert (same_type_ignoring_top_level_qualifiers_p (type,
-							   TREE_TYPE (obj)));
+    {
+      tree objtype = TREE_TYPE (obj);
+      if (TREE_CODE (objtype) == ARRAY_TYPE
+	  && (!TYPE_DOMAIN (objtype)
+	      || !TYPE_MAX_VALUE (TYPE_DOMAIN (objtype))))
+	{
+	  /* When the destination object refers to a flexible array member
+	     verify that it matches the type of the source object except
+	     for its domain.  */
+	  gcc_assert (comptypes (type, objtype, COMPARE_REDECLARATION));
+	}
+      else
+	gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, objtype));
+    }
+
   return obj;
 }
 
diff --git a/gcc/testsuite/g++.dg/ext/flexarray-subst.C b/gcc/testsuite/g++.dg/ext/flexarray-subst.C
new file mode 100644
index 0000000..f644636
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexarray-subst.C
@@ -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);
+}
diff --git a/gcc/testsuite/g++.dg/ext/flexary11.C b/gcc/testsuite/g++.dg/ext/flexary11.C
new file mode 100644
index 0000000..5bf774f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexary11.C
@@ -0,0 +1,19 @@
+// PR c++/69253 - [6 Regression] g++ ICE at -O0 on x86_64-linux-gnu
+//                in "cxx_incomplete_type_diagnostic"
+// { dg-do compile }
+
+struct A {
+  int n;
+  char a [];
+};
+
+void f ()
+{
+  // Compound literals and flexible array members are G++ extensions
+  // accepted for compatibility with C and GCC.
+
+  // The following use of a flexible array member in a compound literal
+  // is invalid in C and rejected by GCC in C mode and so it's also
+  // rejected in C++ mode.
+  (struct A){ 1, "" };   // { dg-error "forbids compound-literals|initialization of a flexible array member|invalid use of a flexible array member" }
+}
diff --git a/gcc/testsuite/g++.dg/ext/flexary12.C b/gcc/testsuite/g++.dg/ext/flexary12.C
new file mode 100644
index 0000000..3d8c805
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexary12.C
@@ -0,0 +1,63 @@
+// PR c++/69290 - [6 Regression] g++ ICE on invalid initialization
+//     of a flexible array member
+// { dg-do compile }
+
+// Suppress pedantic errors about initialization of a flexible array member.
+// { dg-options "-Wno-pedantic" }
+
+struct A {
+  int a [];  // { dg-error "flexible array member .A::a. in an otherwise empty .struct A." }
+};
+
+void f1 ()
+{
+  // This is the meat of the test from c++/69290:
+  struct A a
+    = { "c" };   // { dg-error "invalid conversion from .const char\\*. to .int." }
+
+  (void)&a;
+}
+
+
+// Exercise other forms of invalid initialization besides the one in the bug.
+struct B {
+  int n;
+  int a [];
+};
+
+void f2 ()
+{
+  struct B b1
+    = { 0, "c" };   // { dg-error "invalid conversion from .const char\\*. to .int." }
+
+  (void)&b1;
+
+  const char s[] = "c";
+  struct B b2
+    = { 0, s };   // { dg-error "invalid conversion from .const char\\*. to .int." }
+
+  (void)&b2;
+}
+
+struct D {
+  int a [];  // { dg-error "flexible array member .D::a. in an otherwise empty .struct D." }
+  D ();
+};
+
+D::D ():
+  a ("c")   // { dg-error "incompatible types in assignment of .const char \\\[2\\\]. to .int \\\[\\\]." }
+{ }
+
+
+template <class T>
+struct C {
+  T a [];  // { dg-error "flexible array member" }
+};
+
+void f3 ()
+{
+  struct C<double> cd
+    = { "c" };   // { dg-error "cannot convert .const char\\*. to .double." }
+
+  (void)&cd;
+}
diff --git a/gcc/testsuite/g++.dg/ext/flexary13.C b/gcc/testsuite/g++.dg/ext/flexary13.C
new file mode 100644
index 0000000..462ed65
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexary13.C
@@ -0,0 +1,64 @@
+// { dg-do compile }
+// { dg-options -Wno-pedantic }
+
+#define STR(s) #s
+#define ASSERT(exp) \
+  ((exp) ? (void)0 : (void)(__builtin_printf ("%s:%i: assertion %s failed\n", \
+                     __FILE__, __LINE__, STR(exp)), \
+                      __builtin_abort ()))
+
+struct Ax { int n, a[]; };
+struct AAx { int i; Ax ax; };
+
+int i = 12345678;
+
+int main ()
+{
+  {
+    Ax s = { 0 };
+    ASSERT (s.n == 0);
+  }
+  {
+    Ax s =
+      { 0, { } };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n == 0);
+  }
+  {
+    Ax s =
+      { 1, { 2 } };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n == 1 && s.a [0] == 2);
+  }
+  {
+    Ax s =
+      { 2, { 3, 4 } }; // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n = 2 && s.a [0] == 3 && s.a [1] == 4);
+  }
+  {
+    Ax s =
+      { 123, i };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n == 123 && s.a [0] == i);
+  }
+  {
+    Ax s =
+      { 456, { i } }; // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n == 456 && s.a [0] == i);
+  }
+  {
+    int j = i + 1, k = j + 1;
+    Ax s =
+      { 3, { i, j, k } }; // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n == 3 && s.a [0] == i && s.a [1] == j && s.a [2] == k);
+  }
+
+  {
+    AAx s =
+      { 1, { 2 } };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.i == 1 && s.ax.n == 2);
+  }
+
+  {
+    AAx s =
+      { 1, { 2, { 3 } } };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.i == 1 && s.ax.n == 2 && s.ax.a [0] == 3);
+  }
+}
diff --git a/gcc/testsuite/g++.dg/ext/flexary14.C b/gcc/testsuite/g++.dg/ext/flexary14.C
new file mode 100644
index 0000000..7365357
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexary14.C
@@ -0,0 +1,17 @@
+// PR c++/69349 - template substitution error for flexible array members
+// { dg-do compile }
+
+template <class>
+struct A;
+
+template <class T>
+struct A<T[]> { typedef int X; };
+
+template <class T> int foo (T&, typename A<T>::X = 0) { return 0; }
+
+struct B { int n, a[]; };
+
+void bar (B *b)
+{
+    foo (b->a);
+}
diff --git a/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C b/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C
index d1af7e0..608b5be 100644
--- a/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C
+++ b/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C
@@ -7,5 +7,5 @@ struct S
   __extension__ unsigned char data[];
 };
 
-/* { dg-final { scan-ada-spec "array \\(0 .. 0\\)" } } */
+/* { dg-final { scan-ada-spec "array \\(size_t\\)" } } */
 /* { dg-final { cleanup-ada-spec } } */

^ permalink raw reply	[flat|nested] 16+ messages in thread

* PING [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-01-25 16:55     ` Martin Sebor
@ 2016-02-01  2:01       ` Martin Sebor
  2016-02-02 12:28       ` Jason Merrill
  1 sibling, 0 replies; 16+ messages in thread
From: Martin Sebor @ 2016-02-01  2:01 UTC (permalink / raw)
  To: Jason Merrill, Gcc Patch List

Jason,

Have you had a chance to review the patch below and consider
the ABI ramifications I mentioned?

   https://gcc.gnu.org/ml/gcc-patches/2016-01/msg01901.html

Thanks
Martin

On 01/25/2016 09:55 AM, Martin Sebor wrote:
> On 01/21/2016 04:32 PM, Martin Sebor wrote:
>> On 01/21/2016 04:19 PM, Jason Merrill wrote:
>>> Can we reconsider the representation of flexible arrays?  Following the
>>> example of the C front-end is causing a lot of trouble, and using a null
>>> TYPE_DOMAIN seems more intuitive.
>>
>> I remember running into at least one ICE in the middle end with
>> the alternate representation (null TYPE_DOMAIN).  At this late
>> stage I would worry about the fallout from that. It seems that
>> outside of 69251 and 69277 the problems are mostly triggered by
>> ill-formed code that wasn't being tested and I'm hoping that
>> the problems in the well-formed cases have been reported (and
>> with the patches I've sent fixed).
>>
>> At the same time, based on some debugging I had to do for 69251
>> (ICE in unify_array_domain on a flexible array member) it seems
>> that it might make handling them in template easier.
>
> In a discussion with Jason in IRC I agreed to submit a patch
> changing the representation of flexible array members in the C++
> front end to use a null domain rather than a domain with a null
> upper bound.  Attached is a patch making the requested change.
> It fixes the following bugs:
>
> c++/69251 - [6 Regression] ICE in unify_array_domain on a flexible
>    array member
>    (the bug in the Subject)
> c++/69253 - [6 Regression] ICE in cxx_incomplete_type_diagnostic
>    initializing a flexible array member with empty string
>    with the original patch here:
>    https://gcc.gnu.org/ml/gcc-patches/2016-01/msg01325.htm
> and
> c++/69290 - [6 Regression] ICE on invalid initialization
>    of a flexible array member
>    with the original patch here:
>    https://gcc.gnu.org/ml/gcc-patches/2016-01/msg01685.html
> as well as
> c++/69277 - [6 Regression] ICE mangling a flexible array member
>    with its final patch posted here
>    https://gcc.gnu.org/ml/gcc-patches/2016-01/msg01233.html
>
> The downside of this approach is that it prevents everything but
> the front end from distinguishing flexible array members from
> arrays of unspecified or unknown bounds.  The immediate impact
> is that prevents us from maintaining ABI compatibility with GCC
> 5 (with -fabi-version=9) and from diagnosing the mangling change.
> This means should we decide to adopt this approach, the final
> version of the patch for c++/69277 mentioned above that's still
> pending approval will need to be tweaked to have the ABI checks
> removed.
>
> I successfully tested the new patch on x86_64.
>
> Martin
>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-01-25 16:55     ` Martin Sebor
  2016-02-01  2:01       ` PING " Martin Sebor
@ 2016-02-02 12:28       ` Jason Merrill
  2016-02-03  1:21         ` Martin Sebor
  1 sibling, 1 reply; 16+ messages in thread
From: Jason Merrill @ 2016-02-02 12:28 UTC (permalink / raw)
  To: Martin Sebor, Gcc Patch List

On 01/25/2016 05:55 PM, Martin Sebor wrote:
> The downside of this approach is that it prevents everything but
> the front end from distinguishing flexible array members from
> arrays of unspecified or unknown bounds.  The immediate impact
> is that prevents us from maintaining ABI compatibility with GCC
> 5 (with -fabi-version=9) and from diagnosing the mangling change.
> This means should we decide to adopt this approach, the final
> version of the patch for c++/69277 mentioned above that's still
> pending approval will need to be tweaked to have the ABI checks
> removed.

That's unfortunate, but I think acceptable.

> 	* decl.c (compute_array_index_type): Return null for flexible array
> 	members.

Instead of this, I would think we can remove the calls to 
compute_array_index_type added by your earlier patch, as well as many 
other changes from that patch to handle null TYPE_MAX_VALUE.

> 	* tree.c (array_of_runtime_bound_p): Handle gracefully array types
> 	with null TYPE_MAX_VALUE.

This seems unneeded.

> 	(build_ctor_subob_ref): Loosen debug checking to handle flexible
> 	array members.

And this shouldn't need the TYPE_MAX_VALUE check.

Jason

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-02-02 12:28       ` Jason Merrill
@ 2016-02-03  1:21         ` Martin Sebor
  2016-02-03 18:47           ` Jason Merrill
  2016-02-04 11:05           ` Jakub Jelinek
  0 siblings, 2 replies; 16+ messages in thread
From: Martin Sebor @ 2016-02-03  1:21 UTC (permalink / raw)
  To: Jason Merrill, Gcc Patch List

[-- Attachment #1: Type: text/plain, Size: 2216 bytes --]

On 02/02/2016 05:28 AM, Jason Merrill wrote:
> On 01/25/2016 05:55 PM, Martin Sebor wrote:
>> The downside of this approach is that it prevents everything but
>> the front end from distinguishing flexible array members from
>> arrays of unspecified or unknown bounds.  The immediate impact
>> is that prevents us from maintaining ABI compatibility with GCC
>> 5 (with -fabi-version=9) and from diagnosing the mangling change.
>> This means should we decide to adopt this approach, the final
>> version of the patch for c++/69277 mentioned above that's still
>> pending approval will need to be tweaked to have the ABI checks
>> removed.
>
> That's unfortunate, but I think acceptable.
>
>>     * decl.c (compute_array_index_type): Return null for flexible array
>>     members.
>
> Instead of this, I would think we can remove the calls to
> compute_array_index_type added by your earlier patch, as well as many
> other changes from that patch to handle null TYPE_MAX_VALUE.

Yes, that's possible but it didn't seem essential at this stage.
I wanted to make only conservative changes to avoid any further
fallout.  I also wasn't sure whether the ABI issue above would
make this approach unviable.

>
>>     * tree.c (array_of_runtime_bound_p): Handle gracefully array types
>>     with null TYPE_MAX_VALUE.
>
> This seems unneeded.
>
>>     (build_ctor_subob_ref): Loosen debug checking to handle flexible
>>     array members.
>
> And this shouldn't need the TYPE_MAX_VALUE check.

I went ahead and made the requested changes.  They might seem
perfectly innocuous to you but the removal of the tests for
TYPE_MAX_VALUE(t) being null makes me nervous at this stage.
I'm not nearly comfortable enough with the code to be confident
that they're all 100% safe.  I defer to your better judgment
on this.

In the patch, I also corrected some transgressions against
the GNU formatting rules I introduced in the the original
change.

I've regtested the patch on x86_64.

Please let me know if this patch is good to commit.  In light
of his today's comment on bug 69277 I have the impression
Jakub would like to have the mangling change in the Fedora
mass rebuild or release and I don't want to hold that up.

Thanks
Martin

[-- Attachment #2: gcc-69251.patch --]
[-- Type: text/x-patch, Size: 19995 bytes --]

PR c++/69251 - [6 Regression] ICE in unify_array_domain on a flexible array
               member
PR c++/69253 - [6 Regression] ICE in cxx_incomplete_type_diagnostic initializing
               a flexible array member with empty string
PR c++/69290 - [6 Regression] ICE on invalid initialization of a flexible array
               member
PR c++/69277 - [6 Regression] ICE mangling a flexible array member
PR c++/69349 - template substitution error for flexible array members

gcc/testsuite/ChangeLog:
2016-02-02  Martin Sebor  <msebor@redhat.com>

	PR c++/69251
	PR c++/69253
	PR c++/69290
	PR c++/69277
	PR c++/69349
	* g++.dg/ext/flexarray-mangle-2.C: New test.
	* g++.dg/ext/flexarray-mangle.C: New test.
	* g++.dg/ext/flexarray-subst.C: New test.
	* g++.dg/ext/flexary11.C: New test.
	* g++.dg/ext/flexary12.C: New test.
	* g++.dg/ext/flexary13.C: New test.
	* g++.dg/ext/flexary14.C: New test.
	* g++.dg/other/dump-ada-spec-2.C: Adjust.

gcc/cp/ChangeLog:
2016-02-02  Martin Sebor  <msebor@redhat.com>

	PR c++/69251
	PR c++/69253
	PR c++/69290
	PR c++/69277
	PR c++/69349
	* class.c (walk_subobject_offsets): Avoid testing the upper bound
	of a flexible array member for equality to null.
	(find_flexarrays): Remove spurious whitespace introduced in r231665.
	(diagnose_flexarrays): Avoid checking the upper bound of arrays.
	(check_flexarrays): Same.
	* decl.c (compute_array_index_type): Avoid special case for flexible
	array members.
	(grokdeclarator): Avoid calling compute_array_index_type for flexible
	array members.
	* error.c (dump_type_suffix): Revert changes introduced in r231665
	and rendered unnecessary by the changes above.
	* pt.c (tsubst):  Same.
	* tree.c (build_ctor_subob_ref): Handle flexible array members.
	* typeck2.c (digest_init_r): Revert changes introduced in r231665.
	(process_init_constructor_array): Same.
	(process_init_constructor_record): Same.

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 45d8a24..9876197 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -4120,9 +4120,8 @@ walk_subobject_offsets (tree type,
       /* Avoid recursing into objects that are not interesting.  */
       if (!CLASS_TYPE_P (element_type)
 	  || !CLASSTYPE_CONTAINS_EMPTY_CLASS_P (element_type)
-	  || !domain
-	  /* Flexible array members have no upper bound.  */
-	  || !TYPE_MAX_VALUE (domain))
+	  /* Flexible array members have a null domain.  */
+	  || !domain)
 	return 0;
 
       /* Step through each of the elements in the array.  */
@@ -6645,7 +6644,7 @@ find_flexarrays (tree t, flexmems_t *fmem)
       for (next = fld;
 	   (next = DECL_CHAIN (next))
 	     && TREE_CODE (next) != FIELD_DECL; );
-      
+
       tree fldtype = TREE_TYPE (fld);
       if (TREE_CODE (fld) != TYPE_DECL
 	  && RECORD_OR_UNION_TYPE_P (fldtype)
@@ -6672,22 +6671,20 @@ find_flexarrays (tree t, flexmems_t *fmem)
 	  /* Remember the first non-static data member.  */
 	  if (!fmem->first)
 	    fmem->first = fld;
-	  
+
 	  /* Remember the first non-static data member after the flexible
 	     array member, if one has been found, or the zero-length array
 	     if it has been found.  */
 	  if (!fmem->after && fmem->array)
 	    fmem->after = fld;
 	}
-	    
+
       /* Skip non-arrays.  */
       if (TREE_CODE (fldtype) != ARRAY_TYPE)
 	continue;
 
       /* Determine the upper bound of the array if it has one.  */
-      tree dom = TYPE_DOMAIN (fldtype);
-
-      if (dom && TYPE_MAX_VALUE (dom))
+      if (tree dom = TYPE_DOMAIN (fldtype))
 	{
 	  if (fmem->array)
 	    {
@@ -6710,14 +6707,13 @@ find_flexarrays (tree t, flexmems_t *fmem)
 	    {
 	      /* Replace the zero-length array if it's been stored and
 		 reset the after pointer.  */
-	      dom = TYPE_DOMAIN (TREE_TYPE (fmem->array));
-	      if (dom && TYPE_MAX_VALUE (dom))
+	      if (TYPE_DOMAIN (TREE_TYPE (fmem->array)))
 		{
 		  fmem->array = fld;
 		  fmem->after = NULL_TREE;
 		}
 	    }
-	  else	
+	  else
 	    fmem->array = fld;
 	}
     }
@@ -6737,8 +6733,7 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem)
 
   const char *msg = 0;
 
-  const_tree dom = TYPE_DOMAIN (TREE_TYPE (fmem->array));
-  if (dom && TYPE_MAX_VALUE (dom))
+  if (TYPE_DOMAIN (TREE_TYPE (fmem->array)))
     {
       if (fmem->after)
 	msg = G_("zero-size array member %qD not at end of %q#T");
@@ -6770,7 +6765,7 @@ diagnose_flexarrays (tree t, const flexmems_t *fmem)
 	      inform (DECL_SOURCE_LOCATION (fmem->after),
 		      "next member %q#D declared here",
 		      fmem->after);
-	  
+
 	  inform (location_of (t), "in the definition of %q#T", t);
 	}
     }
@@ -6844,7 +6839,7 @@ check_flexarrays (tree t, flexmems_t *fmem /* = NULL */)
   find_flexarrays (t, fmem);
 
   if (fmem == &flexmems)
-    { 
+    {
       /* Issue diagnostics for invalid flexible and zero-length array members
 	 found in base classes or among the members of the current class.  */
       diagnose_flexarrays (t, fmem);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 8da87d3..2c337bc 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -8645,10 +8645,9 @@ fold_sizeof_expr (tree t)
   return r;
 }
 
-/* Given the SIZE (i.e., number of elements) in an array, compute an
-   appropriate index type for the array.  When SIZE is null, the array
-   is a flexible array member.  If non-NULL, NAME is the name of
-   the entity being declared.  */
+/* Given the SIZE (i.e., number of elements) in an array, compute
+   an appropriate index type for the array.  If non-NULL, NAME is
+   the name of the entity being declared.  */
 
 tree
 compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
@@ -8656,9 +8655,6 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
   tree itype;
   tree osize = size;
 
-  if (size == NULL_TREE)
-    return build_index_type (NULL_TREE);
-
   if (error_operand_p (size))
     return error_mark_node;
 
@@ -10967,11 +10963,10 @@ grokdeclarator (const cp_declarator *declarator,
 		error ("flexible array member in union");
 		type = error_mark_node;
 	      }
-	    else
+	    else 
 	      {
-		tree itype = compute_array_index_type (dname, NULL_TREE,
-						       tf_warning_or_error);
-		type = build_cplus_array_type (TREE_TYPE (type), itype);
+		/* Flexible array member has a null domain.  */
+		type = build_cplus_array_type (TREE_TYPE (type), NULL_TREE);
 	      }
 	  }
 
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 89a00a0..4948fab 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -875,10 +875,11 @@ dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags)
     case ARRAY_TYPE:
       pp_maybe_space (pp);
       pp_cxx_left_bracket (pp);
-      if (TYPE_DOMAIN (t) && TYPE_MAX_VALUE (TYPE_DOMAIN (t)))
+      /* C++ flexible array members have a null domain.  */
+      if (tree dtype = TYPE_DOMAIN (t))
 	{
-	  tree dtype = TYPE_DOMAIN (t);
 	  tree max = TYPE_MAX_VALUE (dtype);
+	  /* Zero-length arrays have an upper bound of SIZE_MAX.  */
 	  if (integer_all_onesp (max))
 	    pp_character (pp, '0');
 	  else if (tree_fits_shwi_p (max))
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 27dfdf86..1dea519 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -12846,14 +12846,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
       if (t == integer_type_node)
 	return t;
 
-      if (TREE_CODE (TYPE_MIN_VALUE (t)) == INTEGER_CST)
-        {
-          if (!TYPE_MAX_VALUE (t))
-            return compute_array_index_type (NULL_TREE, NULL_TREE, complain);
-          
-          if (TREE_CODE (TYPE_MAX_VALUE (t)) == INTEGER_CST)
-            return t;
-        }
+      if (TREE_CODE (TYPE_MIN_VALUE (t)) == INTEGER_CST
+          && TREE_CODE (TYPE_MAX_VALUE (t)) == INTEGER_CST)
+        return t;
 
       {
 	tree max, omax = TREE_OPERAND (TYPE_MAX_VALUE (t), 0);
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 2bf37bca..3203aca 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2586,8 +2586,19 @@ build_ctor_subob_ref (tree index, tree type, tree obj)
     obj = build_class_member_access_expr (obj, index, NULL_TREE,
 					  /*reference*/false, tf_none);
   if (obj)
-    gcc_assert (same_type_ignoring_top_level_qualifiers_p (type,
-							   TREE_TYPE (obj)));
+    {
+      tree objtype = TREE_TYPE (obj);
+      if (TREE_CODE (objtype) == ARRAY_TYPE && !TYPE_DOMAIN (objtype))
+	{
+	  /* When the destination object refers to a flexible array member
+	     verify that it matches the type of the source object except
+	     for its domain.  */
+	  gcc_assert (comptypes (type, objtype, COMPARE_REDECLARATION));
+	}
+      else
+	gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, objtype));
+    }
+
   return obj;
 }
 
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index ac2f3c3..419faa2 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1015,14 +1015,13 @@ digest_init_r (tree type, tree init, bool nested, int flags,
      them if they were present.  */
   if (code == ARRAY_TYPE)
     {
-      if (nested
-	  && (!TYPE_DOMAIN (type) || !TYPE_MAX_VALUE (TYPE_DOMAIN (type))))
+      if (nested && !TYPE_DOMAIN (type))
 	{
-	  /* Flexible array members do not have an upper bound.  */
+	  /* C++ flexible array members have a null domain.  */
 	  pedwarn (EXPR_LOC_OR_LOC (init, input_location), OPT_Wpedantic,
 		   "initialization of a flexible array member");
 	}
-      
+
       tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
       if (char_type_p (typ1)
 	  /*&& init */
@@ -1061,9 +1060,7 @@ digest_init_r (tree type, tree init, bool nested, int flags,
 	      init = copy_node (init);
 	      TREE_TYPE (init) = type;
 	    }
-	  if (TYPE_DOMAIN (type)
-	      && TYPE_MAX_VALUE (TYPE_DOMAIN (type))
-	      && TREE_CONSTANT (TYPE_SIZE (type)))
+	  if (TYPE_DOMAIN (type) && TREE_CONSTANT (TYPE_SIZE (type)))
 	    {
 	      /* Not a flexible array member.  */
 	      int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
@@ -1252,12 +1249,11 @@ process_init_constructor_array (tree type, tree init,
 
   if (TREE_CODE (type) == ARRAY_TYPE)
     {
+      /* C++ flexible array members have a null domain.  */
       tree domain = TYPE_DOMAIN (type);
-      /* Flexible array members have no upper bound.  */
-      tree maxval = domain ? TYPE_MAX_VALUE (domain) : NULL_TREE;
-      if (domain && maxval && TREE_CONSTANT (maxval))
-	len = wi::ext (wi::to_offset (maxval)
-		       - wi::to_offset (TYPE_MIN_VALUE (domain)) + 1,
+      if (domain && TREE_CONSTANT (TYPE_MAX_VALUE (domain)))
+	len = wi::ext (wi::to_offset (TYPE_MAX_VALUE (domain))
+                       - wi::to_offset (TYPE_MIN_VALUE (domain)) + 1,
 		       TYPE_PRECISION (TREE_TYPE (domain)),
 		       TYPE_SIGN (TREE_TYPE (domain))).to_uhwi ();
       else
@@ -1451,9 +1447,7 @@ process_init_constructor_record (tree type, tree init,
 	  /* Warn when some struct elements are implicitly initialized
 	     to zero.  However, avoid issuing the warning for flexible
 	     array members since they need not have any elements.  */
-	  if ((TREE_CODE (fldtype) != ARRAY_TYPE
-	       || (TYPE_DOMAIN (fldtype)
-		   && TYPE_MAX_VALUE (TYPE_DOMAIN (fldtype))))
+	  if ((TREE_CODE (fldtype) != ARRAY_TYPE || TYPE_DOMAIN (fldtype))
 	      && (complain & tf_warning)
 	      && !EMPTY_CONSTRUCTOR_P (init))
 	    warning (OPT_Wmissing_field_initializers,
diff --git a/gcc/testsuite/g++.dg/ext/flexarray-mangle-2.C b/gcc/testsuite/g++.dg/ext/flexarray-mangle-2.C
new file mode 100644
index 0000000..98bd5f5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexarray-mangle-2.C
@@ -0,0 +1,46 @@
+// PR c++/69277 - [6 Regression] ICE mangling a flexible array member
+// { dg-do compile { target c++11 } }
+
+struct A {
+  int n;
+  char a [];
+};
+
+// Declare but do not define function templates.
+template <class T>
+void foo ();
+
+template <typename T>
+void fooref (T&);
+
+// Rvalue references are a C++ 11 feature.
+template <typename T>
+void foorefref (T&&);
+
+void bar (A a)
+{
+  // Decltype is also a C++ 11 feature.
+  // Verify that decltype gets the right type and that foo is
+  // mangled correctly.
+  foo<decltype (a.a)>();
+
+  // Verify that function templates taking a reference and an rvalue
+  // references (as in PR c++/69277) are also mangled correctly.
+  fooref (a.a);
+  foorefref (a.a);
+}
+
+// In G++ versions prior to 6, flexible array members were incorrectly
+// mangled as arrays of zero elements.  Verify that flexible array
+// members are mangled correctly as arrays of an unspecified number
+// of elements.
+
+// void foo<char []>():
+// { dg-final { scan-assembler _Z3fooIA_cEvv } }
+
+// The following is derived from PR c++/69277:
+// void fooref<char []>(char (&) [])
+// { dg-final { scan-assembler _Z6foorefIA_cEvRT_ } }
+
+// void foorefref<char (&) []>(char (&) [])
+// { dg-final { scan-assembler _Z9foorefrefIRA_cEvOT_ } }
diff --git a/gcc/testsuite/g++.dg/ext/flexarray-mangle.C b/gcc/testsuite/g++.dg/ext/flexarray-mangle.C
new file mode 100644
index 0000000..d8a8c0a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexarray-mangle.C
@@ -0,0 +1,24 @@
+// PR c++/69277 - [6 Regression] ICE mangling a flexible array member
+// { dg-do compile }
+
+struct A {
+  int n;
+  char a [];
+};
+
+// Declare but do not define function templates.
+template <typename T>
+void fooref (T&);
+
+void bar (A a)
+{
+  fooref (a.a);
+}
+
+// In G++ versions prior to 6, flexible array members were incorrectly
+// mangled as arrays of zero elements.  Verify that flexible array
+// members are mangled correctly as arrays of an unspecified number
+// of elements.
+
+// void fooref<char []>(char (&) [])
+// { dg-final { scan-assembler _Z6foorefIA_cEvRT_ } }
diff --git a/gcc/testsuite/g++.dg/ext/flexarray-subst.C b/gcc/testsuite/g++.dg/ext/flexarray-subst.C
new file mode 100644
index 0000000..f644636
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexarray-subst.C
@@ -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);
+}
diff --git a/gcc/testsuite/g++.dg/ext/flexary11.C b/gcc/testsuite/g++.dg/ext/flexary11.C
new file mode 100644
index 0000000..5bf774f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexary11.C
@@ -0,0 +1,19 @@
+// PR c++/69253 - [6 Regression] g++ ICE at -O0 on x86_64-linux-gnu
+//                in "cxx_incomplete_type_diagnostic"
+// { dg-do compile }
+
+struct A {
+  int n;
+  char a [];
+};
+
+void f ()
+{
+  // Compound literals and flexible array members are G++ extensions
+  // accepted for compatibility with C and GCC.
+
+  // The following use of a flexible array member in a compound literal
+  // is invalid in C and rejected by GCC in C mode and so it's also
+  // rejected in C++ mode.
+  (struct A){ 1, "" };   // { dg-error "forbids compound-literals|initialization of a flexible array member|invalid use of a flexible array member" }
+}
diff --git a/gcc/testsuite/g++.dg/ext/flexary12.C b/gcc/testsuite/g++.dg/ext/flexary12.C
new file mode 100644
index 0000000..3d8c805
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexary12.C
@@ -0,0 +1,63 @@
+// PR c++/69290 - [6 Regression] g++ ICE on invalid initialization
+//     of a flexible array member
+// { dg-do compile }
+
+// Suppress pedantic errors about initialization of a flexible array member.
+// { dg-options "-Wno-pedantic" }
+
+struct A {
+  int a [];  // { dg-error "flexible array member .A::a. in an otherwise empty .struct A." }
+};
+
+void f1 ()
+{
+  // This is the meat of the test from c++/69290:
+  struct A a
+    = { "c" };   // { dg-error "invalid conversion from .const char\\*. to .int." }
+
+  (void)&a;
+}
+
+
+// Exercise other forms of invalid initialization besides the one in the bug.
+struct B {
+  int n;
+  int a [];
+};
+
+void f2 ()
+{
+  struct B b1
+    = { 0, "c" };   // { dg-error "invalid conversion from .const char\\*. to .int." }
+
+  (void)&b1;
+
+  const char s[] = "c";
+  struct B b2
+    = { 0, s };   // { dg-error "invalid conversion from .const char\\*. to .int." }
+
+  (void)&b2;
+}
+
+struct D {
+  int a [];  // { dg-error "flexible array member .D::a. in an otherwise empty .struct D." }
+  D ();
+};
+
+D::D ():
+  a ("c")   // { dg-error "incompatible types in assignment of .const char \\\[2\\\]. to .int \\\[\\\]." }
+{ }
+
+
+template <class T>
+struct C {
+  T a [];  // { dg-error "flexible array member" }
+};
+
+void f3 ()
+{
+  struct C<double> cd
+    = { "c" };   // { dg-error "cannot convert .const char\\*. to .double." }
+
+  (void)&cd;
+}
diff --git a/gcc/testsuite/g++.dg/ext/flexary13.C b/gcc/testsuite/g++.dg/ext/flexary13.C
new file mode 100644
index 0000000..462ed65
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexary13.C
@@ -0,0 +1,64 @@
+// { dg-do compile }
+// { dg-options -Wno-pedantic }
+
+#define STR(s) #s
+#define ASSERT(exp) \
+  ((exp) ? (void)0 : (void)(__builtin_printf ("%s:%i: assertion %s failed\n", \
+                     __FILE__, __LINE__, STR(exp)), \
+                      __builtin_abort ()))
+
+struct Ax { int n, a[]; };
+struct AAx { int i; Ax ax; };
+
+int i = 12345678;
+
+int main ()
+{
+  {
+    Ax s = { 0 };
+    ASSERT (s.n == 0);
+  }
+  {
+    Ax s =
+      { 0, { } };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n == 0);
+  }
+  {
+    Ax s =
+      { 1, { 2 } };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n == 1 && s.a [0] == 2);
+  }
+  {
+    Ax s =
+      { 2, { 3, 4 } }; // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n = 2 && s.a [0] == 3 && s.a [1] == 4);
+  }
+  {
+    Ax s =
+      { 123, i };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n == 123 && s.a [0] == i);
+  }
+  {
+    Ax s =
+      { 456, { i } }; // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n == 456 && s.a [0] == i);
+  }
+  {
+    int j = i + 1, k = j + 1;
+    Ax s =
+      { 3, { i, j, k } }; // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.n == 3 && s.a [0] == i && s.a [1] == j && s.a [2] == k);
+  }
+
+  {
+    AAx s =
+      { 1, { 2 } };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.i == 1 && s.ax.n == 2);
+  }
+
+  {
+    AAx s =
+      { 1, { 2, { 3 } } };   // dg-warning "initialization of a flexible array member" }
+    ASSERT (s.i == 1 && s.ax.n == 2 && s.ax.a [0] == 3);
+  }
+}
diff --git a/gcc/testsuite/g++.dg/ext/flexary14.C b/gcc/testsuite/g++.dg/ext/flexary14.C
new file mode 100644
index 0000000..7365357
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/flexary14.C
@@ -0,0 +1,17 @@
+// PR c++/69349 - template substitution error for flexible array members
+// { dg-do compile }
+
+template <class>
+struct A;
+
+template <class T>
+struct A<T[]> { typedef int X; };
+
+template <class T> int foo (T&, typename A<T>::X = 0) { return 0; }
+
+struct B { int n, a[]; };
+
+void bar (B *b)
+{
+    foo (b->a);
+}
diff --git a/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C b/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C
index d1af7e0..608b5be 100644
--- a/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C
+++ b/gcc/testsuite/g++.dg/other/dump-ada-spec-2.C
@@ -7,5 +7,5 @@ struct S
   __extension__ unsigned char data[];
 };
 
-/* { dg-final { scan-ada-spec "array \\(0 .. 0\\)" } } */
+/* { dg-final { scan-ada-spec "array \\(size_t\\)" } } */
 /* { dg-final { cleanup-ada-spec } } */

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-02-03  1:21         ` Martin Sebor
@ 2016-02-03 18:47           ` Jason Merrill
  2016-02-04  5:23             ` Martin Sebor
  2016-02-04 11:05           ` Jakub Jelinek
  1 sibling, 1 reply; 16+ messages in thread
From: Jason Merrill @ 2016-02-03 18:47 UTC (permalink / raw)
  To: Martin Sebor, Gcc Patch List

On 02/02/2016 08:21 PM, Martin Sebor wrote:
> On 02/02/2016 05:28 AM, Jason Merrill wrote:
>> On 01/25/2016 05:55 PM, Martin Sebor wrote:
>>> The downside of this approach is that it prevents everything but
>>> the front end from distinguishing flexible array members from
>>> arrays of unspecified or unknown bounds.  The immediate impact
>>> is that prevents us from maintaining ABI compatibility with GCC
>>> 5 (with -fabi-version=9) and from diagnosing the mangling change.
>>> This means should we decide to adopt this approach, the final
>>> version of the patch for c++/69277 mentioned above that's still
>>> pending approval will need to be tweaked to have the ABI checks
>>> removed.
>>
>> That's unfortunate, but I think acceptable.
>>
>>>     * decl.c (compute_array_index_type): Return null for flexible array
>>>     members.
>>
>> Instead of this, I would think we can remove the calls to
>> compute_array_index_type added by your earlier patch, as well as many
>> other changes from that patch to handle null TYPE_MAX_VALUE.
>
> Yes, that's possible but it didn't seem essential at this stage.
> I wanted to make only conservative changes to avoid any further
> fallout.  I also wasn't sure whether the ABI issue above would
> make this approach unviable.

I guess my sense of conservatism is different from yours: I think 
removing recent changes is conservative in that it minimizes the change 
from previous versions of the compiler.

>>>     * tree.c (array_of_runtime_bound_p): Handle gracefully array types
>>>     with null TYPE_MAX_VALUE.
>>
>> This seems unneeded.
>>
>>>     (build_ctor_subob_ref): Loosen debug checking to handle flexible
>>>     array members.
>>
>> And this shouldn't need the TYPE_MAX_VALUE check.
>
> I went ahead and made the requested changes.  They might seem
> perfectly innocuous to you but the removal of the tests for
> TYPE_MAX_VALUE(t) being null makes me nervous at this stage.
> I'm not nearly comfortable enough with the code to be confident
> that they're all 100% safe.  I defer to your better judgment
> on this.

It was impossible to have null TYPE_MAX_VALUE until you introduced that 
in compute_array_index_type, and thus we didn't test for it; if we 
aren't doing that anymore I can't imagine where it would come from now.

> @@ -4120,9 +4120,8 @@ walk_subobject_offsets (tree type,
> -	  || !domain
> -	  /* Flexible array members have no upper bound.  */
> -	  || !TYPE_MAX_VALUE (domain))
> +	  /* Flexible array members have a null domain.  */
> +	  || !domain)

With this patch flexible array members are a special case of array of 
unknown bound, so I don't think we need to call them out in a comment here.

> @@ -875,10 +875,11 @@ dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags)
> -      if (TYPE_DOMAIN (t) && TYPE_MAX_VALUE (TYPE_DOMAIN (t)))
> +      /* C++ flexible array members have a null domain.  */
> +      if (tree dtype = TYPE_DOMAIN (t))

Likewise.

OK with these two comments removed.

Jason

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-02-03 18:47           ` Jason Merrill
@ 2016-02-04  5:23             ` Martin Sebor
  0 siblings, 0 replies; 16+ messages in thread
From: Martin Sebor @ 2016-02-04  5:23 UTC (permalink / raw)
  To: Jason Merrill, Gcc Patch List

I've committed the patch with the changes below.  Just to clarify
my concern (since put to rest):

> It was impossible to have null TYPE_MAX_VALUE until you introduced that
> in compute_array_index_type, and thus we didn't test for it; if we
> aren't doing that anymore I can't imagine where it would come from now.

The patch with the TYPE_MAX_VALUE checks has been in place for
several weeks.  Although unlikely, it seemed conceivable that
a change could have gone in since then that has introduced
a dependency on the domain being non-null for flexible array
members in some corner case.  But you know the code far better
than me (and the changes being committed) so I trust you when
you say the removal is safe.

Martin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-02-03  1:21         ` Martin Sebor
  2016-02-03 18:47           ` Jason Merrill
@ 2016-02-04 11:05           ` Jakub Jelinek
  2016-02-04 15:33             ` Martin Sebor
  1 sibling, 1 reply; 16+ messages in thread
From: Jakub Jelinek @ 2016-02-04 11:05 UTC (permalink / raw)
  To: Martin Sebor; +Cc: Jason Merrill, Gcc Patch List

On Tue, Feb 02, 2016 at 06:21:04PM -0700, Martin Sebor wrote:
> gcc/cp/ChangeLog:
> 2016-02-02  Martin Sebor  <msebor@redhat.com>
> 
> 	PR c++/69251
> 	PR c++/69253
> 	PR c++/69290
> 	PR c++/69277
> 	PR c++/69349
> 	* class.c (walk_subobject_offsets): Avoid testing the upper bound
> 	of a flexible array member for equality to null.
> 	(find_flexarrays): Remove spurious whitespace introduced in r231665.
> 	(diagnose_flexarrays): Avoid checking the upper bound of arrays.
> 	(check_flexarrays): Same.

This broke bootstrap, I've committed following fix as obvious:

2016-02-04  Jakub Jelinek  <jakub@redhat.com>

	* class.c (find_flexarrays): Don't declare dom variable.
	(diagnose_flexarray): Likewise.

--- gcc/cp/class.c.jj	2016-02-04 10:00:26.000000000 +0100
+++ gcc/cp/class.c	2016-02-04 12:01:38.341794819 +0100
@@ -6683,7 +6683,7 @@ find_flexarrays (tree t, flexmems_t *fme
 	continue;
 
       /* Determine the upper bound of the array if it has one.  */
-      if (tree dom = TYPE_DOMAIN (fldtype))
+      if (TYPE_DOMAIN (fldtype))
 	{
 	  if (fmem->array)
 	    {
@@ -6694,7 +6694,7 @@ find_flexarrays (tree t, flexmems_t *fme
 	      if (!fmem->after)
 		fmem->after = fld;
 	    }
-	  else if (integer_all_onesp (TYPE_MAX_VALUE (dom)))
+	  else if (integer_all_onesp (TYPE_MAX_VALUE (TYPE_DOMAIN (fldtype))))
 	    /* Remember the first zero-length array unless a flexible array
 	       member has already been seen.  */
 	    fmem->array = fld;
@@ -6732,7 +6732,7 @@ diagnose_flexarrays (tree t, const flexm
 
   const char *msg = 0;
 
-  if (const_tree dom = TYPE_DOMAIN (TREE_TYPE (fmem->array)))
+  if (TYPE_DOMAIN (TREE_TYPE (fmem->array)))
     {
       if (fmem->after)
 	msg = G_("zero-size array member %qD not at end of %q#T");


	Jakub

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-02-04 11:05           ` Jakub Jelinek
@ 2016-02-04 15:33             ` Martin Sebor
  2016-02-04 16:38               ` Jason Merrill
  2016-02-04 17:42               ` Mike Stump
  0 siblings, 2 replies; 16+ messages in thread
From: Martin Sebor @ 2016-02-04 15:33 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Jason Merrill, Gcc Patch List

On 02/04/2016 04:05 AM, Jakub Jelinek wrote:
> On Tue, Feb 02, 2016 at 06:21:04PM -0700, Martin Sebor wrote:
>> gcc/cp/ChangeLog:
>> 2016-02-02  Martin Sebor  <msebor@redhat.com>
>>
>> 	PR c++/69251
>> 	PR c++/69253
>> 	PR c++/69290
>> 	PR c++/69277
>> 	PR c++/69349
>> 	* class.c (walk_subobject_offsets): Avoid testing the upper bound
>> 	of a flexible array member for equality to null.
>> 	(find_flexarrays): Remove spurious whitespace introduced in r231665.
>> 	(diagnose_flexarrays): Avoid checking the upper bound of arrays.
>> 	(check_flexarrays): Same.
>
> This broke bootstrap, I've committed following fix as obvious:

Sorry. I fixed it twice in my own builds but then as I finally
committed the patch I must have applied the wrong version of it.

FWIW, I keep having trouble with the repository.  Git doesn't
work to check things in at all and I have only one svn repository
that does.  The other one keeps giving me the error below, so
every time I have to retest a patch I end up copying it from one
machine to another, which is obviously error prone.

$ svn switch --relocate svn://gcc.gnu.org/svn/gcc 
svn+ssh://msebor@gcc.gnu.org/svn/gcc
svn: E170013: Unable to connect to a repository at URL 
'svn+ssh://msebor@gcc.gnu.org/svn/gcc/trunk'
svn: E210002: To better debug SSH connection problems, remove the -q 
option from 'ssh' in the [tunnels] section of your Subversion 
configuration file.
svn: E210002: Network connection closed unexpectedly

Martin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-02-04 15:33             ` Martin Sebor
@ 2016-02-04 16:38               ` Jason Merrill
  2016-02-04 17:03                 ` Martin Sebor
  2016-02-04 17:42               ` Mike Stump
  1 sibling, 1 reply; 16+ messages in thread
From: Jason Merrill @ 2016-02-04 16:38 UTC (permalink / raw)
  To: Martin Sebor, Jakub Jelinek; +Cc: Gcc Patch List

On 02/04/2016 10:32 AM, Martin Sebor wrote:
> FWIW, I keep having trouble with the repository.  Git doesn't
> work to check things in at all

The instructions here aren't working for you?

https://gcc.gnu.org/wiki/GitMirror#Commit_upstream_.28git-svn.29

> and I have only one svn repository
> that does.  The other one keeps giving me the error below, so
> every time I have to retest a patch I end up copying it from one
> machine to another, which is obviously error prone.
>
> $ svn switch --relocate svn://gcc.gnu.org/svn/gcc
> svn+ssh://msebor@gcc.gnu.org/svn/gcc
> svn: E170013: Unable to connect to a repository at URL
> 'svn+ssh://msebor@gcc.gnu.org/svn/gcc/trunk'
> svn: E210002: To better debug SSH connection problems, remove the -q
> option from 'ssh' in the [tunnels] section of your Subversion
> configuration file.
> svn: E210002: Network connection closed unexpectedly

Seems like you have ssh setup issues.

Jason

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-02-04 16:38               ` Jason Merrill
@ 2016-02-04 17:03                 ` Martin Sebor
  0 siblings, 0 replies; 16+ messages in thread
From: Martin Sebor @ 2016-02-04 17:03 UTC (permalink / raw)
  To: Jason Merrill, Jakub Jelinek; +Cc: Gcc Patch List

On 02/04/2016 09:38 AM, Jason Merrill wrote:
> On 02/04/2016 10:32 AM, Martin Sebor wrote:
>> FWIW, I keep having trouble with the repository.  Git doesn't
>> work to check things in at all
>
> The instructions here aren't working for you?
>
> https://gcc.gnu.org/wiki/GitMirror#Commit_upstream_.28git-svn.29

It doesn't (or didn't the last time I tried).  I don't recall
the error but ever since my last attempt my local copy is in
a state where each time I pull I get asked to merge.  When I
try to run git svn rebase the command never finishes.

I use Git to check out code and to manage my local branches
(usually one per bug) but when it comes time to test on another
machine I create a patch, copy it to the other machine, apply
it, test it, tweak it, and then copy it back, apply it to the
SVN copy, retest it lightly, and then check it in.  That's
obviously too many steps where things can and do go wrong.
I just haven't found a good way to avoid them.  IIUC, with
Git, I should be able to share/clone my work branch across
all the machines I test on, and also be able to push the final
changes to the origin.  I just haven't figured out a way to do
it.


>> and I have only one svn repository
>> that does.  The other one keeps giving me the error below, so
>> every time I have to retest a patch I end up copying it from one
>> machine to another, which is obviously error prone.
>>
>> $ svn switch --relocate svn://gcc.gnu.org/svn/gcc
>> svn+ssh://msebor@gcc.gnu.org/svn/gcc
>> svn: E170013: Unable to connect to a repository at URL
>> 'svn+ssh://msebor@gcc.gnu.org/svn/gcc/trunk'
>> svn: E210002: To better debug SSH connection problems, remove the -q
>> option from 'ssh' in the [tunnels] section of your Subversion
>> configuration file.
>> svn: E210002: Network connection closed unexpectedly
>
> Seems like you have ssh setup issues.

Right.  I just figured it out. I had to generate a new pair of ssh
keys on the machine and upload the public key from the machine that
can connect by running

   ssh msebor@gcc.gnu.org append-key < new-keyfile

There's a mention of doing this in the "Tips&Tricks around your
account" section way at the bottom of the Read-write SVN access
page but it's not explicit enough for my dense brain.

Martin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-02-04 15:33             ` Martin Sebor
  2016-02-04 16:38               ` Jason Merrill
@ 2016-02-04 17:42               ` Mike Stump
  2016-02-04 18:23                 ` Martin Sebor
  1 sibling, 1 reply; 16+ messages in thread
From: Mike Stump @ 2016-02-04 17:42 UTC (permalink / raw)
  To: Martin Sebor; +Cc: Gcc Patch List

On Feb 4, 2016, at 7:32 AM, Martin Sebor <msebor@gmail.com> wrote:
> FWIW, I keep having trouble with the repository.

> $ svn switch --relocate svn://gcc.gnu.org/svn/gcc svn+ssh://msebor@gcc.gnu.org/svn/gcc
> svn: E170013: Unable to connect to a repository at URL 'svn+ssh://msebor@gcc.gnu.org/svn/gcc/trunk'
> svn: E210002: To better debug SSH connection problems, remove the -q option from 'ssh' in the [tunnels] section of your Subversion configuration file.
> svn: E210002: Network connection closed unexpectedly

You forgot to do:

  ssh -oPubkeyAcceptedKeyTypes=+ssh-dss YOUR_ID@gcc.gnu.org append-key <~/.ssh/id_rsa.pub

Isn’t that obvious?  Be sure you have an id_rsa key first, of course.  Once you do this, then, you can use svn as normal.

If you want to double check first before doing the above, you can add:

ssh = /usr/bin/ssh -oPubkeyAcceptedKeyTypes=+ssh-dss

right after:

  [tunnels]

in ~/.subversion/config, and then do an svn up ChangeLog, and see if it works.  If it does, then you will want to do the first command.  Once you do the first, you will then want to comment out the line you just added to the ~/.subversion/config file, if you added it.  If it does not work, you will want to use:

ssh = /usr/bin/ssh -v

and then have an expert read through the 50 lines of goop and figure it out for you.  If you use some other ssh, and not the one in /usr/bin, you will want to update the full path to ssh above to use the one you actually use.  For example, I happen to use:

ssh = /opt/local/bin/ssh

If you do email the ssh -v output, don’t send to the full list, you can send it to me privately, if you don’t know where to go from there.

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-02-04 17:42               ` Mike Stump
@ 2016-02-04 18:23                 ` Martin Sebor
  2016-02-04 19:35                   ` Mike Stump
  0 siblings, 1 reply; 16+ messages in thread
From: Martin Sebor @ 2016-02-04 18:23 UTC (permalink / raw)
  To: Mike Stump; +Cc: Gcc Patch List

On 02/04/2016 10:39 AM, Mike Stump wrote:
> On Feb 4, 2016, at 7:32 AM, Martin Sebor <msebor@gmail.com> wrote:
>> FWIW, I keep having trouble with the repository.
>
>> $ svn switch --relocate svn://gcc.gnu.org/svn/gcc svn+ssh://msebor@gcc.gnu.org/svn/gcc
>> svn: E170013: Unable to connect to a repository at URL 'svn+ssh://msebor@gcc.gnu.org/svn/gcc/trunk'
>> svn: E210002: To better debug SSH connection problems, remove the -q option from 'ssh' in the [tunnels] section of your Subversion configuration file.
>> svn: E210002: Network connection closed unexpectedly
>
> You forgot to do:
>
>    ssh -oPubkeyAcceptedKeyTypes=+ssh-dss YOUR_ID@gcc.gnu.org append-key <~/.ssh/id_rsa.pub
>
> IsnÂ’t that obvious?  Be sure you have an id_rsa key first, of course.  Once you do this, then, you can use svn as normal.

Yes, I sure did!  (But no, it wasn't obvious to me.  I recently
upgraded this machine and did it differently than I normally do,
so things are, well, different than I expected.  FWIW, it would
be nice to mention this as the first step at the top in the
Authenticated access section: "remember to upload your public
ssh key before accessing SVN via SSH! Doh!")

>
> If you want to double check first before doing the above, you can add:
>
> ssh = /usr/bin/ssh -oPubkeyAcceptedKeyTypes=+ssh-dss
>
> right after:
>
>    [tunnels]
>
> in ~/.subversion/config, and then do an svn up ChangeLog, and see if it works.  If it does, then you will want to do the first command.  Once you do the first, you will then want to comment out the line you just added to the ~/.subversion/config file, if you added it.  If it does not work, you will want to use:
>
> ssh = /usr/bin/ssh -v
>
> and then have an expert read through the 50 lines of goop and figure it out for you.  If you use some other ssh, and not the one in /usr/bin, you will want to update the full path to ssh above to use the one you actually use.  For example, I happen to use:
>
> ssh = /opt/local/bin/ssh
>
> If you do email the ssh -v output, donÂ’t send to the full list, you can send it to me privately, if you donÂ’t know where to go from there.

Thanks. I have Subversion working now.  Git's another story.

Martin



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member
  2016-02-04 18:23                 ` Martin Sebor
@ 2016-02-04 19:35                   ` Mike Stump
  0 siblings, 0 replies; 16+ messages in thread
From: Mike Stump @ 2016-02-04 19:35 UTC (permalink / raw)
  To: Martin Sebor; +Cc: Gcc Patch List

On Feb 4, 2016, at 10:23 AM, Martin Sebor <msebor@gmail.com> wrote:
> Yes, I sure did!  (But no, it wasn't obvious to me.  I recently
> upgraded this machine and did it differently than I normally do,
> so things are, well, different than I expected.  FWIW, it would
> be nice to mention this as the first step at the top in the
> Authenticated access section: "remember to upload your public
> ssh key before accessing SVN via SSH! Doh!”)

But, you can’t upload a key without first uploading a key.  This whole thing is because ssh removed an authentication method, and that is the method that lots of people use.  This happens once every 10 or 20 years, and isn’t a normal occurrence.

^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2016-02-04 19:35 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-19  2:30 [PATCH] fix #69251 - [6 Regression] ICE in unify_array_domain on a flexible array member Martin Sebor
2016-01-21 23:19 ` Jason Merrill
2016-01-21 23:32   ` Martin Sebor
2016-01-25 16:55     ` Martin Sebor
2016-02-01  2:01       ` PING " Martin Sebor
2016-02-02 12:28       ` Jason Merrill
2016-02-03  1:21         ` Martin Sebor
2016-02-03 18:47           ` Jason Merrill
2016-02-04  5:23             ` Martin Sebor
2016-02-04 11:05           ` Jakub Jelinek
2016-02-04 15:33             ` Martin Sebor
2016-02-04 16:38               ` Jason Merrill
2016-02-04 17:03                 ` Martin Sebor
2016-02-04 17:42               ` Mike Stump
2016-02-04 18:23                 ` Martin Sebor
2016-02-04 19:35                   ` Mike Stump

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).