GCC 10 has changed the formatting of zero-length arrays in diagnostics
to include their bound, but it also inadvertently added the zero bound
to flexible array members which are confusingly represented differently
between the C and C++ front ends.

The attached patch corrects the problem so both zero-length arrays and
flexible array members are formatted consistently by both front ends
(i.e., as T[0] and T[]).

Tested on x86_64-linux.

Martin
PR c/92326 - wrong bound in zero-length array diagnostics

gcc/c-family/ChangeLog:

	PR c/92326
	* c-pretty-print.c (c_pretty_printer::direct_abstract_declarator): Avoid
	printing array bound for flexible array members.

gcc/testsuite/ChangeLog:

	PR c/92326
	* c-c++-common/Warray-bounds-8.c: New test.
	* gcc.dg/Warray-bounds-46.c: Adjust expected format of flexible array
	memebrs in diagnostics.
	* gcc.dg/Warray-bounds-49.c: Same.

diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index 0e4303f1a49..eccb63096fd 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -593,7 +593,9 @@ c_pretty_printer::direct_abstract_declarator (tree t)
 		expression (fold_build2 (PLUS_EXPR, type, maxval,
 					 build_int_cst (type, 1)));
 	    }
-	  else
+	  else if (TYPE_SIZE (t))
+	    /* Print zero for zero-length arrays but not for flexible
+	       array members whose TYPE_SIZE is null.  */
 	    pp_string (this, "0");
 	}
       pp_c_right_bracket (this);
diff --git a/gcc/testsuite/c-c++-common/Warray-bounds-8.c b/gcc/testsuite/c-c++-common/Warray-bounds-8.c
new file mode 100644
index 00000000000..64202ddd5df
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Warray-bounds-8.c
@@ -0,0 +1,22 @@
+/* PR c/92326 - wrong bound in zero-length array diagnostics
+   { dg-do compile }
+   { dg-options "-O2 -Wall" } */
+
+extern int a0[0];
+extern int ax[];
+
+void warn_global_array (void)
+{
+  a0[0] = 0;        // { dg-warning "array bounds of 'int *\\\[0]'" }
+  ax[-1] = 0;       // { dg-warning "array bounds of 'int *\\\[]'" }
+}
+
+
+struct S0 { int n, a0[0]; } s0;
+struct Sx { int n, ax[]; } sx = { 0 };
+
+void warn_member_array (void)
+{
+  s0.a0[0] = 0;     // { dg-warning "array bounds of 'int *\\\[0]'" }
+  sx.ax[0] = 0;     // { dg-warning "array bounds of 'int *\\\[]'" }
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-46.c b/gcc/testsuite/gcc.dg/Warray-bounds-46.c
index 74e78cbdbe8..9078c6f5998 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-46.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-46.c
@@ -95,13 +95,13 @@ void strcpy_global_array (void)
   /* GMA2 is external but because it's an array its definition in another
      translation unit may not provide an initializer for the flexible array
      member.  Verify that a warning is issued for access to it.  */
-  T (gma2[0].ax, 1);      // { dg-warning "'strcpy' offset \\\[157, 158] from the object at 'gma2' is out of the bounds of referenced subobject 'ax' with type 'char\\\[0]' at offset 157" }
-  T (gma2[0].ax, 7);      // { dg-warning "'strcpy' offset \\\[157, 164] from the object at 'gma2' is out of the bounds of referenced subobject 'ax' with type 'char\\\[0]' at offset 157" }
+  T (gma2[0].ax, 1);      // { dg-warning "'strcpy' offset \\\[157, 158] from the object at 'gma2' is out of the bounds of referenced subobject 'ax' with type 'char\\\[]' at offset 157" }
+  T (gma2[0].ax, 7);      // { dg-warning "'strcpy' offset \\\[157, 164] from the object at 'gma2' is out of the bounds of referenced subobject 'ax' with type 'char\\\[]' at offset 157" }
 
-  /* IGMA_ is internal and provides on definition for the flexible array
-     member.  Verify that a warnin is issued for out-of-bounds accesses
+  /* IGMA2_ is internal and provides no definition for the flexible array
+     member.  Verify that a warning is issued for out-of-bounds accesses
      to it.  */
-  T (igma2_[0].ax, 1);    // { dg-warning "'strcpy' offset \\\[157, 158] from the object at 'igma2_' is out of the bounds of referenced subobject 'ax' with type 'char\\\[0]' at offset 157" }
+  T (igma2_[0].ax, 1);    // { dg-warning "'strcpy' offset \\\[157, 158] from the object at 'igma2_' is out of the bounds of referenced subobject 'ax' with type 'char\\\[]' at offset 157" }
 
   T (igma_3.ax, 0);
   T (igma_3.ax, 1);
@@ -134,7 +134,7 @@ void strcpy_local (void)
   T (lma.a17, 16);
   T (lma.a17, 17);        // { dg-warning "'strcpy' offset 157 from the object at 'lma' is out of the bounds of referenced subobject 'a17' with type 'char\\\[17]' at offset 140" }
 
-  T (lma.ax, 0);          // { dg-warning "'strcpy' offset 157 from the object at 'lma' is out of the bounds of referenced subobject 'ax' with type 'char\\\[0]' at offset 157" }
+  T (lma.ax, 0);          // { dg-warning "'strcpy' offset 157 from the object at 'lma' is out of the bounds of referenced subobject 'ax' with type 'char\\\[]' at offset 157" }
 }
 
 
@@ -191,11 +191,11 @@ void strcpy_ref (struct MA17 *pma)
      array.  The warning assumes that PMA doesn't point to the last element
      of the array which could in theory have nonzero elements without
      overlapping other objects.  */
-  T (pma[1].ax, 0);       // { dg-warning "'strcpy' offset 314 from the object at 'pma' is out of the bounds of referenced subobject 'ax' with type 'char\\\[0]' at offset 314" }
-  T ((pma + 1)->ax, 1);   // { dg-warning "'strcpy' offset \\\[314, 315] from the object at 'pma' is out of the bounds of referenced subobject 'ax' with type 'char\\\[0]' at offset 314" }
-  T ((pma + 1)[1].ax, 2); // { dg-warning "'strcpy' offset \\\[471, 473] from the object at 'pma' is out of the bounds of referenced subobject 'ax' with type 'char\\\[0]' at offset 471" }
-  T ((*(pma + 2)).ax, 2); // { dg-warning "'strcpy' offset \\\[471, 473] from the object at 'pma' is out of the bounds of referenced subobject 'ax' with type 'char\\\[0]' at offset 471" }
-  T (pma[3].ax, 9);       // { dg-warning "'strcpy' offset \\\[628, 637] from the object at 'pma' is out of the bounds of referenced subobject 'ax' with type 'char\\\[0]' at offset 628" }
+  T (pma[1].ax, 0);       // { dg-warning "'strcpy' offset 314 from the object at 'pma' is out of the bounds of referenced subobject 'ax' with type 'char\\\[]' at offset 314" }
+  T ((pma + 1)->ax, 1);   // { dg-warning "'strcpy' offset \\\[314, 315] from the object at 'pma' is out of the bounds of referenced subobject 'ax' with type 'char\\\[]' at offset 314" }
+  T ((pma + 1)[1].ax, 2); // { dg-warning "'strcpy' offset \\\[471, 473] from the object at 'pma' is out of the bounds of referenced subobject 'ax' with type 'char\\\[]' at offset 471" }
+  T ((*(pma + 2)).ax, 2); // { dg-warning "'strcpy' offset \\\[471, 473] from the object at 'pma' is out of the bounds of referenced subobject 'ax' with type 'char\\\[]' at offset 471" }
+  T (pma[3].ax, 9);       // { dg-warning "'strcpy' offset \\\[628, 637] from the object at 'pma' is out of the bounds of referenced subobject 'ax' with type 'char\\\[]' at offset 628" }
 
   T (pma[-1].a1, 0);
   T (pma[-1].a1, 1);      // { dg-warning "'strcpy' offset -152 from the object at 'pma' is out of the bounds of referenced subobject 'a1' with type 'char\\\[1]' at offset -153" }
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-49.c b/gcc/testsuite/gcc.dg/Warray-bounds-49.c
index 7a847acf4d2..f271dd526b8 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-49.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-49.c
@@ -17,7 +17,7 @@ void test_a0 (void)
   // The first three elements fit in the tail padding.
   a0.a2[0] = 0; a0.a2[1] = 1; a0.a2[2] = 2;
 
-  a0.a2[3] = 3;     // { dg-warning "array subscript 3 is above array bounds of 'short int\\\[0]'" }
+  a0.a2[3] = 3;     // { dg-warning "array subscript 3 is above array bounds of 'short int\\\[]'" }
 }
 
 
@@ -27,7 +27,7 @@ void test_a1 (void)
 {
   a1.a2[0] = 0; a1.a2[1] = 1; a1.a2[2] = 2;
 
-  a1.a2[3] = 3;     // { dg-warning "array subscript 3 is above array bounds of 'short int\\\[0]'" }
+  a1.a2[3] = 3;     // { dg-warning "array subscript 3 is above array bounds of 'short int\\\[]'" }
 }
 
 
@@ -37,7 +37,7 @@ void test_a2 (void)
 {
   a2.a2[0] = 0; a2.a2[1] = 1; a2.a2[2] = 2;
 
-  a2.a2[3] = 3;     // { dg-warning "array subscript 3 is above array bounds of 'short int\\\[0]'" }
+  a2.a2[3] = 3;     // { dg-warning "array subscript 3 is above array bounds of 'short int\\\[]'" }
 }
 
 
@@ -47,7 +47,7 @@ void test_a3 (void)
 {
   a3.a2[0] = 0; a3.a2[1] = 1; a3.a2[2] = 2;
 
-  a3.a2[3] = 3;     // { dg-warning "array subscript 3 is above array bounds of 'short int\\\[0]'" }
+  a3.a2[3] = 3;     // { dg-warning "array subscript 3 is above array bounds of 'short int\\\[]'" }
 }
 
 
@@ -57,7 +57,7 @@ void test_a4 (void)
 {
   a4.a2[0] = 0; a4.a2[1] = 1; a4.a2[2] = 2; a4.a2[3] = 3;
 
-  a4.a2[4] = 4;     // { dg-warning "array subscript 4 is above array bounds of 'short int\\\[0]'" }
+  a4.a2[4] = 4;     // { dg-warning "array subscript 4 is above array bounds of 'short int\\\[]'" }
 }
 
 
@@ -67,7 +67,7 @@ void test_a5 (void)
 {
   a5.a2[0] = 0; a5.a2[1] = 1; a5.a2[2] = 2; a5.a2[3] = 3; a5.a2[4] = 4;
 
-  a5.a2[5] = 5;     // { dg-warning "array subscript 5 is above array bounds of 'short int\\\[0]'" }
+  a5.a2[5] = 5;     // { dg-warning "array subscript 5 is above array bounds of 'short int\\\[]'" }
 }
 
 
@@ -78,7 +78,7 @@ void test_a6 (void)
   a6.a2[0] = 0; a6.a2[1] = 1; a6.a2[2] = 2; a6.a2[3] = 3; a6.a2[4] = 4;
   a6.a2[5] = 5;
 
-  a6.a2[6] = 6;     // { dg-warning "array subscript 6 is above array bounds of 'short int\\\[0]'" }
+  a6.a2[6] = 6;     // { dg-warning "array subscript 6 is above array bounds of 'short int\\\[]'" }
 }
 
 
@@ -89,7 +89,7 @@ void test_a7 (void)
   a7.a2[0] = 0; a7.a2[1] = 1; a7.a2[2] = 2; a7.a2[3] = 3; a7.a2[4] = 4;
   a7.a2[5] = 5; a7.a2[5] = 5; a7.a2[6] = 6;
 
-  a7.a2[7] = 7;     // { dg-warning "array subscript 7 is above array bounds of 'short int\\\[0]'" }
+  a7.a2[7] = 7;     // { dg-warning "array subscript 7 is above array bounds of 'short int\\\[]'" }
 }
 
 
@@ -100,7 +100,7 @@ void test_a8 (void)
   a8.a2[0] = 0; a8.a2[1] = 1; a8.a2[2] = 2; a8.a2[3] = 3; a8.a2[4] = 4;
   a8.a2[5] = 5; a8.a2[5] = 5; a8.a2[6] = 6; a8.a2[7] = 7;
 
-  a8.a2[8] = 8;     // { dg-warning "array subscript 8 is above array bounds of 'short int\\\[0]'" }
+  a8.a2[8] = 8;     // { dg-warning "array subscript 8 is above array bounds of 'short int\\\[]'" }
 }
 
 
@@ -111,5 +111,5 @@ void test_a9 (void)
   a8.a2[0] = 8; a8.a2[1] = 7; a8.a2[2] = 6; a8.a2[3] = 5; a8.a2[4] = 4;
   a8.a2[5] = 3; a8.a2[5] = 2; a8.a2[6] = 1; a8.a2[7] = 0;
 
-  a8.a2[9] = 8;     // { dg-warning "array subscript 9 is above array bounds of 'short int\\\[0]'" }
+  a8.a2[9] = 8;     // { dg-warning "array subscript 9 is above array bounds of 'short int\\\[]'" }
 }

Reply via email to