diff mbox series

[C++] Improve compute_array_index_type locations

Message ID 65a6b7c7-1284-76de-61a3-9467f4223f7a@oracle.com
State New
Headers show
Series [C++] Improve compute_array_index_type locations | expand

Commit Message

Paolo Carlini Nov. 6, 2018, 9:01 a.m. UTC
Hi,

when I improved create_array_type_for_decl I didn't notice that it calls 
compute_array_index_type as helper, which simply needs to have the 
location information propagated. Tested x86_64-linux.

Thanks, Paolo.

////////////////
/cp
2018-11-06  Paolo Carlini  <paolo.carlini@oracle.com>

	* decl.c (compute_array_index_type_loc): New, like the current
	compute_array_index_type but takes a location_t too.
	(compute_array_index_type): Forward to the latter.
	(create_array_type_for_decl): Use compute_array_index_type_loc.

/testsuite
2018-11-06  Paolo Carlini  <paolo.carlini@oracle.com>

	* g++.dg/cpp0x/constexpr-47969.C: Test locations too.
	* g++.dg/cpp0x/constexpr-48324.C: Likewise.
	* g++.dg/cpp0x/constexpr-ex2.C: Likewise.
	* g++.dg/cpp0x/scoped_enum2.C: Likewise.
	* g++.dg/cpp1y/pr63996.C: Likewise.
	* g++.dg/ext/constexpr-vla5.C: Likewise.
	* g++.dg/ext/stmtexpr15.C: Likewise.
	* g++.dg/ext/vla1.C: Likewise.
	* g++.dg/other/fold1.C: Likewise.
	* g++.dg/parse/array-size2.C: Likewise.
	* g++.dg/parse/crash36.C: Likewise.
	* g++.dg/ubsan/pr81530.C: Likewise.
	* g++.dg/warn/Wvla-1.C: Likewise.
	* g++.dg/warn/Wvla-2.C: Likewise.
	* g++.old-deja/g++.brendan/array1.C: Likewise.
	* g++.old-deja/g++.bugs/900402_02.C: Likewise.
	* g++.old-deja/g++.law/init3.C: Likewise.
	* g++.old-deja/g++.mike/p6149.C: Likewise.

Comments

Paolo Carlini Nov. 6, 2018, 11:25 a.m. UTC | #1
.. by the way, we could pass the location to abstract_virtuals_error 
too, thus fixing the locations of tests like other/abstract1.C and 
abstract2.C, where we currently hit the case:

       else if (identifier_p (decl))
     /* Here we do not have location information.  */
     error ("invalid abstract type %qT for %qE", type, decl);

not sure if it's worth it. What do you think?

Thanks, Paolo.
Paolo Carlini Nov. 14, 2018, 7:30 p.m. UTC | #2
Hi,

gently pinging this older patch of mine: given the previous 
create_array_type_for_decl change, its gist should not be very 
controversial...

On 06/11/18 10:01, Paolo Carlini wrote:
> Hi,
>
> when I improved create_array_type_for_decl I didn't notice that it 
> calls compute_array_index_type as helper, which simply needs to have 
> the location information propagated. Tested x86_64-linux.

     https://gcc.gnu.org/ml/gcc-patches/2018-11/msg00331.html

Thanks, Paolo.
Jason Merrill Nov. 29, 2018, 2:01 a.m. UTC | #3
On 11/6/18 4:01 AM, Paolo Carlini wrote:
> when I improved create_array_type_for_decl I didn't notice that it calls 
> compute_array_index_type as helper, which simply needs to have the 
> location information propagated. Tested x86_64-linux.

This looks like it will use the declarator-id location in diagnostics 
about the array bound expression, which isn't optimal; if 'size' has a 
location, we should use that instead.

Jason
Paolo Carlini Nov. 29, 2018, 3:22 p.m. UTC | #4
Hi,

On 29/11/18 03:01, Jason Merrill wrote:
> On 11/6/18 4:01 AM, Paolo Carlini wrote:
>> when I improved create_array_type_for_decl I didn't notice that it 
>> calls compute_array_index_type as helper, which simply needs to have 
>> the location information propagated. Tested x86_64-linux.
>
> This looks like it will use the declarator-id location in diagnostics 
> about the array bound expression, which isn't optimal; if 'size' has a 
> location, we should use that instead.

Yes. The below, for all the error messages talking about "size", uses 
the location of "size" and either the passed location or input_location 
as fall-back. This, afaics, also matches the behavior of clang. There 
are a few minor subtleties: 1- A first version of the patch didn't 
exploit the location of "size" in the unnamed cases, but doing that 
actually helps for testcases like the new constexpr-base6b.C; 2- It's 
important to use the original "size" - as saved in "osize" - otherwise 
after the folding the location information is lost in some cases (eg, 
happens for the ubsan testcase and a couple of g++.old-deja tests); 3- I 
didn't change the warnings about variable length arrays to exploit the 
location of "size", because they don't explicitly talk about the size - 
that, by the way, appears to match clang's behavior.

Tested x86_64-linux.

Thanks, Paolo.

//////////////////////
Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 266555)
+++ cp/decl.c	(working copy)
@@ -9621,8 +9621,9 @@ fold_sizeof_expr (tree t)
    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)
+static tree
+compute_array_index_type_loc (location_t loc, tree name, tree size,
+			      tsubst_flags_t complain)
 {
   tree itype;
   tree osize = size;
@@ -9658,9 +9659,12 @@ fold_sizeof_expr (tree t)
 	  if (!(complain & tf_error))
 	    return error_mark_node;
 	  if (name)
-	    error ("size of array %qD has non-integral type %qT", name, type);
+	    error_at (cp_expr_loc_or_loc (osize, loc),
+		      "size of array %qD has non-integral type %qT",
+		      name, type);
 	  else
-	    error ("size of array has non-integral type %qT", type);
+	    error_at (cp_expr_loc_or_loc (osize, input_location),
+		      "size of array has non-integral type %qT", type);
 	  size = integer_one_node;
 	}
     }
@@ -9689,8 +9693,16 @@ fold_sizeof_expr (tree t)
     {
       tree folded = cp_fully_fold (size);
       if (TREE_CODE (folded) == INTEGER_CST)
-	pedwarn (input_location, OPT_Wpedantic,
-		 "size of array is not an integral constant-expression");
+	{
+	  if (name)
+	    pedwarn (cp_expr_loc_or_loc (osize, loc),
+		     OPT_Wpedantic, "size of array %qD is not an "
+		     "integral constant-expression", name);
+	  else
+	    pedwarn (cp_expr_loc_or_loc (osize, input_location),
+		     OPT_Wpedantic,
+		     "size of array is not an integral constant-expression");
+	}
       /* Use the folded result for VLAs, too; it will have resolved
 	 SIZEOF_EXPR.  */
       size = folded;
@@ -9706,9 +9718,11 @@ fold_sizeof_expr (tree t)
 	    return error_mark_node;
 
 	  if (name)
-	    error ("size of array %qD is negative", name);
+	    error_at (cp_expr_loc_or_loc (osize, loc),
+		      "size of array %qD is negative", name);
 	  else
-	    error ("size of array is negative");
+	    error_at (cp_expr_loc_or_loc (osize, input_location),
+		      "size of array is negative");
 	  size = integer_one_node;
 	}
       /* As an extension we allow zero-sized arrays.  */
@@ -9722,9 +9736,12 @@ fold_sizeof_expr (tree t)
 	  else if (in_system_header_at (input_location))
 	    /* Allow them in system headers because glibc uses them.  */;
 	  else if (name)
-	    pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array %qD", name);
+	    pedwarn (cp_expr_loc_or_loc (osize, loc), OPT_Wpedantic,
+		     "ISO C++ forbids zero-size array %qD", name);
 	  else
-	    pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array");
+	    pedwarn (cp_expr_loc_or_loc (osize, input_location),
+		     OPT_Wpedantic,
+		     "ISO C++ forbids zero-size array");
 	}
     }
   else if (TREE_CONSTANT (size)
@@ -9737,24 +9754,28 @@ fold_sizeof_expr (tree t)
 	return error_mark_node;
       /* `(int) &fn' is not a valid array bound.  */
       if (name)
-	error ("size of array %qD is not an integral constant-expression",
-	       name);
+	error_at (cp_expr_loc_or_loc (osize, loc),
+		  "size of array %qD is not an integral constant-expression",
+		  name);
       else
-	error ("size of array is not an integral constant-expression");
+	error_at (cp_expr_loc_or_loc (osize, input_location),
+		  "size of array is not an integral constant-expression");
       size = integer_one_node;
     }
   else if (pedantic && warn_vla != 0)
     {
       if (name)
-	pedwarn (input_location, OPT_Wvla, "ISO C++ forbids variable length array %qD", name);
+	pedwarn (loc, OPT_Wvla,
+		 "ISO C++ forbids variable length array %qD", name);
       else
-	pedwarn (input_location, OPT_Wvla, "ISO C++ forbids variable length array");
+	pedwarn (input_location, OPT_Wvla,
+		 "ISO C++ forbids variable length array");
     }
   else if (warn_vla > 0)
     {
       if (name)
-	warning (OPT_Wvla, 
-                 "variable length array %qD is used", name);
+	warning_at (loc, OPT_Wvla, 
+		    "variable length array %qD is used", name);
       else
 	warning (OPT_Wvla, 
                  "variable length array is used");
@@ -9821,6 +9842,12 @@ fold_sizeof_expr (tree t)
   return itype;
 }
 
+tree
+compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
+{
+  return compute_array_index_type_loc (input_location, name, size, complain);
+}
+
 /* Returns the scope (if any) in which the entity declared by
    DECLARATOR will be located.  If the entity was declared with an
    unqualified name, NULL_TREE is returned.  */
@@ -9922,7 +9949,8 @@ create_array_type_for_decl (tree name, tree type,
 
   /* Figure out the index type for the array.  */
   if (size)
-    itype = compute_array_index_type (name, size, tf_warning_or_error);
+    itype = compute_array_index_type_loc (loc, name, size,
+					  tf_warning_or_error);
 
   /* [dcl.array]
      T is called the array element type; this type shall not be [...] an
Index: testsuite/g++.dg/cpp0x/constexpr-47969.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-47969.C	(revision 266555)
+++ testsuite/g++.dg/cpp0x/constexpr-47969.C	(working copy)
@@ -8,4 +8,5 @@ struct A
 
 constexpr A a = A();
 
-int ar[a]; // { dg-error "could not convert|has non-integral type" }
+int ar[a]; // { dg-error "could not convert" }
+// { dg-error "5:size of array .ar. has non-integral" "" { target c++11 } .-1 }
Index: testsuite/g++.dg/cpp0x/constexpr-48324.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-48324.C	(revision 266555)
+++ testsuite/g++.dg/cpp0x/constexpr-48324.C	(working copy)
@@ -10,4 +10,4 @@ constexpr const int& to_ref(int i) {
   return S(i).val; // { dg-warning "reference to temporary" }
 }
 
-constexpr int ary[to_ref(98)] = { }; // { dg-error "not an integral" }
+constexpr int ary[to_ref(98)] = { }; // { dg-error "25:size of array .ary. is not an integral" }
Index: testsuite/g++.dg/cpp0x/constexpr-base6b.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-base6b.C	(nonexistent)
+++ testsuite/g++.dg/cpp0x/constexpr-base6b.C	(working copy)
@@ -0,0 +1,13 @@
+// CWG issue 2310
+// { dg-do compile { target c++11 } }
+
+template<typename A, typename B> struct check_derived_from { 
+  static A a; 
+  static constexpr B *p = &a;	// { dg-error "cannot convert" }
+  int ar[p-p+1];  // { dg-error "13:size of array is not an integral constant-expression" }
+}; 
+struct W { int i; }; 
+struct Z : W
+{
+  check_derived_from<Z, W> cdf;
+};
Index: testsuite/g++.dg/cpp0x/constexpr-ex2.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-ex2.C	(revision 266555)
+++ testsuite/g++.dg/cpp0x/constexpr-ex2.C	(working copy)
@@ -18,5 +18,5 @@ constexpr A a = 42;
 
 X<a> x;	    // OK: unique conversion to int
 int ar[X<a>::i]; // also OK
-int ary[a]; // { dg-error "could not convert|ambiguous|conversion|array" } ambiguous conversion
-
+int ary[a]; // { dg-error "could not convert" } ambiguous conversion
+// { dg-error "5:size of array .ary. has non-integral" "" { target c++11 } .-1 }
Index: testsuite/g++.dg/cpp0x/scoped_enum2.C
===================================================================
--- testsuite/g++.dg/cpp0x/scoped_enum2.C	(revision 266555)
+++ testsuite/g++.dg/cpp0x/scoped_enum2.C	(working copy)
@@ -4,7 +4,8 @@ enum class E { e = 10 };
 enum E2 { e2 = 10 };
 
 struct C {
-  int arr[E::e];    // { dg-error "could not convert|non-integral type" }
+  int arr[E::e];    // { dg-error "could not convert" }
+// { dg-error "7:size of array .arr. has non-integral" "" { target c++11 } .-1 }
   int arr2[E2::e2]; // OK
   int i: E::e;	    // { dg-error "could not convert|non-integral type" }
   int i2: E2::e2;   // OK
Index: testsuite/g++.dg/cpp1y/pr63996.C
===================================================================
--- testsuite/g++.dg/cpp1y/pr63996.C	(revision 266555)
+++ testsuite/g++.dg/cpp1y/pr63996.C	(working copy)
@@ -4,7 +4,7 @@
 constexpr int
 foo (int i)
 {
-  int a[i] = { }; // { dg-error "forbids variable length" }
+  int a[i] = { }; // { dg-error "7:ISO C\\+\\+ forbids variable length array .a" }
 }
 
 constexpr int j = foo (1); // { dg-error "flows off the end|in .constexpr. expansion of" }
Index: testsuite/g++.dg/ext/constexpr-vla5.C
===================================================================
--- testsuite/g++.dg/ext/constexpr-vla5.C	(revision 266555)
+++ testsuite/g++.dg/ext/constexpr-vla5.C	(working copy)
@@ -4,5 +4,5 @@
 void foo(int i)
 {
   constexpr char x[i] = "";	// { dg-error "18:.constexpr. variable .x. has variably-modified type" }
-// { dg-error "ISO C\\+\\+ forbids variable length array .x" "" { target c++11 } .-1 }  
+// { dg-error "18:ISO C\\+\\+ forbids variable length array .x" "" { target c++11 } .-1 }  
 }
Index: testsuite/g++.dg/ext/stmtexpr15.C
===================================================================
--- testsuite/g++.dg/ext/stmtexpr15.C	(revision 266555)
+++ testsuite/g++.dg/ext/stmtexpr15.C	(working copy)
@@ -3,5 +3,6 @@
 
 void foo()
 {
-  int x[({ return; })];		// { dg-error "could not convert|non-integral" }
+  int x[({ return; })];		// { dg-error "could not convert" }
+// { dg-error "12:size of array .x. has non-integral" "" { target *-*-* } .-1 }  
 }
Index: testsuite/g++.dg/ext/vla1.C
===================================================================
--- testsuite/g++.dg/ext/vla1.C	(revision 266555)
+++ testsuite/g++.dg/ext/vla1.C	(working copy)
@@ -9,7 +9,7 @@ class A { A (int); };
 
 A::A (int i)
 {
-  int ar[1][i];    // { dg-error "array" }
+  int ar[1][i];    // { dg-error "7:ISO C\\+\\+ forbids variable length array .ar" }
 
   ar[0][0] = 0;
 }
@@ -19,7 +19,8 @@ class B { B (int); };
 B::B (int i)
 {
   struct S {
-    int ar[1][i];  // { dg-error "array" }
+    int ar[1][i];  // { dg-error "9:size of array .ar. is not an integral" "" { target c++11 } }
+// { dg-error "array bound" "" { target c++98_only } .-1 }
   } s;
 
   s.ar[0][0] = 0;  // { dg-prune-output "no member" }
Index: testsuite/g++.dg/other/fold1.C
===================================================================
--- testsuite/g++.dg/other/fold1.C	(revision 266555)
+++ testsuite/g++.dg/other/fold1.C	(working copy)
@@ -4,5 +4,5 @@
 struct A
 {
     static const int i = i;  // { dg-error "not declared" }
-    int x[i];		     // { dg-error "constant-expression|narrowing conversion" }
+    int x[i];		     // { dg-error "9:size of array .x. is not an integral constant-expression" }
 };
Index: testsuite/g++.dg/parse/array-size2.C
===================================================================
--- testsuite/g++.dg/parse/array-size2.C	(revision 266555)
+++ testsuite/g++.dg/parse/array-size2.C	(working copy)
@@ -14,7 +14,7 @@ extern void bar (char *, char *);
 void
 foo (void)
 {
-  char g[(char *) &((struct S *) 0)->b - (char *) 0]; // { dg-error "constant|narrowing conversion" }
-  char h[(__SIZE_TYPE__) &((struct S *) 8)->b];	      // { dg-error "constant" }
+  char g[(char *) &((struct S *) 0)->b - (char *) 0]; // { dg-error "40:size of array .g. is not an integral constant-expression" }
+  char h[(__SIZE_TYPE__) &((struct S *) 8)->b];	      // { dg-error "10:size of array .h. is not an integral constant-expression" }
   bar (g, h);
 }
Index: testsuite/g++.dg/parse/crash36.C
===================================================================
--- testsuite/g++.dg/parse/crash36.C	(revision 266555)
+++ testsuite/g++.dg/parse/crash36.C	(working copy)
@@ -9,4 +9,4 @@ template <typename... T> struct A	// { dg-warning
   static const int i = sizeof (++t);	// { dg-error "was not declared in this scope" }
 };
 
-int x[A <int>::i];		// { dg-error "constant-expression" }
+int x[A <int>::i];		// { dg-error "5:size of array .x. is not an integral constant-expression" }
Index: testsuite/g++.dg/ubsan/pr81530.C
===================================================================
--- testsuite/g++.dg/ubsan/pr81530.C	(revision 266555)
+++ testsuite/g++.dg/ubsan/pr81530.C	(working copy)
@@ -2,4 +2,4 @@
 /* { dg-do compile } */
 /* { dg-options "-fsanitize=undefined" } */
 
-int a[(long) 4e20]; /* { dg-error "size of array .a. is (too large|negative)" } */
+int a[(long) 4e20]; /* { dg-error "7:size of array .a. is (too large|negative)" } */
Index: testsuite/g++.dg/warn/Wvla-1.C
===================================================================
--- testsuite/g++.dg/warn/Wvla-1.C	(revision 266555)
+++ testsuite/g++.dg/warn/Wvla-1.C	(working copy)
@@ -4,5 +4,5 @@
 
 void func (int i)
 {
-  int array[i]; /* { dg-warning "variable length array 'array' is used" } */
+  int array[i]; /* { dg-warning "7:variable length array 'array' is used" } */
 }
Index: testsuite/g++.dg/warn/Wvla-2.C
===================================================================
--- testsuite/g++.dg/warn/Wvla-2.C	(revision 266555)
+++ testsuite/g++.dg/warn/Wvla-2.C	(working copy)
@@ -3,5 +3,5 @@
 
 void func (int i)
 {
-  int array[i]; /* { dg-error "ISO C.* forbids variable.* array 'array'" } */
+  int array[i]; /* { dg-error "7:ISO C.* forbids variable.* array 'array'" } */
 }
Index: testsuite/g++.old-deja/g++.brendan/array1.C
===================================================================
--- testsuite/g++.old-deja/g++.brendan/array1.C	(revision 266555)
+++ testsuite/g++.old-deja/g++.brendan/array1.C	(working copy)
@@ -2,5 +2,5 @@
 // GROUPS passed array-bindings
 
 extern "C" int printf (const char *, ...);
-char array[~(~((__SIZE_TYPE__)0ul)>>1)|~(((__SIZE_TYPE__)0ul)>>3)];  // { dg-error "" } overflow in array dimension.*
+char array[~(~((__SIZE_TYPE__)0ul)>>1)|~(((__SIZE_TYPE__)0ul)>>3)];  // { dg-error "39:size of array .array. is negative" } overflow in array dimension.*
 int main () { printf ("PASS\n"); return 0; }
Index: testsuite/g++.old-deja/g++.bugs/900402_02.C
===================================================================
--- testsuite/g++.old-deja/g++.bugs/900402_02.C	(revision 266555)
+++ testsuite/g++.old-deja/g++.bugs/900402_02.C	(working copy)
@@ -6,17 +6,17 @@
 
 // keywords: arrays, array bound, zero length
 
-typedef int array_type[0];		// { dg-error "zero-size array" }
+typedef int array_type[0];		// { dg-error "13:ISO C\\+\\+ forbids zero-size array" }
 
-int array_object_1[0];			// { dg-error "zero-size array" }
+int array_object_1[0];			// { dg-error "5:ISO C\\+\\+ forbids zero-size array" }
 
-void function_0 (int formal_array[0])	// { dg-error "zero-size array" }
+void function_0 (int formal_array[0])	// { dg-error "22:ISO C\\+\\+ forbids zero-size array" }
 {
 }
 
 void function_2 ()
 {
-  int local_object_array_0[0];		// { dg-error "zero-size array" }
+  int local_object_array_0[0];		// { dg-error "7:ISO C\\+\\+ forbids zero-size array" }
 }
 
 int main () { return 0; }
Index: testsuite/g++.old-deja/g++.law/init3.C
===================================================================
--- testsuite/g++.old-deja/g++.law/init3.C	(revision 266555)
+++ testsuite/g++.old-deja/g++.law/init3.C	(working copy)
@@ -8,5 +8,5 @@
 
 int main() {
 int offset;
-char buf[offset]=""; // { dg-error "" } ansi forbids variable arrays
+char buf[offset]=""; // { dg-error "6:ISO C\\+\\+ forbids variable length array .buf" } ansi forbids variable arrays
 }
Index: testsuite/g++.old-deja/g++.mike/p6149.C
===================================================================
--- testsuite/g++.old-deja/g++.mike/p6149.C	(revision 266555)
+++ testsuite/g++.old-deja/g++.mike/p6149.C	(working copy)
@@ -1,4 +1,4 @@
 // { dg-do assemble  }
 // prms-id: 6149
 
-int a[3 - sizeof(double)];	// { dg-error "" } 
+int a[3 - sizeof(double)];	// { dg-error "9:size of array .a. is negative" }
Jason Merrill Nov. 29, 2018, 4:13 p.m. UTC | #5
On 11/29/18 10:22 AM, Paolo Carlini wrote:
> Hi,
> 
> On 29/11/18 03:01, Jason Merrill wrote:
>> On 11/6/18 4:01 AM, Paolo Carlini wrote:
>>> when I improved create_array_type_for_decl I didn't notice that it 
>>> calls compute_array_index_type as helper, which simply needs to have 
>>> the location information propagated. Tested x86_64-linux.
>>
>> This looks like it will use the declarator-id location in diagnostics 
>> about the array bound expression, which isn't optimal; if 'size' has a 
>> location, we should use that instead.
> 
> Yes. The below, for all the error messages talking about "size", uses 
> the location of "size" and either the passed location or input_location 
> as fall-back. This, afaics, also matches the behavior of clang. There 
> are a few minor subtleties: 1- A first version of the patch didn't 
> exploit the location of "size" in the unnamed cases, but doing that 
> actually helps for testcases like the new constexpr-base6b.C; 2- It's 
> important to use the original "size" - as saved in "osize" - otherwise 
> after the folding the location information is lost in some cases (eg, 
> happens for the ubsan testcase and a couple of g++.old-deja tests); 3- I 
> didn't change the warnings about variable length arrays to exploit the 
> location of "size", because they don't explicitly talk about the size - 
> that, by the way, appears to match clang's behavior.

> +	    error_at (cp_expr_loc_or_loc (osize, loc),
....
> +	    error_at (cp_expr_loc_or_loc (osize, input_location),

Let's compute the location we want to use once at the top of the 
function.  And maybe rename the 'loc' parameter to name_loc.

Jason
Paolo Carlini Nov. 29, 2018, 7:09 p.m. UTC | #6
Hi,

On 29/11/18 17:13, Jason Merrill wrote:
> + error_at (cp_expr_loc_or_loc (osize, loc),
> ....
>> +        error_at (cp_expr_loc_or_loc (osize, input_location),
>
> Let's compute the location we want to use once at the top of the 
> function.  And maybe rename the 'loc' parameter to name_loc.

Makes sense. Thus I tested the attached.

Thanks, Paolo.

////////////////////
Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 266634)
+++ cp/decl.c	(working copy)
@@ -9621,8 +9621,9 @@ fold_sizeof_expr (tree t)
    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)
+static tree
+compute_array_index_type_loc (location_t name_loc, tree name, tree size,
+			      tsubst_flags_t complain)
 {
   tree itype;
   tree osize = size;
@@ -9630,6 +9631,8 @@ fold_sizeof_expr (tree t)
   if (error_operand_p (size))
     return error_mark_node;
 
+  location_t loc = cp_expr_loc_or_loc (size, name ? name_loc : input_location);
+
   if (!type_dependent_expression_p (size))
     {
       osize = size = mark_rvalue_use (size);
@@ -9658,9 +9661,10 @@ fold_sizeof_expr (tree t)
 	  if (!(complain & tf_error))
 	    return error_mark_node;
 	  if (name)
-	    error ("size of array %qD has non-integral type %qT", name, type);
+	    error_at (loc, "size of array %qD has non-integral type %qT",
+		      name, type);
 	  else
-	    error ("size of array has non-integral type %qT", type);
+	    error_at (loc, "size of array has non-integral type %qT", type);
 	  size = integer_one_node;
 	}
     }
@@ -9689,8 +9693,14 @@ fold_sizeof_expr (tree t)
     {
       tree folded = cp_fully_fold (size);
       if (TREE_CODE (folded) == INTEGER_CST)
-	pedwarn (input_location, OPT_Wpedantic,
-		 "size of array is not an integral constant-expression");
+	{
+	  if (name)
+	    pedwarn (loc, OPT_Wpedantic, "size of array %qD is not an "
+		     "integral constant-expression", name);
+	  else
+	    pedwarn (loc, OPT_Wpedantic,
+		     "size of array is not an integral constant-expression");
+	}
       /* Use the folded result for VLAs, too; it will have resolved
 	 SIZEOF_EXPR.  */
       size = folded;
@@ -9706,9 +9716,9 @@ fold_sizeof_expr (tree t)
 	    return error_mark_node;
 
 	  if (name)
-	    error ("size of array %qD is negative", name);
+	    error_at (loc, "size of array %qD is negative", name);
 	  else
-	    error ("size of array is negative");
+	    error_at (loc, "size of array is negative");
 	  size = integer_one_node;
 	}
       /* As an extension we allow zero-sized arrays.  */
@@ -9722,9 +9732,11 @@ fold_sizeof_expr (tree t)
 	  else if (in_system_header_at (input_location))
 	    /* Allow them in system headers because glibc uses them.  */;
 	  else if (name)
-	    pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array %qD", name);
+	    pedwarn (loc, OPT_Wpedantic,
+		     "ISO C++ forbids zero-size array %qD", name);
 	  else
-	    pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array");
+	    pedwarn (loc, OPT_Wpedantic,
+		     "ISO C++ forbids zero-size array");
 	}
     }
   else if (TREE_CONSTANT (size)
@@ -9737,24 +9749,27 @@ fold_sizeof_expr (tree t)
 	return error_mark_node;
       /* `(int) &fn' is not a valid array bound.  */
       if (name)
-	error ("size of array %qD is not an integral constant-expression",
-	       name);
+	error_at (loc,
+		  "size of array %qD is not an integral constant-expression",
+		  name);
       else
-	error ("size of array is not an integral constant-expression");
+	error_at (loc, "size of array is not an integral constant-expression");
       size = integer_one_node;
     }
   else if (pedantic && warn_vla != 0)
     {
       if (name)
-	pedwarn (input_location, OPT_Wvla, "ISO C++ forbids variable length array %qD", name);
+	pedwarn (name_loc, OPT_Wvla,
+		 "ISO C++ forbids variable length array %qD", name);
       else
-	pedwarn (input_location, OPT_Wvla, "ISO C++ forbids variable length array");
+	pedwarn (input_location, OPT_Wvla,
+		 "ISO C++ forbids variable length array");
     }
   else if (warn_vla > 0)
     {
       if (name)
-	warning (OPT_Wvla, 
-                 "variable length array %qD is used", name);
+	warning_at (name_loc, OPT_Wvla, 
+		    "variable length array %qD is used", name);
       else
 	warning (OPT_Wvla, 
                  "variable length array is used");
@@ -9821,6 +9836,12 @@ fold_sizeof_expr (tree t)
   return itype;
 }
 
+tree
+compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
+{
+  return compute_array_index_type_loc (input_location, name, size, complain);
+}
+
 /* Returns the scope (if any) in which the entity declared by
    DECLARATOR will be located.  If the entity was declared with an
    unqualified name, NULL_TREE is returned.  */
@@ -9922,7 +9943,8 @@ create_array_type_for_decl (tree name, tree type,
 
   /* Figure out the index type for the array.  */
   if (size)
-    itype = compute_array_index_type (name, size, tf_warning_or_error);
+    itype = compute_array_index_type_loc (loc, name, size,
+					  tf_warning_or_error);
 
   /* [dcl.array]
      T is called the array element type; this type shall not be [...] an
Index: testsuite/g++.dg/cpp0x/constexpr-47969.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-47969.C	(revision 266634)
+++ testsuite/g++.dg/cpp0x/constexpr-47969.C	(working copy)
@@ -8,4 +8,5 @@ struct A
 
 constexpr A a = A();
 
-int ar[a]; // { dg-error "could not convert|has non-integral type" }
+int ar[a]; // { dg-error "could not convert" }
+// { dg-error "5:size of array .ar. has non-integral" "" { target c++11 } .-1 }
Index: testsuite/g++.dg/cpp0x/constexpr-48324.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-48324.C	(revision 266634)
+++ testsuite/g++.dg/cpp0x/constexpr-48324.C	(working copy)
@@ -10,4 +10,4 @@ constexpr const int& to_ref(int i) {
   return S(i).val; // { dg-warning "reference to temporary" }
 }
 
-constexpr int ary[to_ref(98)] = { }; // { dg-error "not an integral" }
+constexpr int ary[to_ref(98)] = { }; // { dg-error "25:size of array .ary. is not an integral" }
Index: testsuite/g++.dg/cpp0x/constexpr-base6b.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-base6b.C	(nonexistent)
+++ testsuite/g++.dg/cpp0x/constexpr-base6b.C	(working copy)
@@ -0,0 +1,13 @@
+// CWG issue 2310
+// { dg-do compile { target c++11 } }
+
+template<typename A, typename B> struct check_derived_from { 
+  static A a; 
+  static constexpr B *p = &a;	// { dg-error "cannot convert" }
+  int ar[p-p+1];  // { dg-error "13:size of array is not an integral constant-expression" }
+}; 
+struct W { int i; }; 
+struct Z : W
+{
+  check_derived_from<Z, W> cdf;
+};
Index: testsuite/g++.dg/cpp0x/constexpr-ex2.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-ex2.C	(revision 266634)
+++ testsuite/g++.dg/cpp0x/constexpr-ex2.C	(working copy)
@@ -18,5 +18,5 @@ constexpr A a = 42;
 
 X<a> x;	    // OK: unique conversion to int
 int ar[X<a>::i]; // also OK
-int ary[a]; // { dg-error "could not convert|ambiguous|conversion|array" } ambiguous conversion
-
+int ary[a]; // { dg-error "could not convert" } ambiguous conversion
+// { dg-error "5:size of array .ary. has non-integral" "" { target c++11 } .-1 }
Index: testsuite/g++.dg/cpp0x/scoped_enum2.C
===================================================================
--- testsuite/g++.dg/cpp0x/scoped_enum2.C	(revision 266634)
+++ testsuite/g++.dg/cpp0x/scoped_enum2.C	(working copy)
@@ -4,7 +4,8 @@ enum class E { e = 10 };
 enum E2 { e2 = 10 };
 
 struct C {
-  int arr[E::e];    // { dg-error "could not convert|non-integral type" }
+  int arr[E::e];    // { dg-error "could not convert" }
+// { dg-error "7:size of array .arr. has non-integral" "" { target c++11 } .-1 }
   int arr2[E2::e2]; // OK
   int i: E::e;	    // { dg-error "could not convert|non-integral type" }
   int i2: E2::e2;   // OK
Index: testsuite/g++.dg/cpp1y/pr63996.C
===================================================================
--- testsuite/g++.dg/cpp1y/pr63996.C	(revision 266634)
+++ testsuite/g++.dg/cpp1y/pr63996.C	(working copy)
@@ -4,7 +4,7 @@
 constexpr int
 foo (int i)
 {
-  int a[i] = { }; // { dg-error "forbids variable length" }
+  int a[i] = { }; // { dg-error "7:ISO C\\+\\+ forbids variable length array .a" }
 }
 
 constexpr int j = foo (1); // { dg-error "flows off the end|in .constexpr. expansion of" }
Index: testsuite/g++.dg/ext/constexpr-vla5.C
===================================================================
--- testsuite/g++.dg/ext/constexpr-vla5.C	(revision 266634)
+++ testsuite/g++.dg/ext/constexpr-vla5.C	(working copy)
@@ -4,5 +4,5 @@
 void foo(int i)
 {
   constexpr char x[i] = "";	// { dg-error "18:.constexpr. variable .x. has variably-modified type" }
-// { dg-error "ISO C\\+\\+ forbids variable length array .x" "" { target c++11 } .-1 }  
+// { dg-error "18:ISO C\\+\\+ forbids variable length array .x" "" { target c++11 } .-1 }  
 }
Index: testsuite/g++.dg/ext/stmtexpr15.C
===================================================================
--- testsuite/g++.dg/ext/stmtexpr15.C	(revision 266634)
+++ testsuite/g++.dg/ext/stmtexpr15.C	(working copy)
@@ -3,5 +3,6 @@
 
 void foo()
 {
-  int x[({ return; })];		// { dg-error "could not convert|non-integral" }
+  int x[({ return; })];		// { dg-error "could not convert" }
+// { dg-error "12:size of array .x. has non-integral" "" { target *-*-* } .-1 }  
 }
Index: testsuite/g++.dg/ext/vla1.C
===================================================================
--- testsuite/g++.dg/ext/vla1.C	(revision 266634)
+++ testsuite/g++.dg/ext/vla1.C	(working copy)
@@ -9,7 +9,7 @@ class A { A (int); };
 
 A::A (int i)
 {
-  int ar[1][i];    // { dg-error "array" }
+  int ar[1][i];    // { dg-error "7:ISO C\\+\\+ forbids variable length array .ar" }
 
   ar[0][0] = 0;
 }
@@ -19,7 +19,8 @@ class B { B (int); };
 B::B (int i)
 {
   struct S {
-    int ar[1][i];  // { dg-error "array" }
+    int ar[1][i];  // { dg-error "9:size of array .ar. is not an integral" "" { target c++11 } }
+// { dg-error "array bound" "" { target c++98_only } .-1 }
   } s;
 
   s.ar[0][0] = 0;  // { dg-prune-output "no member" }
Index: testsuite/g++.dg/other/fold1.C
===================================================================
--- testsuite/g++.dg/other/fold1.C	(revision 266634)
+++ testsuite/g++.dg/other/fold1.C	(working copy)
@@ -4,5 +4,5 @@
 struct A
 {
     static const int i = i;  // { dg-error "not declared" }
-    int x[i];		     // { dg-error "constant-expression|narrowing conversion" }
+    int x[i];		     // { dg-error "9:size of array .x. is not an integral constant-expression" }
 };
Index: testsuite/g++.dg/parse/array-size2.C
===================================================================
--- testsuite/g++.dg/parse/array-size2.C	(revision 266634)
+++ testsuite/g++.dg/parse/array-size2.C	(working copy)
@@ -14,7 +14,7 @@ extern void bar (char *, char *);
 void
 foo (void)
 {
-  char g[(char *) &((struct S *) 0)->b - (char *) 0]; // { dg-error "constant|narrowing conversion" }
-  char h[(__SIZE_TYPE__) &((struct S *) 8)->b];	      // { dg-error "constant" }
+  char g[(char *) &((struct S *) 0)->b - (char *) 0]; // { dg-error "40:size of array .g. is not an integral constant-expression" }
+  char h[(__SIZE_TYPE__) &((struct S *) 8)->b];	      // { dg-error "10:size of array .h. is not an integral constant-expression" }
   bar (g, h);
 }
Index: testsuite/g++.dg/parse/crash36.C
===================================================================
--- testsuite/g++.dg/parse/crash36.C	(revision 266634)
+++ testsuite/g++.dg/parse/crash36.C	(working copy)
@@ -9,4 +9,4 @@ template <typename... T> struct A	// { dg-warning
   static const int i = sizeof (++t);	// { dg-error "was not declared in this scope" }
 };
 
-int x[A <int>::i];		// { dg-error "constant-expression" }
+int x[A <int>::i];		// { dg-error "5:size of array .x. is not an integral constant-expression" }
Index: testsuite/g++.dg/ubsan/pr81530.C
===================================================================
--- testsuite/g++.dg/ubsan/pr81530.C	(revision 266634)
+++ testsuite/g++.dg/ubsan/pr81530.C	(working copy)
@@ -2,4 +2,4 @@
 /* { dg-do compile } */
 /* { dg-options "-fsanitize=undefined" } */
 
-int a[(long) 4e20]; /* { dg-error "size of array .a. is (too large|negative)" } */
+int a[(long) 4e20]; /* { dg-error "7:size of array .a. is (too large|negative)" } */
Index: testsuite/g++.dg/warn/Wvla-1.C
===================================================================
--- testsuite/g++.dg/warn/Wvla-1.C	(revision 266634)
+++ testsuite/g++.dg/warn/Wvla-1.C	(working copy)
@@ -4,5 +4,5 @@
 
 void func (int i)
 {
-  int array[i]; /* { dg-warning "variable length array 'array' is used" } */
+  int array[i]; /* { dg-warning "7:variable length array 'array' is used" } */
 }
Index: testsuite/g++.dg/warn/Wvla-2.C
===================================================================
--- testsuite/g++.dg/warn/Wvla-2.C	(revision 266634)
+++ testsuite/g++.dg/warn/Wvla-2.C	(working copy)
@@ -3,5 +3,5 @@
 
 void func (int i)
 {
-  int array[i]; /* { dg-error "ISO C.* forbids variable.* array 'array'" } */
+  int array[i]; /* { dg-error "7:ISO C.* forbids variable.* array 'array'" } */
 }
Index: testsuite/g++.old-deja/g++.brendan/array1.C
===================================================================
--- testsuite/g++.old-deja/g++.brendan/array1.C	(revision 266634)
+++ testsuite/g++.old-deja/g++.brendan/array1.C	(working copy)
@@ -2,5 +2,5 @@
 // GROUPS passed array-bindings
 
 extern "C" int printf (const char *, ...);
-char array[~(~((__SIZE_TYPE__)0ul)>>1)|~(((__SIZE_TYPE__)0ul)>>3)];  // { dg-error "" } overflow in array dimension.*
+char array[~(~((__SIZE_TYPE__)0ul)>>1)|~(((__SIZE_TYPE__)0ul)>>3)];  // { dg-error "39:size of array .array. is negative" } overflow in array dimension.*
 int main () { printf ("PASS\n"); return 0; }
Index: testsuite/g++.old-deja/g++.bugs/900402_02.C
===================================================================
--- testsuite/g++.old-deja/g++.bugs/900402_02.C	(revision 266634)
+++ testsuite/g++.old-deja/g++.bugs/900402_02.C	(working copy)
@@ -6,17 +6,17 @@
 
 // keywords: arrays, array bound, zero length
 
-typedef int array_type[0];		// { dg-error "zero-size array" }
+typedef int array_type[0];		// { dg-error "13:ISO C\\+\\+ forbids zero-size array" }
 
-int array_object_1[0];			// { dg-error "zero-size array" }
+int array_object_1[0];			// { dg-error "5:ISO C\\+\\+ forbids zero-size array" }
 
-void function_0 (int formal_array[0])	// { dg-error "zero-size array" }
+void function_0 (int formal_array[0])	// { dg-error "22:ISO C\\+\\+ forbids zero-size array" }
 {
 }
 
 void function_2 ()
 {
-  int local_object_array_0[0];		// { dg-error "zero-size array" }
+  int local_object_array_0[0];		// { dg-error "7:ISO C\\+\\+ forbids zero-size array" }
 }
 
 int main () { return 0; }
Index: testsuite/g++.old-deja/g++.law/init3.C
===================================================================
--- testsuite/g++.old-deja/g++.law/init3.C	(revision 266634)
+++ testsuite/g++.old-deja/g++.law/init3.C	(working copy)
@@ -8,5 +8,5 @@
 
 int main() {
 int offset;
-char buf[offset]=""; // { dg-error "" } ansi forbids variable arrays
+char buf[offset]=""; // { dg-error "6:ISO C\\+\\+ forbids variable length array .buf" } ansi forbids variable arrays
 }
Index: testsuite/g++.old-deja/g++.mike/p6149.C
===================================================================
--- testsuite/g++.old-deja/g++.mike/p6149.C	(revision 266634)
+++ testsuite/g++.old-deja/g++.mike/p6149.C	(working copy)
@@ -1,4 +1,4 @@
 // { dg-do assemble  }
 // prms-id: 6149
 
-int a[3 - sizeof(double)];	// { dg-error "" } 
+int a[3 - sizeof(double)];	// { dg-error "9:size of array .a. is negative" }
Jason Merrill Nov. 29, 2018, 7:52 p.m. UTC | #7
On 11/29/18 2:09 PM, Paolo Carlini wrote:
> Hi,
> 
> On 29/11/18 17:13, Jason Merrill wrote:
>> + error_at (cp_expr_loc_or_loc (osize, loc),
>> ....
>>> +        error_at (cp_expr_loc_or_loc (osize, input_location),
>>
>> Let's compute the location we want to use once at the top of the 
>> function.  And maybe rename the 'loc' parameter to name_loc.
> 
> Makes sense. Thus I tested the attached.

OK.

Jason
diff mbox series

Patch

Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 265826)
+++ cp/decl.c	(working copy)
@@ -9621,8 +9621,9 @@  fold_sizeof_expr (tree t)
    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)
+static tree
+compute_array_index_type_loc (location_t loc, tree name, tree size,
+			      tsubst_flags_t complain)
 {
   tree itype;
   tree osize = size;
@@ -9658,7 +9659,8 @@  fold_sizeof_expr (tree t)
 	  if (!(complain & tf_error))
 	    return error_mark_node;
 	  if (name)
-	    error ("size of array %qD has non-integral type %qT", name, type);
+	    error_at (loc, "size of array %qD has non-integral type %qT",
+		      name, type);
 	  else
 	    error ("size of array has non-integral type %qT", type);
 	  size = integer_one_node;
@@ -9689,8 +9691,14 @@  fold_sizeof_expr (tree t)
     {
       tree folded = cp_fully_fold (size);
       if (TREE_CODE (folded) == INTEGER_CST)
-	pedwarn (input_location, OPT_Wpedantic,
-		 "size of array is not an integral constant-expression");
+	{
+	  if (name)
+	    pedwarn (loc, OPT_Wpedantic, "size of array %qD is not an "
+		     "integral constant-expression", name);
+	  else
+	    pedwarn (input_location, OPT_Wpedantic,
+		     "size of array is not an integral constant-expression");
+	}
       /* Use the folded result for VLAs, too; it will have resolved
 	 SIZEOF_EXPR.  */
       size = folded;
@@ -9706,7 +9714,7 @@  fold_sizeof_expr (tree t)
 	    return error_mark_node;
 
 	  if (name)
-	    error ("size of array %qD is negative", name);
+	    error_at (loc, "size of array %qD is negative", name);
 	  else
 	    error ("size of array is negative");
 	  size = integer_one_node;
@@ -9722,9 +9730,11 @@  fold_sizeof_expr (tree t)
 	  else if (in_system_header_at (input_location))
 	    /* Allow them in system headers because glibc uses them.  */;
 	  else if (name)
-	    pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array %qD", name);
+	    pedwarn (loc, OPT_Wpedantic,
+		     "ISO C++ forbids zero-size array %qD", name);
 	  else
-	    pedwarn (input_location, OPT_Wpedantic, "ISO C++ forbids zero-size array");
+	    pedwarn (input_location, OPT_Wpedantic,
+		     "ISO C++ forbids zero-size array");
 	}
     }
   else if (TREE_CONSTANT (size)
@@ -9737,8 +9747,9 @@  fold_sizeof_expr (tree t)
 	return error_mark_node;
       /* `(int) &fn' is not a valid array bound.  */
       if (name)
-	error ("size of array %qD is not an integral constant-expression",
-	       name);
+	error_at (loc,
+		  "size of array %qD is not an integral constant-expression",
+		  name);
       else
 	error ("size of array is not an integral constant-expression");
       size = integer_one_node;
@@ -9746,15 +9757,17 @@  fold_sizeof_expr (tree t)
   else if (pedantic && warn_vla != 0)
     {
       if (name)
-	pedwarn (input_location, OPT_Wvla, "ISO C++ forbids variable length array %qD", name);
+	pedwarn (loc, OPT_Wvla,
+		 "ISO C++ forbids variable length array %qD", name);
       else
-	pedwarn (input_location, OPT_Wvla, "ISO C++ forbids variable length array");
+	pedwarn (input_location, OPT_Wvla,
+		 "ISO C++ forbids variable length array");
     }
   else if (warn_vla > 0)
     {
       if (name)
-	warning (OPT_Wvla, 
-                 "variable length array %qD is used", name);
+	warning_at (loc, OPT_Wvla, 
+		    "variable length array %qD is used", name);
       else
 	warning (OPT_Wvla, 
                  "variable length array is used");
@@ -9821,6 +9834,12 @@  fold_sizeof_expr (tree t)
   return itype;
 }
 
+tree
+compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
+{
+  return compute_array_index_type_loc (input_location, name, size, complain);
+}
+
 /* Returns the scope (if any) in which the entity declared by
    DECLARATOR will be located.  If the entity was declared with an
    unqualified name, NULL_TREE is returned.  */
@@ -9922,7 +9941,8 @@  create_array_type_for_decl (tree name, tree type,
 
   /* Figure out the index type for the array.  */
   if (size)
-    itype = compute_array_index_type (name, size, tf_warning_or_error);
+    itype = compute_array_index_type_loc (loc, name, size,
+					  tf_warning_or_error);
 
   /* [dcl.array]
      T is called the array element type; this type shall not be [...] an
Index: testsuite/g++.dg/cpp0x/constexpr-47969.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-47969.C	(revision 265826)
+++ testsuite/g++.dg/cpp0x/constexpr-47969.C	(working copy)
@@ -8,4 +8,5 @@  struct A
 
 constexpr A a = A();
 
-int ar[a]; // { dg-error "could not convert|has non-integral type" }
+int ar[a]; // { dg-error "could not convert" }
+// { dg-error "5:size of array .ar. has non-integral" "" { target c++11 } .-1 }
Index: testsuite/g++.dg/cpp0x/constexpr-48324.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-48324.C	(revision 265826)
+++ testsuite/g++.dg/cpp0x/constexpr-48324.C	(working copy)
@@ -10,4 +10,4 @@  constexpr const int& to_ref(int i) {
   return S(i).val; // { dg-warning "reference to temporary" }
 }
 
-constexpr int ary[to_ref(98)] = { }; // { dg-error "not an integral" }
+constexpr int ary[to_ref(98)] = { }; // { dg-error "15:size of array .ary. is not an integral" }
Index: testsuite/g++.dg/cpp0x/constexpr-ex2.C
===================================================================
--- testsuite/g++.dg/cpp0x/constexpr-ex2.C	(revision 265826)
+++ testsuite/g++.dg/cpp0x/constexpr-ex2.C	(working copy)
@@ -18,5 +18,5 @@  constexpr A a = 42;
 
 X<a> x;	    // OK: unique conversion to int
 int ar[X<a>::i]; // also OK
-int ary[a]; // { dg-error "could not convert|ambiguous|conversion|array" } ambiguous conversion
-
+int ary[a]; // { dg-error "could not convert" } ambiguous conversion
+// { dg-error "5:size of array .ary. has non-integral" "" { target c++11 } .-1 }
Index: testsuite/g++.dg/cpp0x/scoped_enum2.C
===================================================================
--- testsuite/g++.dg/cpp0x/scoped_enum2.C	(revision 265826)
+++ testsuite/g++.dg/cpp0x/scoped_enum2.C	(working copy)
@@ -4,7 +4,8 @@  enum class E { e = 10 };
 enum E2 { e2 = 10 };
 
 struct C {
-  int arr[E::e];    // { dg-error "could not convert|non-integral type" }
+  int arr[E::e];    // { dg-error "could not convert" }
+// { dg-error "7:size of array .arr. has non-integral" "" { target c++11 } .-1 }
   int arr2[E2::e2]; // OK
   int i: E::e;	    // { dg-error "could not convert|non-integral type" }
   int i2: E2::e2;   // OK
Index: testsuite/g++.dg/cpp1y/pr63996.C
===================================================================
--- testsuite/g++.dg/cpp1y/pr63996.C	(revision 265826)
+++ testsuite/g++.dg/cpp1y/pr63996.C	(working copy)
@@ -4,7 +4,7 @@ 
 constexpr int
 foo (int i)
 {
-  int a[i] = { }; // { dg-error "forbids variable length" }
+  int a[i] = { }; // { dg-error "7:ISO C\\+\\+ forbids variable length array .a" }
 }
 
 constexpr int j = foo (1); // { dg-error "flows off the end|in .constexpr. expansion of" }
Index: testsuite/g++.dg/ext/constexpr-vla5.C
===================================================================
--- testsuite/g++.dg/ext/constexpr-vla5.C	(revision 265826)
+++ testsuite/g++.dg/ext/constexpr-vla5.C	(working copy)
@@ -3,5 +3,6 @@ 
 
 void foo(int i)
 {
-  constexpr char x[i] = "";	// { dg-error "" }
+  constexpr char x[i] = "";	// { dg-error ".constexpr. variable .x" }
+// { dg-error "18:ISO C\\+\\+ forbids variable length array .x" "" { target c++11 } .-1 }  
 }
Index: testsuite/g++.dg/ext/stmtexpr15.C
===================================================================
--- testsuite/g++.dg/ext/stmtexpr15.C	(revision 265826)
+++ testsuite/g++.dg/ext/stmtexpr15.C	(working copy)
@@ -3,5 +3,6 @@ 
 
 void foo()
 {
-  int x[({ return; })];		// { dg-error "could not convert|non-integral" }
+  int x[({ return; })];		// { dg-error "could not convert" }
+// { dg-error "7:size of array .x. has non-integral" "" { target *-*-* } .-1 }  
 }
Index: testsuite/g++.dg/ext/vla1.C
===================================================================
--- testsuite/g++.dg/ext/vla1.C	(revision 265826)
+++ testsuite/g++.dg/ext/vla1.C	(working copy)
@@ -9,7 +9,7 @@  class A { A (int); };
 
 A::A (int i)
 {
-  int ar[1][i];    // { dg-error "array" }
+  int ar[1][i];    // { dg-error "7:ISO C\\+\\+ forbids variable length array .ar" }
 
   ar[0][0] = 0;
 }
@@ -19,7 +19,8 @@  class B { B (int); };
 B::B (int i)
 {
   struct S {
-    int ar[1][i];  // { dg-error "array" }
+    int ar[1][i];  // { dg-error "9:size of array .ar. is not an integral" "" { target c++11 } }
+// { dg-error "array bound" "" { target c++98_only } .-1 }
   } s;
 
   s.ar[0][0] = 0;  // { dg-prune-output "no member" }
Index: testsuite/g++.dg/other/fold1.C
===================================================================
--- testsuite/g++.dg/other/fold1.C	(revision 265826)
+++ testsuite/g++.dg/other/fold1.C	(working copy)
@@ -4,5 +4,5 @@ 
 struct A
 {
     static const int i = i;  // { dg-error "not declared" }
-    int x[i];		     // { dg-error "constant-expression|narrowing conversion" }
+    int x[i];		     // { dg-error "9:size of array .x. is not an integral constant-expression" }
 };
Index: testsuite/g++.dg/parse/array-size2.C
===================================================================
--- testsuite/g++.dg/parse/array-size2.C	(revision 265826)
+++ testsuite/g++.dg/parse/array-size2.C	(working copy)
@@ -14,7 +14,7 @@  extern void bar (char *, char *);
 void
 foo (void)
 {
-  char g[(char *) &((struct S *) 0)->b - (char *) 0]; // { dg-error "constant|narrowing conversion" }
-  char h[(__SIZE_TYPE__) &((struct S *) 8)->b];	      // { dg-error "constant" }
+  char g[(char *) &((struct S *) 0)->b - (char *) 0]; // { dg-error "8:size of array .g. is not an integral constant-expression" }
+  char h[(__SIZE_TYPE__) &((struct S *) 8)->b];	      // { dg-error "8:size of array .h. is not an integral constant-expression" }
   bar (g, h);
 }
Index: testsuite/g++.dg/parse/crash36.C
===================================================================
--- testsuite/g++.dg/parse/crash36.C	(revision 265826)
+++ testsuite/g++.dg/parse/crash36.C	(working copy)
@@ -9,4 +9,4 @@  template <typename... T> struct A	// { dg-warning
   static const int i = sizeof (++t);	// { dg-error "was not declared in this scope" }
 };
 
-int x[A <int>::i];		// { dg-error "constant-expression" }
+int x[A <int>::i];		// { dg-error "5:size of array .x. is not an integral constant-expression" }
Index: testsuite/g++.dg/ubsan/pr81530.C
===================================================================
--- testsuite/g++.dg/ubsan/pr81530.C	(revision 265826)
+++ testsuite/g++.dg/ubsan/pr81530.C	(working copy)
@@ -2,4 +2,4 @@ 
 /* { dg-do compile } */
 /* { dg-options "-fsanitize=undefined" } */
 
-int a[(long) 4e20]; /* { dg-error "size of array .a. is (too large|negative)" } */
+int a[(long) 4e20]; /* { dg-error "5:size of array .a. is (too large|negative)" } */
Index: testsuite/g++.dg/warn/Wvla-1.C
===================================================================
--- testsuite/g++.dg/warn/Wvla-1.C	(revision 265826)
+++ testsuite/g++.dg/warn/Wvla-1.C	(working copy)
@@ -4,5 +4,5 @@ 
 
 void func (int i)
 {
-  int array[i]; /* { dg-warning "variable length array 'array' is used" } */
+  int array[i]; /* { dg-warning "7:variable length array 'array' is used" } */
 }
Index: testsuite/g++.dg/warn/Wvla-2.C
===================================================================
--- testsuite/g++.dg/warn/Wvla-2.C	(revision 265826)
+++ testsuite/g++.dg/warn/Wvla-2.C	(working copy)
@@ -3,5 +3,5 @@ 
 
 void func (int i)
 {
-  int array[i]; /* { dg-error "ISO C.* forbids variable.* array 'array'" } */
+  int array[i]; /* { dg-error "7:ISO C.* forbids variable.* array 'array'" } */
 }
Index: testsuite/g++.old-deja/g++.brendan/array1.C
===================================================================
--- testsuite/g++.old-deja/g++.brendan/array1.C	(revision 265826)
+++ testsuite/g++.old-deja/g++.brendan/array1.C	(working copy)
@@ -2,5 +2,5 @@ 
 // GROUPS passed array-bindings
 
 extern "C" int printf (const char *, ...);
-char array[~(~((__SIZE_TYPE__)0ul)>>1)|~(((__SIZE_TYPE__)0ul)>>3)];  // { dg-error "" } overflow in array dimension.*
+char array[~(~((__SIZE_TYPE__)0ul)>>1)|~(((__SIZE_TYPE__)0ul)>>3)];  // { dg-error "6:size of array .array. is negative" } overflow in array dimension.*
 int main () { printf ("PASS\n"); return 0; }
Index: testsuite/g++.old-deja/g++.bugs/900402_02.C
===================================================================
--- testsuite/g++.old-deja/g++.bugs/900402_02.C	(revision 265826)
+++ testsuite/g++.old-deja/g++.bugs/900402_02.C	(working copy)
@@ -6,17 +6,17 @@ 
 
 // keywords: arrays, array bound, zero length
 
-typedef int array_type[0];		// { dg-error "zero-size array" }
+typedef int array_type[0];		// { dg-error "13:ISO C\\+\\+ forbids zero-size array" }
 
-int array_object_1[0];			// { dg-error "zero-size array" }
+int array_object_1[0];			// { dg-error "5:ISO C\\+\\+ forbids zero-size array" }
 
-void function_0 (int formal_array[0])	// { dg-error "zero-size array" }
+void function_0 (int formal_array[0])	// { dg-error "22:ISO C\\+\\+ forbids zero-size array" }
 {
 }
 
 void function_2 ()
 {
-  int local_object_array_0[0];		// { dg-error "zero-size array" }
+  int local_object_array_0[0];		// { dg-error "7:ISO C\\+\\+ forbids zero-size array" }
 }
 
 int main () { return 0; }
Index: testsuite/g++.old-deja/g++.law/init3.C
===================================================================
--- testsuite/g++.old-deja/g++.law/init3.C	(revision 265826)
+++ testsuite/g++.old-deja/g++.law/init3.C	(working copy)
@@ -8,5 +8,5 @@ 
 
 int main() {
 int offset;
-char buf[offset]=""; // { dg-error "" } ansi forbids variable arrays
+char buf[offset]=""; // { dg-error "6:ISO C\\+\\+ forbids variable length array .buf" } ansi forbids variable arrays
 }
Index: testsuite/g++.old-deja/g++.mike/p6149.C
===================================================================
--- testsuite/g++.old-deja/g++.mike/p6149.C	(revision 265826)
+++ testsuite/g++.old-deja/g++.mike/p6149.C	(working copy)
@@ -1,4 +1,4 @@ 
 // { dg-do assemble  }
 // prms-id: 6149
 
-int a[3 - sizeof(double)];	// { dg-error "" } 
+int a[3 - sizeof(double)];	// { dg-error "5:size of array .a. is negative" }