diff mbox

[C/C++] Reject declarators with huge arrays (PR c/68107, c++/68266)

Message ID 20151110163623.GB3185@redhat.com
State New
Headers show

Commit Message

Marek Polacek Nov. 10, 2015, 4:36 p.m. UTC
While both C and C++ FEs are able to reject e.g.
int a[__SIZE_MAX__ / sizeof(int)];
they are accepting code such as
int (*a)[__SIZE_MAX__ / sizeof(int)];

As Joseph pointed out, any construction of a non-VLA type whose size is half or
more of the address space should receive a compile-time error.

Done by moving up the check for the size in bytes so that it checks check every
non-VLA complete array type constructed in the course of processing the
declarator.  Since the C++ FE had the same problem, I've fixed it up there as
well.  And that's why I had to twek dg-error of two C++ tests; if the size of
an array is considered invalid, we give an error message with word "unnamed".

(I've removed the comment about crashing in tree_to_[su]hwi since that seems
to no longer be the case.)

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2015-11-10  Marek Polacek  <polacek@redhat.com>

	PR c/68107
	PR c++/68266
	* c-decl.c (grokdeclarator): Check whether the size of arrays is
	valid earlier.

	* decl.c (grokdeclarator): Check whether the size of arrays is valid
	earlier.

	* c-c++-common/pr68107.c: New test.
	* g++.dg/init/new38.C (large_array_char): Adjust dg-error.
	(large_array_char_template): Likewise.
	* g++.dg/init/new44.C: Adjust dg-error.


	Marek

Comments

Paolo Carlini Nov. 10, 2015, 5:38 p.m. UTC | #1
Hi,

On 11/10/2015 05:36 PM, Marek Polacek wrote:
> +
> +		/* Did array size calculations overflow or does the array
> +		   cover more than half of the address-space?  */
> +		if (COMPLETE_TYPE_P (type)
> +		    && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
> +		    && !valid_constant_size_p (TYPE_SIZE_UNIT (type)))
> +		  {
> +		    if (name)
> +		      error_at (loc, "size of array %qE is too large", name);
> +		    else
> +		      error_at (loc, "size of unnamed array is too large");
> +		    type = error_mark_node;
> +		  }
>   	      }
Obviously "the issue" predates your proposed change, but I don't 
understand why the code implementing the check can't be shared by the 
front-ends via a small function in c-family...

Paolo.
Joseph Myers Nov. 10, 2015, 6:02 p.m. UTC | #2
On Tue, 10 Nov 2015, Marek Polacek wrote:

> While both C and C++ FEs are able to reject e.g.
> int a[__SIZE_MAX__ / sizeof(int)];
> they are accepting code such as
> int (*a)[__SIZE_MAX__ / sizeof(int)];
> 
> As Joseph pointed out, any construction of a non-VLA type whose size is half or
> more of the address space should receive a compile-time error.
> 
> Done by moving up the check for the size in bytes so that it checks check every
> non-VLA complete array type constructed in the course of processing the
> declarator.  Since the C++ FE had the same problem, I've fixed it up there as
> well.  And that's why I had to twek dg-error of two C++ tests; if the size of
> an array is considered invalid, we give an error message with word "unnamed".
> 
> (I've removed the comment about crashing in tree_to_[su]hwi since that seems
> to no longer be the case.)
> 
> Bootstrapped/regtested on x86_64-linux, ok for trunk?

The C front-end changes are OK.
Martin Sebor Nov. 10, 2015, 7:40 p.m. UTC | #3
On 11/10/2015 09:36 AM, Marek Polacek wrote:
> While both C and C++ FEs are able to reject e.g.
> int a[__SIZE_MAX__ / sizeof(int)];
> they are accepting code such as
> int (*a)[__SIZE_MAX__ / sizeof(int)];
>
> As Joseph pointed out, any construction of a non-VLA type whose size is half or
> more of the address space should receive a compile-time error.
>
> Done by moving up the check for the size in bytes so that it checks check every
> non-VLA complete array type constructed in the course of processing the
> declarator.  Since the C++ FE had the same problem, I've fixed it up there as
> well.  And that's why I had to twek dg-error of two C++ tests; if the size of
> an array is considered invalid, we give an error message with word "unnamed".
>
> (I've removed the comment about crashing in tree_to_[su]hwi since that seems
> to no longer be the case.)

Thanks for including me on this. I tested it with C++ references
to arrays (in addition to pointers) and it works correctly for
those as well (unsurprisingly). The only thing that bothers me
a bit is that the seemingly  arbitrary inconsistency between
the diagnostics:

> +    p = new char [1][MAX - 99];         // { dg-error "size of unnamed array" }
>       p = new char [1][MAX / 2];          // { dg-error "size of array" }

Would it be possible to make the message issued by the front ends
the same? I.e., either both "unnamed array" or both just "array?"

Martin
Jeff Law Nov. 10, 2015, 11:48 p.m. UTC | #4
On 11/10/2015 09:36 AM, Marek Polacek wrote:
> While both C and C++ FEs are able to reject e.g.
> int a[__SIZE_MAX__ / sizeof(int)];
> they are accepting code such as
> int (*a)[__SIZE_MAX__ / sizeof(int)];
>
> As Joseph pointed out, any construction of a non-VLA type whose size is half or
> more of the address space should receive a compile-time error.
>
> Done by moving up the check for the size in bytes so that it checks check every
> non-VLA complete array type constructed in the course of processing the
> declarator.  Since the C++ FE had the same problem, I've fixed it up there as
> well.  And that's why I had to twek dg-error of two C++ tests; if the size of
> an array is considered invalid, we give an error message with word "unnamed".
>
> (I've removed the comment about crashing in tree_to_[su]hwi since that seems
> to no longer be the case.)
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2015-11-10  Marek Polacek  <polacek@redhat.com>
>
> 	PR c/68107
> 	PR c++/68266
> 	* c-decl.c (grokdeclarator): Check whether the size of arrays is
> 	valid earlier.
>
> 	* decl.c (grokdeclarator): Check whether the size of arrays is valid
> 	earlier.
>
> 	* c-c++-common/pr68107.c: New test.
> 	* g++.dg/init/new38.C (large_array_char): Adjust dg-error.
> 	(large_array_char_template): Likewise.
> 	* g++.dg/init/new44.C: Adjust dg-error.
Someone (I can't recall who) suggested the overflow check ought to be 
shared, I agree.  Can you factor out that check, shove it into c-family/ 
and call it from the C & C++ front-ends?

Approved with that change.  Please post it here for archival purposes 
though.

Your decision as to whether or not the shared routine verifies that type 
!= error_mark_node as is currently done in the C++ front-end.  The C 
front-end merely checks it earlier.  SO it's safe to put that test into 
the shared code if you want.

Jeff
Marek Polacek Nov. 11, 2015, 12:31 p.m. UTC | #5
On Tue, Nov 10, 2015 at 06:38:31PM +0100, Paolo Carlini wrote:
>  Hi,
> 
> On 11/10/2015 05:36 PM, Marek Polacek wrote:
> >+
> >+		/* Did array size calculations overflow or does the array
> >+		   cover more than half of the address-space?  */
> >+		if (COMPLETE_TYPE_P (type)
> >+		    && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
> >+		    && !valid_constant_size_p (TYPE_SIZE_UNIT (type)))
> >+		  {
> >+		    if (name)
> >+		      error_at (loc, "size of array %qE is too large", name);
> >+		    else
> >+		      error_at (loc, "size of unnamed array is too large");
> >+		    type = error_mark_node;
> >+		  }
> >  	      }
> Obviously "the issue" predates your proposed change, but I don't understand
> why the code implementing the check can't be shared by the front-ends via a
> small function in c-family...

Certainly I'm in favor of sharing code between C and C++ FEs, though in
this case it didn't seem too important/obvious, because of the extra !=
error_mark_node check + I don't really like the new function getting *type
and setting it there.

But I'll submit another version of the patch with a common function.

	Marek
Marek Polacek Nov. 11, 2015, 12:39 p.m. UTC | #6
On Tue, Nov 10, 2015 at 12:40:49PM -0700, Martin Sebor wrote:
> On 11/10/2015 09:36 AM, Marek Polacek wrote:
> >While both C and C++ FEs are able to reject e.g.
> >int a[__SIZE_MAX__ / sizeof(int)];
> >they are accepting code such as
> >int (*a)[__SIZE_MAX__ / sizeof(int)];
> >
> >As Joseph pointed out, any construction of a non-VLA type whose size is half or
> >more of the address space should receive a compile-time error.
> >
> >Done by moving up the check for the size in bytes so that it checks check every
> >non-VLA complete array type constructed in the course of processing the
> >declarator.  Since the C++ FE had the same problem, I've fixed it up there as
> >well.  And that's why I had to twek dg-error of two C++ tests; if the size of
> >an array is considered invalid, we give an error message with word "unnamed".
> >
> >(I've removed the comment about crashing in tree_to_[su]hwi since that seems
> >to no longer be the case.)
> 
> Thanks for including me on this. I tested it with C++ references
> to arrays (in addition to pointers) and it works correctly for
> those as well (unsurprisingly). The only thing that bothers me

Good, thanks!

> a bit is that the seemingly  arbitrary inconsistency between
> the diagnostics:
 
> >+    p = new char [1][MAX - 99];         // { dg-error "size of unnamed array" }
> >      p = new char [1][MAX / 2];          // { dg-error "size of array" }
> 
> Would it be possible to make the message issued by the front ends
> the same? I.e., either both "unnamed array" or both just "array?"

Yeah, I was thinking about that, too, but I was also hoping that we can
clean this up as a follow-up.  I think let's drop the "unnamed" word, even
though that means that the changes in new44.C brought with my patch will
essentially have to be reverted...

Oh, and we could also be more informative and print the size of an array,
or the number of elements, as clang does.

Thanks,

	Marek
Bernd Schmidt Nov. 11, 2015, 12:42 p.m. UTC | #7
On 11/11/2015 01:31 PM, Marek Polacek wrote:

> Certainly I'm in favor of sharing code between C and C++ FEs, though in
> this case it didn't seem too important/obvious, because of the extra !=
> error_mark_node check + I don't really like the new function getting *type
> and setting it there.

Make it return bool to indicate whether to change type to error_mark.


Bernd
Marek Polacek Nov. 11, 2015, 2:55 p.m. UTC | #8
On Wed, Nov 11, 2015 at 01:42:04PM +0100, Bernd Schmidt wrote:
> On 11/11/2015 01:31 PM, Marek Polacek wrote:
> 
> >Certainly I'm in favor of sharing code between C and C++ FEs, though in
> >this case it didn't seem too important/obvious, because of the extra !=
> >error_mark_node check + I don't really like the new function getting *type
> >and setting it there.
> 
> Make it return bool to indicate whether to change type to error_mark.

Yeah, I've done it like so.

	Marek
Martin Sebor Nov. 12, 2015, 4:49 a.m. UTC | #9
> Oh, and we could also be more informative and print the size of an array,
> or the number of elements, as clang does.

Yes, that's pretty nice. It helps but the diagnostic must point at
the right dimension. GCC often just points at the whole expression
or some token within it.

void* foo ()
{
     enum { I = 65535, J = 65536, K = 65537, L = 65538, M = 65539 };

     return new int [I][J][K][L][M];
}
z.c:5:24: error: array is too large (65536 elements)
     return new int [I][J][K][L][M];
                        ^

It might be even more helpful if it included the size of each element
(i.e., here, K * L * M byes).

Martin
diff mbox

Patch

diff --git gcc/c/c-decl.c gcc/c/c-decl.c
index a3d8ead..2ec4865 100644
--- gcc/c/c-decl.c
+++ gcc/c/c-decl.c
@@ -6007,6 +6007,19 @@  grokdeclarator (const struct c_declarator *declarator,
 		    TYPE_SIZE_UNIT (type) = size_zero_node;
 		    SET_TYPE_STRUCTURAL_EQUALITY (type);
 		  }
+
+		/* Did array size calculations overflow or does the array
+		   cover more than half of the address-space?  */
+		if (COMPLETE_TYPE_P (type)
+		    && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
+		    && !valid_constant_size_p (TYPE_SIZE_UNIT (type)))
+		  {
+		    if (name)
+		      error_at (loc, "size of array %qE is too large", name);
+		    else
+		      error_at (loc, "size of unnamed array is too large");
+		    type = error_mark_node;
+		  }
 	      }
 
 	    if (decl_context != PARM
@@ -6014,7 +6027,8 @@  grokdeclarator (const struct c_declarator *declarator,
 		    || array_ptr_attrs != NULL_TREE
 		    || array_parm_static))
 	      {
-		error_at (loc, "static or type qualifiers in non-parameter array declarator");
+		error_at (loc, "static or type qualifiers in non-parameter "
+			  "array declarator");
 		array_ptr_quals = TYPE_UNQUALIFIED;
 		array_ptr_attrs = NULL_TREE;
 		array_parm_static = 0;
@@ -6293,22 +6307,6 @@  grokdeclarator (const struct c_declarator *declarator,
 	}
     }
 
-  /* Did array size calculations overflow or does the array cover more
-     than half of the address-space?  */
-  if (TREE_CODE (type) == ARRAY_TYPE
-      && COMPLETE_TYPE_P (type)
-      && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
-      && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
-    {
-      if (name)
-	error_at (loc, "size of array %qE is too large", name);
-      else
-	error_at (loc, "size of unnamed array is too large");
-      /* If we proceed with the array type as it is, we'll eventually
-	 crash in tree_to_[su]hwi().  */
-      type = error_mark_node;
-    }
-
   /* If this is declaring a typedef name, return a TYPE_DECL.  */
 
   if (storage_class == csc_typedef)
diff --git gcc/cp/decl.c gcc/cp/decl.c
index bd3f2bc..68ad82e 100644
--- gcc/cp/decl.c
+++ gcc/cp/decl.c
@@ -9945,6 +9945,18 @@  grokdeclarator (const cp_declarator *declarator,
 	case cdk_array:
 	  type = create_array_type_for_decl (dname, type,
 					     declarator->u.array.bounds);
+	  if (type != error_mark_node
+	      && COMPLETE_TYPE_P (type)
+	      && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
+	      && !valid_constant_size_p (TYPE_SIZE_UNIT (type)))
+	    {
+	      if (dname)
+		error ("size of array %qE is too large", dname);
+	      else
+		error ("size of unnamed array is too large");
+	      type = error_mark_node;
+	    }
+
 	  if (declarator->std_attributes)
 	    /* [dcl.array]/1:
 
@@ -10508,19 +10520,6 @@  grokdeclarator (const cp_declarator *declarator,
         error ("non-parameter %qs cannot be a parameter pack", name);
     }
 
-  /* Did array size calculations overflow or does the array cover more
-     than half of the address-space?  */
-  if (TREE_CODE (type) == ARRAY_TYPE
-      && COMPLETE_TYPE_P (type)
-      && TREE_CODE (TYPE_SIZE_UNIT (type)) == INTEGER_CST
-      && ! valid_constant_size_p (TYPE_SIZE_UNIT (type)))
-    {
-      error ("size of array %qs is too large", name);
-      /* If we proceed with the array type as it is, we'll eventually
-	 crash in tree_to_[su]hwi().  */
-      type = error_mark_node;
-    }
-
   if ((decl_context == FIELD || decl_context == PARM)
       && !processing_template_decl
       && variably_modified_type_p (type, NULL_TREE))
diff --git gcc/testsuite/c-c++-common/pr68107.c gcc/testsuite/c-c++-common/pr68107.c
index e69de29..f1ed465 100644
--- gcc/testsuite/c-c++-common/pr68107.c
+++ gcc/testsuite/c-c++-common/pr68107.c
@@ -0,0 +1,37 @@ 
+/* PR c/68107 */
+/* { dg-do compile } */
+
+#define N ((__SIZE_MAX__ / sizeof (int)) / 2 + 1)
+
+typedef int (*T1)[N]; /* { dg-error "too large" } */
+typedef int (*T2)[N - 1];
+typedef int (*T3)[N][N]; /* { dg-error "too large" } */
+typedef int (*T4)[N - 1][N - 1]; /* { dg-error "too large" } */
+typedef int (**T5)[N]; /* { dg-error "too large" } */
+
+struct S {
+  int (*q1)[N]; /* { dg-error "too large" } */
+  int (*q2)[N - 1];
+  int (*q3)[N][N]; /* { dg-error "too large" } */
+  int (*q4)[N - 1][N - 1]; /* { dg-error "too large" } */
+  int (**q5)[N]; /* { dg-error "too large" } */
+};
+
+void fn1 (int (*p1)[N]); /* { dg-error "too large" } */
+void fn2 (int (*p1)[N - 1]);
+void fn3 (int (*p3)[N][N]); /* { dg-error "too large" } */
+void fn4 (int (*p4)[N - 1][N - 1]); /* { dg-error "too large" } */
+void fn5 (int (**p5)[N]); /* { dg-error "too large" } */
+
+void
+fn (void)
+{
+  int (*n1)[N]; /* { dg-error "too large" } */
+  int (*n2)[N - 1];
+  int (*n3)[N][N]; /* { dg-error "too large" } */
+  int (*n4)[N - 1][N - 1]; /* { dg-error "too large" } */
+  int (**n5)[N]; /* { dg-error "too large" } */
+
+  sizeof (int (*)[N]); /* { dg-error "too large" } */
+  sizeof (int [N]); /* { dg-error "too large" } */
+}
diff --git gcc/testsuite/g++.dg/init/new38.C gcc/testsuite/g++.dg/init/new38.C
index 1672f22..37da525 100644
--- gcc/testsuite/g++.dg/init/new38.C
+++ gcc/testsuite/g++.dg/init/new38.C
@@ -5,7 +5,7 @@  large_array_char(int n)
 {
   new char[n]
     [1ULL << (sizeof(void *) * 4)]
-    [1ULL << (sizeof(void *) * 4)]; // { dg-error "size of array" }
+    [1ULL << (sizeof(void *) * 4)]; // { dg-error "size of unnamed array" }
 }
 
 template <typename T>
@@ -14,7 +14,7 @@  large_array_char_template(int n)
 {
   new char[n]
     [1ULL << (sizeof(void *) * 4)]
-    [1ULL << (sizeof(void *) * 4)]; // { dg-error "size of array" }
+    [1ULL << (sizeof(void *) * 4)]; // { dg-error "size of unnamed array" }
 }
 
 
diff --git gcc/testsuite/g++.dg/init/new44.C gcc/testsuite/g++.dg/init/new44.C
index d6ff86a..ab6e348 100644
--- gcc/testsuite/g++.dg/init/new44.C
+++ gcc/testsuite/g++.dg/init/new44.C
@@ -87,10 +87,10 @@  test_one_dim_short_array ()
 static void __attribute__ ((used))
 test_two_dim_char_array ()
 {
-    p = new char [1][MAX];              // { dg-error "size of array" }
-    p = new char [1][MAX - 1];          // { dg-error "size of array" }
-    p = new char [1][MAX - 2];          // { dg-error "size of array" }
-    p = new char [1][MAX - 99];         // { dg-error "size of array" }
+    p = new char [1][MAX];              // { dg-error "size of unnamed array" }
+    p = new char [1][MAX - 1];          // { dg-error "size of unnamed array" }
+    p = new char [1][MAX - 2];          // { dg-error "size of unnamed array" }
+    p = new char [1][MAX - 99];         // { dg-error "size of unnamed array" }
     p = new char [1][MAX / 2];          // { dg-error "size of array" }
     p = new char [1][MAX / 2 - 1];      // { dg-error "size of array" }
     p = new char [1][MAX / 2 - 2];      // { dg-error "size of array" }
@@ -104,18 +104,18 @@  test_two_dim_char_array ()
     p = new char [1][MAX / 2 - 7];      // okay
     p = new char [1][MAX / 2 - 8];      // okay
 
-    p = new char [2][MAX];              // { dg-error "size of array" }
-    p = new char [2][MAX - 1];          // { dg-error "size of array" }
-    p = new char [2][MAX - 2];          // { dg-error "size of array" }
+    p = new char [2][MAX];              // { dg-error "size of unnamed array" }
+    p = new char [2][MAX - 1];          // { dg-error "size of unnamed array" }
+    p = new char [2][MAX - 2];          // { dg-error "size of unnamed array" }
     p = new char [2][MAX / 2];          // { dg-error "size of array" }
     p = new char [2][MAX / 2 - 1];      // { dg-error "size of array" }
     p = new char [2][MAX / 2 - 2];      // { dg-error "size of array" }
     p = new char [2][MAX / 2 - 7];      // { dg-error "size of array" }
     p = new char [2][MAX / 2 - 8];      // { dg-error "size of array" }
 
-    p = new char [MAX][MAX];            // { dg-error "size of array" }
-    p = new char [MAX][MAX - 1];        // { dg-error "size of array" }
-    p = new char [MAX][MAX - 2];        // { dg-error "size of array" }
+    p = new char [MAX][MAX];            // { dg-error "size of unnamed array" }
+    p = new char [MAX][MAX - 1];        // { dg-error "size of unnamed array" }
+    p = new char [MAX][MAX - 2];        // { dg-error "size of unnamed array" }
     p = new char [MAX][MAX / 2];        // { dg-error "size of array" }
     p = new char [MAX][MAX / 2 - 1];    // { dg-error "size of array" }
     p = new char [MAX][MAX / 2 - 2];    // { dg-error "size of array" }
@@ -142,10 +142,10 @@  test_two_dim_char_array ()
 static __attribute__ ((used)) void
 test_three_dim_char_array ()
 {
-    p = new char [1][1][MAX];           // { dg-error "size of array" }
-    p = new char [1][1][MAX - 1];       // { dg-error "size of array" }
-    p = new char [1][1][MAX - 2];       // { dg-error "size of array" }
-    p = new char [1][1][MAX - 99];      // { dg-error "size of array" }
+    p = new char [1][1][MAX];           // { dg-error "size of unnamed array" }
+    p = new char [1][1][MAX - 1];       // { dg-error "size of unnamed array" }
+    p = new char [1][1][MAX - 2];       // { dg-error "size of unnamed array" }
+    p = new char [1][1][MAX - 99];      // { dg-error "size of unnamed array" }
     p = new char [1][1][MAX / 2];       // { dg-error "size of array" }
     p = new char [1][1][MAX / 2 - 1];   // { dg-error "size of array" }
     p = new char [1][1][MAX / 2 - 2];   // { dg-error "size of array" }
@@ -159,19 +159,19 @@  test_three_dim_char_array ()
     p = new char [1][1][MAX / 2 - 7];   // okay
     p = new char [1][1][MAX / 2 - 8];   // okay
 
-    p = new char [1][2][MAX];           // { dg-error "size of array" }
-    p = new char [1][2][MAX - 1];       // { dg-error "size of array" }
-    p = new char [1][2][MAX - 2];       // { dg-error "size of array" }
-    p = new char [1][2][MAX - 99];      // { dg-error "size of array" }
-    p = new char [1][2][MAX / 2];       // { dg-error "size of array" }
-    p = new char [1][2][MAX / 2 - 1];   // { dg-error "size of array" }
-    p = new char [1][2][MAX / 2 - 2];   // { dg-error "size of array" }
-    p = new char [1][2][MAX / 2 - 3];   // { dg-error "size of array" }
-    p = new char [1][2][MAX / 2 - 4];   // { dg-error "size of array" }
-    p = new char [1][2][MAX / 2 - 5];   // { dg-error "size of array" }
-    p = new char [1][2][MAX / 2 - 6];   // { dg-error "size of array" }
-    p = new char [1][2][MAX / 2 - 7];   // { dg-error "size of array" }
-    p = new char [1][2][MAX / 2 - 8];   // { dg-error "size of array" }
+    p = new char [1][2][MAX];           // { dg-error "size of unnamed array" }
+    p = new char [1][2][MAX - 1];       // { dg-error "size of unnamed array" }
+    p = new char [1][2][MAX - 2];       // { dg-error "size of unnamed array" }
+    p = new char [1][2][MAX - 99];      // { dg-error "size of unnamed array" }
+    p = new char [1][2][MAX / 2];       // { dg-error "size of unnamed array" }
+    p = new char [1][2][MAX / 2 - 1];   // { dg-error "size of unnamed array" }
+    p = new char [1][2][MAX / 2 - 2];   // { dg-error "size of unnamed array" }
+    p = new char [1][2][MAX / 2 - 3];   // { dg-error "size of unnamed array" }
+    p = new char [1][2][MAX / 2 - 4];   // { dg-error "size of unnamed array" }
+    p = new char [1][2][MAX / 2 - 5];   // { dg-error "size of unnamed array" }
+    p = new char [1][2][MAX / 2 - 6];   // { dg-error "size of unnamed array" }
+    p = new char [1][2][MAX / 2 - 7];   // { dg-error "size of unnamed array" }
+    p = new char [1][2][MAX / 2 - 8];   // { dg-error "size of unnamed array" }
     p = new char [1][2][MAX / 4];       // { dg-error "size of array" }
 
     // Avoid exercising data model-dependent expressions.
@@ -181,10 +181,10 @@  test_three_dim_char_array ()
     p = new char [1][2][MAX / 4 - 3];   // okay
     p = new char [1][2][MAX / 4 - 4];   // okay
 
-    p = new char [2][1][MAX];           // { dg-error "size of array" }
-    p = new char [2][1][MAX - 1];       // { dg-error "size of array" }
-    p = new char [2][1][MAX - 2];       // { dg-error "size of array" }
-    p = new char [2][1][MAX - 99];      // { dg-error "size of array" }
+    p = new char [2][1][MAX];           // { dg-error "size of unnamed array" }
+    p = new char [2][1][MAX - 1];       // { dg-error "size of unnamed array" }
+    p = new char [2][1][MAX - 2];       // { dg-error "size of unnamed array" }
+    p = new char [2][1][MAX - 99];      // { dg-error "size of unnamed array" }
     p = new char [2][1][MAX / 2];       // { dg-error "size of array" }
     p = new char [2][1][MAX / 2 - 1];   // { dg-error "size of array" }
     p = new char [2][1][MAX / 2 - 2];   // { dg-error "size of array" }
@@ -203,19 +203,19 @@  test_three_dim_char_array ()
     p = new char [2][1][MAX / 4 - 3];   // okay
     p = new char [2][1][MAX / 4 - 4];   // okay
 
-    p = new char [2][2][MAX];           // { dg-error "size of array" }
-    p = new char [2][2][MAX - 1];       // { dg-error "size of array" }
-    p = new char [2][2][MAX - 2];       // { dg-error "size of array" }
-    p = new char [2][2][MAX - 99];      // { dg-error "size of array" }
-    p = new char [2][2][MAX / 2];       // { dg-error "size of array" }
-    p = new char [2][2][MAX / 2 - 1];   // { dg-error "size of array" }
-    p = new char [2][2][MAX / 2 - 2];   // { dg-error "size of array" }
-    p = new char [2][2][MAX / 2 - 3];   // { dg-error "size of array" }
-    p = new char [2][2][MAX / 2 - 4];   // { dg-error "size of array" }
-    p = new char [2][2][MAX / 2 - 5];   // { dg-error "size of array" }
-    p = new char [2][2][MAX / 2 - 6];   // { dg-error "size of array" }
-    p = new char [2][2][MAX / 2 - 7];   // { dg-error "size of array" }
-    p = new char [2][2][MAX / 2 - 8];   // { dg-error "size of array" }
+    p = new char [2][2][MAX];           // { dg-error "size of unnamed array" }
+    p = new char [2][2][MAX - 1];       // { dg-error "size of unnamed array" }
+    p = new char [2][2][MAX - 2];       // { dg-error "size of unnamed array" }
+    p = new char [2][2][MAX - 99];      // { dg-error "size of unnamed array" }
+    p = new char [2][2][MAX / 2];       // { dg-error "size of unnamed array" }
+    p = new char [2][2][MAX / 2 - 1];   // { dg-error "size of unnamed array" }
+    p = new char [2][2][MAX / 2 - 2];   // { dg-error "size of unnamed array" }
+    p = new char [2][2][MAX / 2 - 3];   // { dg-error "size of unnamed array" }
+    p = new char [2][2][MAX / 2 - 4];   // { dg-error "size of unnamed array" }
+    p = new char [2][2][MAX / 2 - 5];   // { dg-error "size of unnamed array" }
+    p = new char [2][2][MAX / 2 - 6];   // { dg-error "size of unnamed array" }
+    p = new char [2][2][MAX / 2 - 7];   // { dg-error "size of unnamed array" }
+    p = new char [2][2][MAX / 2 - 8];   // { dg-error "size of unnamed array" }
     p = new char [2][2][MAX / 4];       // { dg-error "size of array" }
     p = new char [2][2][MAX / 4 - 1];   // { dg-error "size of array" }
     p = new char [2][2][MAX / 4 - 2];   // { dg-error "size of array" }
@@ -227,19 +227,19 @@  test_three_dim_char_array ()
     p = new char [2][2][MAX / 8 - 2];
     p = new char [2][2][MAX / 8 - 3];
 
-    p = new char [2][MAX][2];           // { dg-error "size of array" }
-    p = new char [2][MAX - 1][2];       // { dg-error "size of array" }
-    p = new char [2][MAX - 2][2];       // { dg-error "size of array" }
-    p = new char [2][MAX - 99][2];      // { dg-error "size of array" }
-    p = new char [2][MAX / 2][2];       // { dg-error "size of array" }
-    p = new char [2][MAX / 2 - 1][2];   // { dg-error "size of array" }
-    p = new char [2][MAX / 2 - 2][2];   // { dg-error "size of array" }
-    p = new char [2][MAX / 2 - 3][2];   // { dg-error "size of array" }
-    p = new char [2][MAX / 2 - 4][2];   // { dg-error "size of array" }
-    p = new char [2][MAX / 2 - 5][2];   // { dg-error "size of array" }
-    p = new char [2][MAX / 2 - 6][2];   // { dg-error "size of array" }
-    p = new char [2][MAX / 2 - 7][2];   // { dg-error "size of array" }
-    p = new char [2][MAX / 2 - 8][2];   // { dg-error "size of array" }
+    p = new char [2][MAX][2];           // { dg-error "size of unnamed array" }
+    p = new char [2][MAX - 1][2];       // { dg-error "size of unnamed array" }
+    p = new char [2][MAX - 2][2];       // { dg-error "size of unnamed array" }
+    p = new char [2][MAX - 99][2];      // { dg-error "size of unnamed array" }
+    p = new char [2][MAX / 2][2];       // { dg-error "size of unnamed array" }
+    p = new char [2][MAX / 2 - 1][2];   // { dg-error "size of unnamed array" }
+    p = new char [2][MAX / 2 - 2][2];   // { dg-error "size of unnamed array" }
+    p = new char [2][MAX / 2 - 3][2];   // { dg-error "size of unnamed array" }
+    p = new char [2][MAX / 2 - 4][2];   // { dg-error "size of unnamed array" }
+    p = new char [2][MAX / 2 - 5][2];   // { dg-error "size of unnamed array" }
+    p = new char [2][MAX / 2 - 6][2];   // { dg-error "size of unnamed array" }
+    p = new char [2][MAX / 2 - 7][2];   // { dg-error "size of unnamed array" }
+    p = new char [2][MAX / 2 - 8][2];   // { dg-error "size of unnamed array" }
     p = new char [2][MAX / 4][2];       // { dg-error "size of array" }
     p = new char [2][MAX / 4 - 1][2];   // { dg-error "size of array" }
     p = new char [2][MAX / 4 - 2][2];   // { dg-error "size of array" }
@@ -275,11 +275,11 @@  test_three_dim_char_array ()
     p = new char [MAX / 8 - 2][2][2];
     p = new char [MAX / 8 - 3][2][2];
 
-    p = new char [MAX][MAX][MAX];         // { dg-error "size of array" }
-    p = new char [MAX][MAX][MAX / 2];     // { dg-error "size of array" }
-    p = new char [MAX][MAX / 2][MAX];     // { dg-error "size of array" }
-    p = new char [MAX][MAX / 2][MAX / 2]; // { dg-error "size of array" }
-    p = new char [MAX / 2][MAX / 2][MAX / 2]; // { dg-error "size of array" }
+    p = new char [MAX][MAX][MAX];         // { dg-error "size of unnamed array" }
+    p = new char [MAX][MAX][MAX / 2];     // { dg-error "size of unnamed array" }
+    p = new char [MAX][MAX / 2][MAX];     // { dg-error "size of unnamed array" }
+    p = new char [MAX][MAX / 2][MAX / 2]; // { dg-error "size of unnamed array" }
+    p = new char [MAX / 2][MAX / 2][MAX / 2]; // { dg-error "size of unnamed array" }
 }
 
 // Exercise new expression with N-dimensional arrays where N is
@@ -342,10 +342,10 @@  test_one_dim_byte_array (void *p)
 static void __attribute__ ((used))
 test_placement_two_dim_byte_struct_array (void *p)
 {
-    p = new (p) B [1][MAX];             // { dg-error "size of array" }
-    p = new (p) B [1][MAX - 1];         // { dg-error "size of array" }
-    p = new (p) B [1][MAX - 2];         // { dg-error "size of array" }
-    p = new (p) B [1][MAX - 99];        // { dg-error "size of array" }
+    p = new (p) B [1][MAX];             // { dg-error "size of unnamed array" }
+    p = new (p) B [1][MAX - 1];         // { dg-error "size of unnamed array" }
+    p = new (p) B [1][MAX - 2];         // { dg-error "size of unnamed array" }
+    p = new (p) B [1][MAX - 99];        // { dg-error "size of unnamed array" }
     p = new (p) B [1][MAX / 2];         // { dg-error "size of array" }
     p = new (p) B [1][MAX / 2 - 1];     // { dg-error "size of array" }
     p = new (p) B [1][MAX / 2 - 2];     // { dg-error "size of array" }
@@ -359,18 +359,18 @@  test_placement_two_dim_byte_struct_array (void *p)
     p = new (p) B [1][MAX / 2 - 7];      // okay
     p = new (p) B [1][MAX / 2 - 8];      // okay
 
-    p = new (p) B [2][MAX];             // { dg-error "size of array" }
-    p = new (p) B [2][MAX - 1];         // { dg-error "size of array" }
-    p = new (p) B [2][MAX - 2];         // { dg-error "size of array" }
+    p = new (p) B [2][MAX];             // { dg-error "size of unnamed array" }
+    p = new (p) B [2][MAX - 1];         // { dg-error "size of unnamed array" }
+    p = new (p) B [2][MAX - 2];         // { dg-error "size of unnamed array" }
     p = new (p) B [2][MAX / 2];         // { dg-error "size of array" }
     p = new (p) B [2][MAX / 2 - 1];     // { dg-error "size of array" }
     p = new (p) B [2][MAX / 2 - 2];     // { dg-error "size of array" }
     p = new (p) B [2][MAX / 2 - 7];     // { dg-error "size of array" }
     p = new (p) B [2][MAX / 2 - 8];     // { dg-error "size of array" }
 
-    p = new (p) B [MAX][MAX];           // { dg-error "size of array" }
-    p = new (p) B [MAX][MAX - 1];       // { dg-error "size of array" }
-    p = new (p) B [MAX][MAX - 2];       // { dg-error "size of array" }
+    p = new (p) B [MAX][MAX];           // { dg-error "size of unnamed array" }
+    p = new (p) B [MAX][MAX - 1];       // { dg-error "size of unnamed array" }
+    p = new (p) B [MAX][MAX - 2];       // { dg-error "size of unnamed array" }
     p = new (p) B [MAX][MAX / 2];       // { dg-error "size of array" }
     p = new (p) B [MAX][MAX / 2 - 1];   // { dg-error "size of array" }
     p = new (p) B [MAX][MAX / 2 - 2];   // { dg-error "size of array" }
@@ -397,10 +397,10 @@  test_placement_two_dim_byte_struct_array (void *p)
 static __attribute__ ((used)) void
 test_placement_three_dim_byte_struct_array (void *p)
 {
-    p = new (p) B [1][1][MAX];          // { dg-error "size of array" }
-    p = new (p) B [1][1][MAX - 1];      // { dg-error "size of array" }
-    p = new (p) B [1][1][MAX - 2];      // { dg-error "size of array" }
-    p = new (p) B [1][1][MAX - 99];     // { dg-error "size of array" }
+    p = new (p) B [1][1][MAX];          // { dg-error "size of unnamed array" }
+    p = new (p) B [1][1][MAX - 1];      // { dg-error "size of unnamed array" }
+    p = new (p) B [1][1][MAX - 2];      // { dg-error "size of unnamed array" }
+    p = new (p) B [1][1][MAX - 99];     // { dg-error "size of unnamed array" }
     p = new (p) B [1][1][MAX / 2];      // { dg-error "size of array" }
     p = new (p) B [1][1][MAX / 2 - 1];  // { dg-error "size of array" }
     p = new (p) B [1][1][MAX / 2 - 2];  // { dg-error "size of array" }
@@ -414,19 +414,19 @@  test_placement_three_dim_byte_struct_array (void *p)
     p = new (p) B [1][1][MAX / 2 - 7];   // okay
     p = new (p) B [1][1][MAX / 2 - 8];   // okay
 
-    p = new (p) B [1][2][MAX];          // { dg-error "size of array" }
-    p = new (p) B [1][2][MAX - 1];      // { dg-error "size of array" }
-    p = new (p) B [1][2][MAX - 2];      // { dg-error "size of array" }
-    p = new (p) B [1][2][MAX - 99];     // { dg-error "size of array" }
-    p = new (p) B [1][2][MAX / 2];      // { dg-error "size of array" }
-    p = new (p) B [1][2][MAX / 2 - 1];  // { dg-error "size of array" }
-    p = new (p) B [1][2][MAX / 2 - 2];  // { dg-error "size of array" }
-    p = new (p) B [1][2][MAX / 2 - 3];  // { dg-error "size of array" }
-    p = new (p) B [1][2][MAX / 2 - 4];  // { dg-error "size of array" }
-    p = new (p) B [1][2][MAX / 2 - 5];  // { dg-error "size of array" }
-    p = new (p) B [1][2][MAX / 2 - 6];  // { dg-error "size of array" }
-    p = new (p) B [1][2][MAX / 2 - 7];  // { dg-error "size of array" }
-    p = new (p) B [1][2][MAX / 2 - 8];  // { dg-error "size of array" }
+    p = new (p) B [1][2][MAX];          // { dg-error "size of unnamed array" }
+    p = new (p) B [1][2][MAX - 1];      // { dg-error "size of unnamed array" }
+    p = new (p) B [1][2][MAX - 2];      // { dg-error "size of unnamed array" }
+    p = new (p) B [1][2][MAX - 99];     // { dg-error "size of unnamed array" }
+    p = new (p) B [1][2][MAX / 2];      // { dg-error "size of unnamed array" }
+    p = new (p) B [1][2][MAX / 2 - 1];  // { dg-error "size of unnamed array" }
+    p = new (p) B [1][2][MAX / 2 - 2];  // { dg-error "size of unnamed array" }
+    p = new (p) B [1][2][MAX / 2 - 3];  // { dg-error "size of unnamed array" }
+    p = new (p) B [1][2][MAX / 2 - 4];  // { dg-error "size of unnamed array" }
+    p = new (p) B [1][2][MAX / 2 - 5];  // { dg-error "size of unnamed array" }
+    p = new (p) B [1][2][MAX / 2 - 6];  // { dg-error "size of unnamed array" }
+    p = new (p) B [1][2][MAX / 2 - 7];  // { dg-error "size of unnamed array" }
+    p = new (p) B [1][2][MAX / 2 - 8];  // { dg-error "size of unnamed array" }
     p = new (p) B [1][2][MAX / 4];      // { dg-error "size of array" }
 
     // Avoid exercising data model-dependent expressions.
@@ -436,10 +436,10 @@  test_placement_three_dim_byte_struct_array (void *p)
     p = new (p) B [1][2][MAX / 4 - 3];   // okay
     p = new (p) B [1][2][MAX / 4 - 4];   // okay
 
-    p = new (p) B [2][1][MAX];          // { dg-error "size of array" }
-    p = new (p) B [2][1][MAX - 1];      // { dg-error "size of array" }
-    p = new (p) B [2][1][MAX - 2];      // { dg-error "size of array" }
-    p = new (p) B [2][1][MAX - 99];     // { dg-error "size of array" }
+    p = new (p) B [2][1][MAX];          // { dg-error "size of unnamed array" }
+    p = new (p) B [2][1][MAX - 1];      // { dg-error "size of unnamed array" }
+    p = new (p) B [2][1][MAX - 2];      // { dg-error "size of unnamed array" }
+    p = new (p) B [2][1][MAX - 99];     // { dg-error "size of unnamed array" }
     p = new (p) B [2][1][MAX / 2];      // { dg-error "size of array" }
     p = new (p) B [2][1][MAX / 2 - 1];  // { dg-error "size of array" }
     p = new (p) B [2][1][MAX / 2 - 2];  // { dg-error "size of array" }
@@ -458,19 +458,19 @@  test_placement_three_dim_byte_struct_array (void *p)
     p = new (p) B [2][1][MAX / 4 - 3];   // okay
     p = new (p) B [2][1][MAX / 4 - 4];   // okay
 
-    p = new (p) B [2][2][MAX];          // { dg-error "size of array" }
-    p = new (p) B [2][2][MAX - 1];      // { dg-error "size of array" }
-    p = new (p) B [2][2][MAX - 2];      // { dg-error "size of array" }
-    p = new (p) B [2][2][MAX - 99];     // { dg-error "size of array" }
-    p = new (p) B [2][2][MAX / 2];      // { dg-error "size of array" }
-    p = new (p) B [2][2][MAX / 2 - 1];  // { dg-error "size of array" }
-    p = new (p) B [2][2][MAX / 2 - 2];  // { dg-error "size of array" }
-    p = new (p) B [2][2][MAX / 2 - 3];  // { dg-error "size of array" }
-    p = new (p) B [2][2][MAX / 2 - 4];  // { dg-error "size of array" }
-    p = new (p) B [2][2][MAX / 2 - 5];  // { dg-error "size of array" }
-    p = new (p) B [2][2][MAX / 2 - 6];  // { dg-error "size of array" }
-    p = new (p) B [2][2][MAX / 2 - 7];  // { dg-error "size of array" }
-    p = new (p) B [2][2][MAX / 2 - 8];  // { dg-error "size of array" }
+    p = new (p) B [2][2][MAX];          // { dg-error "size of unnamed array" }
+    p = new (p) B [2][2][MAX - 1];      // { dg-error "size of unnamed array" }
+    p = new (p) B [2][2][MAX - 2];      // { dg-error "size of unnamed array" }
+    p = new (p) B [2][2][MAX - 99];     // { dg-error "size of unnamed array" }
+    p = new (p) B [2][2][MAX / 2];      // { dg-error "size of unnamed array" }
+    p = new (p) B [2][2][MAX / 2 - 1];  // { dg-error "size of unnamed array" }
+    p = new (p) B [2][2][MAX / 2 - 2];  // { dg-error "size of unnamed array" }
+    p = new (p) B [2][2][MAX / 2 - 3];  // { dg-error "size of unnamed array" }
+    p = new (p) B [2][2][MAX / 2 - 4];  // { dg-error "size of unnamed array" }
+    p = new (p) B [2][2][MAX / 2 - 5];  // { dg-error "size of unnamed array" }
+    p = new (p) B [2][2][MAX / 2 - 6];  // { dg-error "size of unnamed array" }
+    p = new (p) B [2][2][MAX / 2 - 7];  // { dg-error "size of unnamed array" }
+    p = new (p) B [2][2][MAX / 2 - 8];  // { dg-error "size of unnamed array" }
     p = new (p) B [2][2][MAX / 4];      // { dg-error "size of array" }
     p = new (p) B [2][2][MAX / 4 - 1];  // { dg-error "size of array" }
     p = new (p) B [2][2][MAX / 4 - 2];  // { dg-error "size of array" }
@@ -482,19 +482,19 @@  test_placement_three_dim_byte_struct_array (void *p)
     p = new (p) B [2][2][MAX / 8 - 2];
     p = new (p) B [2][2][MAX / 8 - 3];
 
-    p = new (p) B [2][MAX][2];          // { dg-error "size of array" }
-    p = new (p) B [2][MAX - 1][2];      // { dg-error "size of array" }
-    p = new (p) B [2][MAX - 2][2];      // { dg-error "size of array" }
-    p = new (p) B [2][MAX - 99][2];     // { dg-error "size of array" }
-    p = new (p) B [2][MAX / 2][2];      // { dg-error "size of array" }
-    p = new (p) B [2][MAX / 2 - 1][2];  // { dg-error "size of array" }
-    p = new (p) B [2][MAX / 2 - 2][2];  // { dg-error "size of array" }
-    p = new (p) B [2][MAX / 2 - 3][2];  // { dg-error "size of array" }
-    p = new (p) B [2][MAX / 2 - 4][2];  // { dg-error "size of array" }
-    p = new (p) B [2][MAX / 2 - 5][2];  // { dg-error "size of array" }
-    p = new (p) B [2][MAX / 2 - 6][2];  // { dg-error "size of array" }
-    p = new (p) B [2][MAX / 2 - 7][2];  // { dg-error "size of array" }
-    p = new (p) B [2][MAX / 2 - 8][2];  // { dg-error "size of array" }
+    p = new (p) B [2][MAX][2];          // { dg-error "size of unnamed array" }
+    p = new (p) B [2][MAX - 1][2];      // { dg-error "size of unnamed array" }
+    p = new (p) B [2][MAX - 2][2];      // { dg-error "size of unnamed array" }
+    p = new (p) B [2][MAX - 99][2];     // { dg-error "size of unnamed array" }
+    p = new (p) B [2][MAX / 2][2];      // { dg-error "size of unnamed array" }
+    p = new (p) B [2][MAX / 2 - 1][2];  // { dg-error "size of unnamed array" }
+    p = new (p) B [2][MAX / 2 - 2][2];  // { dg-error "size of unnamed array" }
+    p = new (p) B [2][MAX / 2 - 3][2];  // { dg-error "size of unnamed array" }
+    p = new (p) B [2][MAX / 2 - 4][2];  // { dg-error "size of unnamed array" }
+    p = new (p) B [2][MAX / 2 - 5][2];  // { dg-error "size of unnamed array" }
+    p = new (p) B [2][MAX / 2 - 6][2];  // { dg-error "size of unnamed array" }
+    p = new (p) B [2][MAX / 2 - 7][2];  // { dg-error "size of unnamed array" }
+    p = new (p) B [2][MAX / 2 - 8][2];  // { dg-error "size of unnamed array" }
     p = new (p) B [2][MAX / 4][2];      // { dg-error "size of array" }
     p = new (p) B [2][MAX / 4 - 1][2];  // { dg-error "size of array" }
     p = new (p) B [2][MAX / 4 - 2][2];  // { dg-error "size of array" }