diff mbox series

PATCH: Updated error messages for ill-formed cases of array initialization by string literal

Message ID f32ff373-a4b7-5dd2-6918-1870dd3b498d@honermann.net
State New
Headers show
Series PATCH: Updated error messages for ill-formed cases of array initialization by string literal | expand

Commit Message

Tom Honermann Dec. 27, 2018, 8:49 p.m. UTC
As requested by Jason in the review of the P0482 (char8_t) core language 
changes, this patch includes updates to the error messages emitted for 
ill-formed cases of array initialization with a string literal.  With 
these changes, error messages that previously looked something like these:

- "char-array initialized from wide string"
- "wide character array initialized from non-wide string"
- "wide character array initialized from incompatible wide string"

now look like:

- "cannot initialize array of type 'char' from a string literal with 
type array of 'short unsigned int'"
- "cannot initialize array of type 'short unsigned int' from a string 
literal with type array of 'char'"
- "cannot initialize array of type 'short unsigned int' from a string 
literal with type array of 'unsigned int'"

These changes affect both the C and C++ front ends.

These changes have dependencies on the (revised) set of patches 
submitted for P0482 (char8_t) and will not apply cleanly without them.

Tested on x86_64-linux.

gcc/c/ChangeLog:

2018-12-26  Tom Honermann  <tom@honermann.net>

      * c-typeck.c (digest_init): Revised the error message produced for
      ill-formed cases of array initialization with a string literal.

gcc/cp/ChangeLog:

2018-12-26  Tom Honermann  <tom@honermann.net>

      * typeck2.c (digest_init_r): Revised the error message produced for
      ill-formed cases of array initialization with a string literal.

gcc/testsuite/ChangeLog:

2018-12-26  Tom Honermann  <tom@honermann.net>

      * gcc/testsuite/g++.dg/ext/char8_t-init-2.C: Updated the expected
      error messages for ill-formed cases of array initialization with a
      string literal.
      * gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C: Likewise.
      * gcc/testsuite/g++.dg/ext/utf-array.C: Likewise.
      * gcc/testsuite/g++.dg/ext/utf8-2.C: Likewise.
      * gcc/testsuite/gcc.dg/init-string-2.c: Likewise.
      * gcc/testsuite/gcc.dg/pr61096-1.c: Likewise.
      * gcc/testsuite/gcc.dg/utf-array-short-wchar.c: Likewise.
      * gcc/testsuite/gcc.dg/utf-array.c: Likewise.
      * gcc/testsuite/gcc.dg/utf8-2.c: Likewise.

Tom.

Comments

Martin Sebor Jan. 5, 2019, 12:25 a.m. UTC | #1
On 12/27/18 1:49 PM, Tom Honermann wrote:
> As requested by Jason in the review of the P0482 (char8_t) core language 
> changes, this patch includes updates to the error messages emitted for 
> ill-formed cases of array initialization with a string literal.  With 
> these changes, error messages that previously looked something like these:
> 
> - "char-array initialized from wide string"
> - "wide character array initialized from non-wide string"
> - "wide character array initialized from incompatible wide string"
> 
> now look like:
> 
> - "cannot initialize array of type 'char' from a string literal with 
> type array of 'short unsigned int'"

The first word "type" doesn't quite work here.  The type of every
array is "array of T" where T is the type of the element, so for
instance, "array of char."  Saying "array of type X" makes it sound
like X is the type of the whole array, which is of course not
the case when X is char.  I think you want to use the same wording
as for the second type:

   "cannot initialize array of 'char' from a string literal with
   type array of 'short unsigned int'"

or perhaps even better

   "cannot initialize array of 'char' from a string literal with
   type 'char16_t[N]'"

(i.e., show the actual type of the string, including its bound).

Martin
Tom Honermann Jan. 15, 2019, 4:09 a.m. UTC | #2
On 1/4/19 7:25 PM, Martin Sebor wrote:
> On 12/27/18 1:49 PM, Tom Honermann wrote:
>> As requested by Jason in the review of the P0482 (char8_t) core 
>> language changes, this patch includes updates to the error messages 
>> emitted for ill-formed cases of array initialization with a string 
>> literal.  With these changes, error messages that previously looked 
>> something like these:
>>
>> - "char-array initialized from wide string"
>> - "wide character array initialized from non-wide string"
>> - "wide character array initialized from incompatible wide string"
>>
>> now look like:
>>
>> - "cannot initialize array of type 'char' from a string literal with 
>> type array of 'short unsigned int'"
>
> The first word "type" doesn't quite work here.  The type of every
> array is "array of T" where T is the type of the element, so for
> instance, "array of char."  Saying "array of type X" makes it sound
> like X is the type of the whole array, which is of course not
> the case when X is char.  I think you want to use the same wording
> as for the second type:
>
>   "cannot initialize array of 'char' from a string literal with
>   type array of 'short unsigned int'"
>
> or perhaps even better
>
>   "cannot initialize array of 'char' from a string literal with
>   type 'char16_t[N]'"
>
> (i.e., show the actual type of the string, including its bound).

Thank you for the feedback, Martin; sorry for the delayed response.  
I'll follow up with a revised patch within the next week or two.

Tom.

>
> Martin
Jason Merrill Jan. 15, 2019, 3:15 p.m. UTC | #3
On 1/14/19 11:09 PM, Tom Honermann wrote:
> On 1/4/19 7:25 PM, Martin Sebor wrote:
>> On 12/27/18 1:49 PM, Tom Honermann wrote:
>>> As requested by Jason in the review of the P0482 (char8_t) core 
>>> language changes, this patch includes updates to the error messages 
>>> emitted for ill-formed cases of array initialization with a string 
>>> literal.  With these changes, error messages that previously looked 
>>> something like these:
>>>
>>> - "char-array initialized from wide string"
>>> - "wide character array initialized from non-wide string"
>>> - "wide character array initialized from incompatible wide string"
>>>
>>> now look like:
>>>
>>> - "cannot initialize array of type 'char' from a string literal with 
>>> type array of 'short unsigned int'"
>>
>> The first word "type" doesn't quite work here.  The type of every
>> array is "array of T" where T is the type of the element, so for
>> instance, "array of char."  Saying "array of type X" makes it sound
>> like X is the type of the whole array, which is of course not
>> the case when X is char.  I think you want to use the same wording
>> as for the second type:
>>
>>   "cannot initialize array of 'char' from a string literal with
>>   type array of 'short unsigned int'"
>>
>> or perhaps even better
>>
>>   "cannot initialize array of 'char' from a string literal with
>>   type 'char16_t[N]'"
>>
>> (i.e., show the actual type of the string, including its bound).
> 
> Thank you for the feedback, Martin; sorry for the delayed response. I'll 
> follow up with a revised patch within the next week or two.

I actually incorporated the C++ part of these changes into yesterday's 
commit, using Martin's first suggestion.  Here's the adjusted C patch, 
which I'd like a C maintainer to approve.

Jason
commit dc77155cc9868b6b5e7c634fd46813b81361e7ee
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Jan 9 15:01:53 2019 -0500

    Improve the C error for mismatched array string literal initialization.
    
            * c-typeck.c (digest_init): Revised the error message produced for
            ill-formed cases of array initialization with a string literal.

diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 63d177f7a6f..c7c5c627c2e 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -7722,6 +7722,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
 	{
 	  struct c_expr expr;
 	  tree typ2 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)));
+	  bool incompat_string_cst = false;
 	  expr.value = inside_init;
 	  expr.original_code = (strict_string ? STRING_CST : ERROR_MARK);
 	  expr.original_type = NULL;
@@ -7738,27 +7739,18 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
 	  if (char_array)
 	    {
 	      if (typ2 != char_type_node)
-		{
-		  error_init (init_loc, "char-array initialized from wide "
-			      "string");
-		  return error_mark_node;
-		}
-	    }
-	  else
-	    {
-	      if (typ2 == char_type_node)
-		{
-		  error_init (init_loc, "wide character array initialized "
-			      "from non-wide string");
-		  return error_mark_node;
-		}
-	      else if (!comptypes(typ1, typ2))
-		{
-		  error_init (init_loc, "wide character array initialized "
-			      "from incompatible wide string");
-		  return error_mark_node;
-		}
+		incompat_string_cst = true;
 	    }
+	  else if (!comptypes (typ1, typ2))
+	    incompat_string_cst = true;
+
+          if (incompat_string_cst)
+            {
+	      error_init (init_loc, "cannot initialize array of %qT from "
+			  "a string literal with type array of %qT",
+			  typ1, typ2);
+	      return error_mark_node;
+            }
 
 	  if (TYPE_DOMAIN (type) != NULL_TREE
 	      && TYPE_SIZE (type) != NULL_TREE
diff --git a/gcc/testsuite/gcc.dg/init-string-2.c b/gcc/testsuite/gcc.dg/init-string-2.c
index 9efd44b3d2f..9b11073c913 100644
--- a/gcc/testsuite/gcc.dg/init-string-2.c
+++ b/gcc/testsuite/gcc.dg/init-string-2.c
@@ -28,8 +28,8 @@ uchar a8[] = "foo"; /* { dg-error "string constant" "a8" } */
 const schar a9[] = "foo"; /* { dg-error "string constant" "a9" } */
 short a10[] = L"foo"; /* { dg-error "string constant" "a10" } */
 const sshrt a11[] = L"foo"; /* { dg-error "string constant" "a11" } */
-char a12[] = L"foo"; /* { dg-error "from wide string" "a12" } */
-wchar_t a13[] = "foo"; /* { dg-error "non-wide string" "a13" } */
+char a12[] = L"foo"; /* { dg-error "from a string literal with type array of .short unsigned int." "a12" } */
+wchar_t a13[] = "foo"; /* { dg-error "from a string literal with type array of .char." "a13" } */
 
 char b0[] = { "foo" };
 const signed char b2[4] = { "foo" };
@@ -43,8 +43,8 @@ uchar b8[] = { "foo" }; /* { dg-error "string constant" "b8" } */
 const schar b9[] = { "foo" }; /* { dg-error "string constant" "b9" } */
 short b10[] = { L"foo" }; /* { dg-error "string constant" "b10" } */
 const sshrt b11[] = { L"foo" }; /* { dg-error "string constant" "b11" } */
-char b12[] = { L"foo" }; /* { dg-error "from wide string" "b12" } */
-wchar_t b13[] = { "foo" }; /* { dg-error "non-wide string" "b13" } */
+char b12[] = { L"foo" }; /* { dg-error "from a string literal with type array of .short unsigned int." "b12" } */
+wchar_t b13[] = { "foo" }; /* { dg-error "from a string literal with type array of .char." "b13" } */
 
 struct s { signed char a[10]; int b; ushrt c[10]; };
 
diff --git a/gcc/testsuite/gcc.dg/pr61096-1.c b/gcc/testsuite/gcc.dg/pr61096-1.c
index 6678d812eb5..4b9da582fe7 100644
--- a/gcc/testsuite/gcc.dg/pr61096-1.c
+++ b/gcc/testsuite/gcc.dg/pr61096-1.c
@@ -19,9 +19,9 @@ struct g
   struct f f; /* { dg-warning "invalid use of structure with flexible array member" } */
 };
 
-char w1[] = L"foo"; /* { dg-error "13:char-array initialized from wide string" } */
-__WCHAR_TYPE__ w2[] = "foo"; /* { dg-error "23:wide character array initialized from non-wide string" } */
-__WCHAR_TYPE__ w3[] = U"foo"; /* { dg-error "23:wide character array initialized from incompatible wide string" } */
+char w1[] = L"foo"; /* { dg-error "13:array of .char. from a string literal with type array of .short unsigned int." } */
+__WCHAR_TYPE__ w2[] = "foo"; /* { dg-error "23:array of .short unsigned int. from a string literal with type array of .char." } */
+__WCHAR_TYPE__ w3[] = U"foo"; /* { dg-error "23:array of .short unsigned int. from a string literal with type array of .unsigned int." } */
 schar a1[] = "foo"; /* { dg-error "14:array of inappropriate type initialized from string constant" } */
 int a2[] = (int[]) { 1 }; /* { dg-warning "12:initializer element is not constant" } */
 
diff --git a/gcc/testsuite/gcc.dg/utf-array-short-wchar.c b/gcc/testsuite/gcc.dg/utf-array-short-wchar.c
index ec478121a07..1691bbc0475 100644
--- a/gcc/testsuite/gcc.dg/utf-array-short-wchar.c
+++ b/gcc/testsuite/gcc.dg/utf-array-short-wchar.c
@@ -10,33 +10,37 @@ typedef __CHAR16_TYPE__ char16_t;
 typedef __CHAR32_TYPE__ char32_t;
 
 const char	s_0[]	= "ab";
-const char	s_1[]	= u"ab";	/* { dg-error "from wide string" } */
-const char	s_2[]	= U"ab";	/* { dg-error "from wide string" } */
-const char	s_3[]	= L"ab";	/* { dg-error "from wide string" } */
+const char	s_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .short unsigned int." } */
+const char	s_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .unsigned int." } */
+const char	s_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .short unsigned int." } */
+const char	s_4[]	= u8"ab";
 
-const char16_t	s16_0[]	= "ab";		/* { dg-error "from non-wide" } */
+const char16_t	s16_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
 const char16_t	s16_1[]	= u"ab";
-const char16_t	s16_2[]	= U"ab";	/* { dg-error "from incompatible" } */
+const char16_t	s16_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .unsigned int." } */
 const char16_t	s16_3[]	= L"ab";
+const char16_t	s16_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
-const char16_t	s16_4[0] = u"ab";	/* { dg-warning "chars is too long" } */
-const char16_t	s16_5[1] = u"ab";	/* { dg-warning "chars is too long" } */
-const char16_t	s16_6[2] = u"ab";
-const char16_t	s16_7[3] = u"ab";
-const char16_t	s16_8[4] = u"ab";
+const char16_t	s16_5[0] = u"ab";	/* { dg-warning "chars is too long" } */
+const char16_t	s16_6[1] = u"ab";	/* { dg-warning "chars is too long" } */
+const char16_t	s16_7[2] = u"ab";
+const char16_t	s16_8[3] = u"ab";
+const char16_t	s16_9[4] = u"ab";
 
-const char32_t	s32_0[]	= "ab";		/* { dg-error "from non-wide" } */
-const char32_t	s32_1[]	= u"ab";	/* { dg-error "from incompatible" } */
+const char32_t	s32_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
+const char32_t	s32_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .short unsigned int." } */
 const char32_t	s32_2[]	= U"ab";
-const char32_t	s32_3[]	= L"ab";	/* { dg-error "from incompatible" } */
+const char32_t	s32_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .short unsigned int." } */
+const char32_t	s32_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
-const char32_t	s32_4[0] = U"ab";	/* { dg-warning "chars is too long" } */
-const char32_t	s32_5[1] = U"ab";	/* { dg-warning "chars is too long" } */
-const char32_t	s32_6[2] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
-const char32_t	s32_7[3] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
-const char32_t	s32_8[4] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
+const char32_t	s32_5[0] = U"ab";	/* { dg-warning "chars is too long" } */
+const char32_t	s32_6[1] = U"ab";	/* { dg-warning "chars is too long" } */
+const char32_t	s32_7[2] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
+const char32_t	s32_8[3] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
+const char32_t	s32_9[4] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
 
-const wchar_t	sw_0[]	= "ab";		/* { dg-error "from non-wide" } */
+const wchar_t	sw_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
 const wchar_t	sw_1[]	= u"ab";
-const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from incompatible" } */
+const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .unsigned int." } */
 const wchar_t	sw_3[]	= L"ab";
+const wchar_t	sw_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
diff --git a/gcc/testsuite/gcc.dg/utf-array.c b/gcc/testsuite/gcc.dg/utf-array.c
index 433ddcfaf48..da6a0c9233a 100644
--- a/gcc/testsuite/gcc.dg/utf-array.c
+++ b/gcc/testsuite/gcc.dg/utf-array.c
@@ -10,33 +10,37 @@ typedef __CHAR16_TYPE__	char16_t;
 typedef __CHAR32_TYPE__	char32_t;
 
 const char	s_0[]	= "ab";
-const char	s_1[]	= u"ab";	/* { dg-error "from wide string" } */
-const char	s_2[]	= U"ab";	/* { dg-error "from wide string" } */
-const char	s_3[]	= L"ab";	/* { dg-error "from wide string" } */
+const char	s_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .short unsigned int." } */
+const char	s_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .unsigned int." } */
+const char	s_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .int." } */
+const char	s_4[]	= u8"ab";
 
-const char16_t	s16_0[]	= "ab";		/* { dg-error "from non-wide" } */
+const char16_t	s16_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
 const char16_t	s16_1[]	= u"ab";
-const char16_t	s16_2[]	= U"ab";	/* { dg-error "from incompatible" } */
-const char16_t	s16_3[]	= L"ab";	/* { dg-error "from incompatible" "" { target { ! wchar_t_char16_t_compatible } } } */
+const char16_t	s16_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .unsigned int." } */
+const char16_t	s16_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .int." "" { target { ! wchar_t_char16_t_compatible } } } */
+const char16_t	s16_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
-const char16_t	s16_4[0] = u"ab";	/* { dg-warning "chars is too long" } */
-const char16_t	s16_5[1] = u"ab";	/* { dg-warning "chars is too long" } */
-const char16_t	s16_6[2] = u"ab";
-const char16_t	s16_7[3] = u"ab";
-const char16_t	s16_8[4] = u"ab";
+const char16_t	s16_5[0] = u"ab";	/* { dg-warning "chars is too long" } */
+const char16_t	s16_6[1] = u"ab";	/* { dg-warning "chars is too long" } */
+const char16_t	s16_7[2] = u"ab";
+const char16_t	s16_8[3] = u"ab";
+const char16_t	s16_9[4] = u"ab";
 
-const char32_t	s32_0[]	= "ab";		/* { dg-error "from non-wide" } */
-const char32_t	s32_1[]	= u"ab";	/* { dg-error "from incompatible" } */
+const char32_t	s32_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
+const char32_t	s32_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .short unsigned int." } */
 const char32_t	s32_2[]	= U"ab";
-const char32_t	s32_3[]	= L"ab";	/* { dg-error "from incompatible" "" { target { ! wchar_t_char32_t_compatible } } } */
+const char32_t	s32_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .int." "" { target { ! wchar_t_char32_t_compatible } } } */
+const char32_t	s32_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
-const char32_t	s32_4[0] = U"ab";	/* { dg-warning "chars is too long" } */
-const char32_t	s32_5[1] = U"ab";	/* { dg-warning "chars is too long" } */
-const char32_t	s32_6[2] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
-const char32_t	s32_7[3] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
-const char32_t	s32_8[4] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
+const char32_t	s32_5[0] = U"ab";	/* { dg-warning "chars is too long" } */
+const char32_t	s32_6[1] = U"ab";	/* { dg-warning "chars is too long" } */
+const char32_t	s32_7[2] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
+const char32_t	s32_8[3] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
+const char32_t	s32_9[4] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
 
-const wchar_t	sw_0[]	= "ab";		/* { dg-error "from non-wide" } */
-const wchar_t	sw_1[]	= u"ab";	/* { dg-error "from incompatible" "" { target { ! wchar_t_char16_t_compatible } } } */
-const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from incompatible" "" { target { ! wchar_t_char32_t_compatible } } } */
+const wchar_t	sw_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
+const wchar_t	sw_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .short unsigned int." "" { target { ! wchar_t_char16_t_compatible } } } */
+const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .unsigned int." "" { target { ! wchar_t_char32_t_compatible } } } */
 const wchar_t	sw_3[]	= L"ab";
+const wchar_t	sw_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
diff --git a/gcc/testsuite/gcc.dg/utf8-2.c b/gcc/testsuite/gcc.dg/utf8-2.c
index f3b83fe3341..d96b15dccb7 100644
--- a/gcc/testsuite/gcc.dg/utf8-2.c
+++ b/gcc/testsuite/gcc.dg/utf8-2.c
@@ -8,9 +8,9 @@ typedef __CHAR16_TYPE__	char16_t;
 typedef __CHAR32_TYPE__ char32_t;
 
 const char	s0[]	= u8"ab";
-const char16_t	s1[]	= u8"ab";	/* { dg-error "from non-wide" } */
-const char32_t  s2[]    = u8"ab";	/* { dg-error "from non-wide" } */
-const wchar_t   s3[]    = u8"ab";	/* { dg-error "from non-wide" } */
+const char16_t	s1[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
+const char32_t  s2[]    = u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
+const wchar_t   s3[]    = u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
 const char      t0[0]   = u8"ab";	/* { dg-warning "chars is too long" } */
 const char      t1[1]   = u8"ab";	/* { dg-warning "chars is too long" } */
Marek Polacek Jan. 15, 2019, 4 p.m. UTC | #4
On Tue, Jan 15, 2019 at 10:15:22AM -0500, Jason Merrill wrote:
> On 1/14/19 11:09 PM, Tom Honermann wrote:
> > On 1/4/19 7:25 PM, Martin Sebor wrote:
> > > On 12/27/18 1:49 PM, Tom Honermann wrote:
> > > > As requested by Jason in the review of the P0482 (char8_t) core
> > > > language changes, this patch includes updates to the error
> > > > messages emitted for ill-formed cases of array initialization
> > > > with a string literal.  With these changes, error messages that
> > > > previously looked something like these:
> > > > 
> > > > - "char-array initialized from wide string"
> > > > - "wide character array initialized from non-wide string"
> > > > - "wide character array initialized from incompatible wide string"
> > > > 
> > > > now look like:
> > > > 
> > > > - "cannot initialize array of type 'char' from a string literal
> > > > with type array of 'short unsigned int'"
> > > 
> > > The first word "type" doesn't quite work here.  The type of every
> > > array is "array of T" where T is the type of the element, so for
> > > instance, "array of char."  Saying "array of type X" makes it sound
> > > like X is the type of the whole array, which is of course not
> > > the case when X is char.  I think you want to use the same wording
> > > as for the second type:
> > > 
> > >   "cannot initialize array of 'char' from a string literal with
> > >   type array of 'short unsigned int'"
> > > 
> > > or perhaps even better
> > > 
> > >   "cannot initialize array of 'char' from a string literal with
> > >   type 'char16_t[N]'"
> > > 
> > > (i.e., show the actual type of the string, including its bound).
> > 
> > Thank you for the feedback, Martin; sorry for the delayed response. I'll
> > follow up with a revised patch within the next week or two.
> 
> I actually incorporated the C++ part of these changes into yesterday's
> commit, using Martin's first suggestion.  Here's the adjusted C patch, which
> I'd like a C maintainer to approve.

Patch is OK, thanks.

Marek
Joseph Myers Jan. 15, 2019, 5:59 p.m. UTC | #5
On Tue, 15 Jan 2019, Jason Merrill wrote:

> I actually incorporated the C++ part of these changes into yesterday's commit,
> using Martin's first suggestion.  Here's the adjusted C patch, which I'd like
> a C maintainer to approve.

The front-end changes are OK.  However, in the testcase changes, some of 
the new expected diagnostics are hardcoding that "unsigned int" is the 
type of char32_t, which isn't correct for all platforms (for example, it's 
definitely not the type when int is 16-bit).  In principle the same 
applies to diagnostics hardcoding the choice of char16_t, although 
variations are at least less likely there.
Jason Merrill Jan. 17, 2019, 5:41 p.m. UTC | #6
On 1/15/19 12:59 PM, Joseph Myers wrote:
> On Tue, 15 Jan 2019, Jason Merrill wrote:
> 
>> I actually incorporated the C++ part of these changes into yesterday's commit,
>> using Martin's first suggestion.  Here's the adjusted C patch, which I'd like
>> a C maintainer to approve.
> 
> The front-end changes are OK.  However, in the testcase changes, some of
> the new expected diagnostics are hardcoding that "unsigned int" is th
> type of char32_t, which isn't correct for all platforms (for example, it's
> definitely not the type when int is 16-bit).  In principle the same
> applies to diagnostics hardcoding the choice of char16_t, although
> variations are at least less likely there.

This updated patch removes {short ,}unsigned int from the expected 
diagnostics.  And also improves error_init to accept additional 
arguments, like pedwarn_init already does.

Tested x86_64-pc-linux-gnu.

Jason
commit 7760281e48c2eee881c44ff255d2fbf72b5461b8
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Jan 9 15:01:53 2019 -0500

    Improve the C error for mismatched array string literal initialization.
    
            * c-typeck.c (digest_init): Revised the error message produced for
            ill-formed cases of array initialization with a string literal.
            (error_init): Make variadic.

diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 63d177f7a6f..6da1f321835 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -6339,17 +6339,21 @@ convert_to_anonymous_field (location_t location, tree type, tree rhs)
    GMSGID identifies the message.
    The component name is taken from the spelling stack.  */
 
-static void
-error_init (location_t loc, const char *gmsgid)
+static void ATTRIBUTE_GCC_DIAG (2,0)
+error_init (location_t loc, const char *gmsgid, ...)
 {
   char *ofwhat;
 
   auto_diagnostic_group d;
 
   /* The gmsgid may be a format string with %< and %>. */
-  error_at (loc, gmsgid);
+  va_list ap;
+  va_start (ap, gmsgid);
+  bool warned = emit_diagnostic_valist (DK_ERROR, loc, -1, gmsgid, &ap);
+  va_end (ap);
+
   ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
-  if (*ofwhat)
+  if (*ofwhat && warned)
     inform (loc, "(near initialization for %qs)", ofwhat);
 }
 
@@ -7722,6 +7726,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
 	{
 	  struct c_expr expr;
 	  tree typ2 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)));
+	  bool incompat_string_cst = false;
 	  expr.value = inside_init;
 	  expr.original_code = (strict_string ? STRING_CST : ERROR_MARK);
 	  expr.original_type = NULL;
@@ -7738,27 +7743,18 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
 	  if (char_array)
 	    {
 	      if (typ2 != char_type_node)
-		{
-		  error_init (init_loc, "char-array initialized from wide "
-			      "string");
-		  return error_mark_node;
-		}
-	    }
-	  else
-	    {
-	      if (typ2 == char_type_node)
-		{
-		  error_init (init_loc, "wide character array initialized "
-			      "from non-wide string");
-		  return error_mark_node;
-		}
-	      else if (!comptypes(typ1, typ2))
-		{
-		  error_init (init_loc, "wide character array initialized "
-			      "from incompatible wide string");
-		  return error_mark_node;
-		}
+		incompat_string_cst = true;
 	    }
+	  else if (!comptypes (typ1, typ2))
+	    incompat_string_cst = true;
+
+          if (incompat_string_cst)
+            {
+	      error_init (init_loc, "cannot initialize array of %qT from "
+			  "a string literal with type array of %qT",
+			  typ1, typ2);
+	      return error_mark_node;
+            }
 
 	  if (TYPE_DOMAIN (type) != NULL_TREE
 	      && TYPE_SIZE (type) != NULL_TREE
diff --git a/gcc/testsuite/gcc.dg/init-string-2.c b/gcc/testsuite/gcc.dg/init-string-2.c
index 9efd44b3d2f..ded9bf27708 100644
--- a/gcc/testsuite/gcc.dg/init-string-2.c
+++ b/gcc/testsuite/gcc.dg/init-string-2.c
@@ -28,8 +28,8 @@ uchar a8[] = "foo"; /* { dg-error "string constant" "a8" } */
 const schar a9[] = "foo"; /* { dg-error "string constant" "a9" } */
 short a10[] = L"foo"; /* { dg-error "string constant" "a10" } */
 const sshrt a11[] = L"foo"; /* { dg-error "string constant" "a11" } */
-char a12[] = L"foo"; /* { dg-error "from wide string" "a12" } */
-wchar_t a13[] = "foo"; /* { dg-error "non-wide string" "a13" } */
+char a12[] = L"foo"; /* { dg-error "from a string literal with type array of" "a12" } */
+wchar_t a13[] = "foo"; /* { dg-error "from a string literal with type array of .char." "a13" } */
 
 char b0[] = { "foo" };
 const signed char b2[4] = { "foo" };
@@ -43,8 +43,8 @@ uchar b8[] = { "foo" }; /* { dg-error "string constant" "b8" } */
 const schar b9[] = { "foo" }; /* { dg-error "string constant" "b9" } */
 short b10[] = { L"foo" }; /* { dg-error "string constant" "b10" } */
 const sshrt b11[] = { L"foo" }; /* { dg-error "string constant" "b11" } */
-char b12[] = { L"foo" }; /* { dg-error "from wide string" "b12" } */
-wchar_t b13[] = { "foo" }; /* { dg-error "non-wide string" "b13" } */
+char b12[] = { L"foo" }; /* { dg-error "from a string literal with type array of" "b12" } */
+wchar_t b13[] = { "foo" }; /* { dg-error "from a string literal with type array of .char." "b13" } */
 
 struct s { signed char a[10]; int b; ushrt c[10]; };
 
diff --git a/gcc/testsuite/gcc.dg/pr61096-1.c b/gcc/testsuite/gcc.dg/pr61096-1.c
index 6678d812eb5..111585dd025 100644
--- a/gcc/testsuite/gcc.dg/pr61096-1.c
+++ b/gcc/testsuite/gcc.dg/pr61096-1.c
@@ -19,9 +19,9 @@ struct g
   struct f f; /* { dg-warning "invalid use of structure with flexible array member" } */
 };
 
-char w1[] = L"foo"; /* { dg-error "13:char-array initialized from wide string" } */
-__WCHAR_TYPE__ w2[] = "foo"; /* { dg-error "23:wide character array initialized from non-wide string" } */
-__WCHAR_TYPE__ w3[] = U"foo"; /* { dg-error "23:wide character array initialized from incompatible wide string" } */
+char w1[] = L"foo"; /* { dg-error "13:array of .char. from a string literal with type array of" } */
+__WCHAR_TYPE__ w2[] = "foo"; /* { dg-error "23:from a string literal with type array of .char." } */
+__WCHAR_TYPE__ w3[] = U"foo"; /* { dg-error "23:from a string literal with type array of" } */
 schar a1[] = "foo"; /* { dg-error "14:array of inappropriate type initialized from string constant" } */
 int a2[] = (int[]) { 1 }; /* { dg-warning "12:initializer element is not constant" } */
 
diff --git a/gcc/testsuite/gcc.dg/utf-array-short-wchar.c b/gcc/testsuite/gcc.dg/utf-array-short-wchar.c
index ec478121a07..a582e71178c 100644
--- a/gcc/testsuite/gcc.dg/utf-array-short-wchar.c
+++ b/gcc/testsuite/gcc.dg/utf-array-short-wchar.c
@@ -10,33 +10,37 @@ typedef __CHAR16_TYPE__ char16_t;
 typedef __CHAR32_TYPE__ char32_t;
 
 const char	s_0[]	= "ab";
-const char	s_1[]	= u"ab";	/* { dg-error "from wide string" } */
-const char	s_2[]	= U"ab";	/* { dg-error "from wide string" } */
-const char	s_3[]	= L"ab";	/* { dg-error "from wide string" } */
+const char	s_1[]	= u"ab";	/* { dg-error "from a string literal with type array of" } */
+const char	s_2[]	= U"ab";	/* { dg-error "from a string literal with type array of" } */
+const char	s_3[]	= L"ab";	/* { dg-error "from a string literal with type array of" } */
+const char	s_4[]	= u8"ab";
 
-const char16_t	s16_0[]	= "ab";		/* { dg-error "from non-wide" } */
+const char16_t	s16_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
 const char16_t	s16_1[]	= u"ab";
-const char16_t	s16_2[]	= U"ab";	/* { dg-error "from incompatible" } */
+const char16_t	s16_2[]	= U"ab";	/* { dg-error "from a string literal with type array of" } */
 const char16_t	s16_3[]	= L"ab";
+const char16_t	s16_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
-const char16_t	s16_4[0] = u"ab";	/* { dg-warning "chars is too long" } */
-const char16_t	s16_5[1] = u"ab";	/* { dg-warning "chars is too long" } */
-const char16_t	s16_6[2] = u"ab";
-const char16_t	s16_7[3] = u"ab";
-const char16_t	s16_8[4] = u"ab";
+const char16_t	s16_5[0] = u"ab";	/* { dg-warning "chars is too long" } */
+const char16_t	s16_6[1] = u"ab";	/* { dg-warning "chars is too long" } */
+const char16_t	s16_7[2] = u"ab";
+const char16_t	s16_8[3] = u"ab";
+const char16_t	s16_9[4] = u"ab";
 
-const char32_t	s32_0[]	= "ab";		/* { dg-error "from non-wide" } */
-const char32_t	s32_1[]	= u"ab";	/* { dg-error "from incompatible" } */
+const char32_t	s32_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
+const char32_t	s32_1[]	= u"ab";	/* { dg-error "from a string literal with type array of" } */
 const char32_t	s32_2[]	= U"ab";
-const char32_t	s32_3[]	= L"ab";	/* { dg-error "from incompatible" } */
+const char32_t	s32_3[]	= L"ab";	/* { dg-error "from a string literal with type array of" } */
+const char32_t	s32_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
-const char32_t	s32_4[0] = U"ab";	/* { dg-warning "chars is too long" } */
-const char32_t	s32_5[1] = U"ab";	/* { dg-warning "chars is too long" } */
-const char32_t	s32_6[2] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
-const char32_t	s32_7[3] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
-const char32_t	s32_8[4] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
+const char32_t	s32_5[0] = U"ab";	/* { dg-warning "chars is too long" } */
+const char32_t	s32_6[1] = U"ab";	/* { dg-warning "chars is too long" } */
+const char32_t	s32_7[2] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
+const char32_t	s32_8[3] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
+const char32_t	s32_9[4] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
 
-const wchar_t	sw_0[]	= "ab";		/* { dg-error "from non-wide" } */
+const wchar_t	sw_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
 const wchar_t	sw_1[]	= u"ab";
-const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from incompatible" } */
+const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from a string literal with type array of" } */
 const wchar_t	sw_3[]	= L"ab";
+const wchar_t	sw_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
diff --git a/gcc/testsuite/gcc.dg/utf-array.c b/gcc/testsuite/gcc.dg/utf-array.c
index 433ddcfaf48..74a0c0c0e05 100644
--- a/gcc/testsuite/gcc.dg/utf-array.c
+++ b/gcc/testsuite/gcc.dg/utf-array.c
@@ -10,33 +10,37 @@ typedef __CHAR16_TYPE__	char16_t;
 typedef __CHAR32_TYPE__	char32_t;
 
 const char	s_0[]	= "ab";
-const char	s_1[]	= u"ab";	/* { dg-error "from wide string" } */
-const char	s_2[]	= U"ab";	/* { dg-error "from wide string" } */
-const char	s_3[]	= L"ab";	/* { dg-error "from wide string" } */
+const char	s_1[]	= u"ab";	/* { dg-error "from a string literal with type array of" } */
+const char	s_2[]	= U"ab";	/* { dg-error "from a string literal with type array of" } */
+const char	s_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .int." } */
+const char	s_4[]	= u8"ab";
 
-const char16_t	s16_0[]	= "ab";		/* { dg-error "from non-wide" } */
+const char16_t	s16_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
 const char16_t	s16_1[]	= u"ab";
-const char16_t	s16_2[]	= U"ab";	/* { dg-error "from incompatible" } */
-const char16_t	s16_3[]	= L"ab";	/* { dg-error "from incompatible" "" { target { ! wchar_t_char16_t_compatible } } } */
+const char16_t	s16_2[]	= U"ab";	/* { dg-error "from a string literal with type array of" } */
+const char16_t	s16_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .int." "" { target { ! wchar_t_char16_t_compatible } } } */
+const char16_t	s16_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
-const char16_t	s16_4[0] = u"ab";	/* { dg-warning "chars is too long" } */
-const char16_t	s16_5[1] = u"ab";	/* { dg-warning "chars is too long" } */
-const char16_t	s16_6[2] = u"ab";
-const char16_t	s16_7[3] = u"ab";
-const char16_t	s16_8[4] = u"ab";
+const char16_t	s16_5[0] = u"ab";	/* { dg-warning "chars is too long" } */
+const char16_t	s16_6[1] = u"ab";	/* { dg-warning "chars is too long" } */
+const char16_t	s16_7[2] = u"ab";
+const char16_t	s16_8[3] = u"ab";
+const char16_t	s16_9[4] = u"ab";
 
-const char32_t	s32_0[]	= "ab";		/* { dg-error "from non-wide" } */
-const char32_t	s32_1[]	= u"ab";	/* { dg-error "from incompatible" } */
+const char32_t	s32_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
+const char32_t	s32_1[]	= u"ab";	/* { dg-error "from a string literal with type array of" } */
 const char32_t	s32_2[]	= U"ab";
-const char32_t	s32_3[]	= L"ab";	/* { dg-error "from incompatible" "" { target { ! wchar_t_char32_t_compatible } } } */
+const char32_t	s32_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .int." "" { target { ! wchar_t_char32_t_compatible } } } */
+const char32_t	s32_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
-const char32_t	s32_4[0] = U"ab";	/* { dg-warning "chars is too long" } */
-const char32_t	s32_5[1] = U"ab";	/* { dg-warning "chars is too long" } */
-const char32_t	s32_6[2] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
-const char32_t	s32_7[3] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
-const char32_t	s32_8[4] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
+const char32_t	s32_5[0] = U"ab";	/* { dg-warning "chars is too long" } */
+const char32_t	s32_6[1] = U"ab";	/* { dg-warning "chars is too long" } */
+const char32_t	s32_7[2] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
+const char32_t	s32_8[3] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
+const char32_t	s32_9[4] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
 
-const wchar_t	sw_0[]	= "ab";		/* { dg-error "from non-wide" } */
-const wchar_t	sw_1[]	= u"ab";	/* { dg-error "from incompatible" "" { target { ! wchar_t_char16_t_compatible } } } */
-const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from incompatible" "" { target { ! wchar_t_char32_t_compatible } } } */
+const wchar_t	sw_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
+const wchar_t	sw_1[]	= u"ab";	/* { dg-error "from a string literal with type array of" "" { target { ! wchar_t_char16_t_compatible } } } */
+const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from a string literal with type array of" "" { target { ! wchar_t_char32_t_compatible } } } */
 const wchar_t	sw_3[]	= L"ab";
+const wchar_t	sw_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
diff --git a/gcc/testsuite/gcc.dg/utf8-2.c b/gcc/testsuite/gcc.dg/utf8-2.c
index f3b83fe3341..d96b15dccb7 100644
--- a/gcc/testsuite/gcc.dg/utf8-2.c
+++ b/gcc/testsuite/gcc.dg/utf8-2.c
@@ -8,9 +8,9 @@ typedef __CHAR16_TYPE__	char16_t;
 typedef __CHAR32_TYPE__ char32_t;
 
 const char	s0[]	= u8"ab";
-const char16_t	s1[]	= u8"ab";	/* { dg-error "from non-wide" } */
-const char32_t  s2[]    = u8"ab";	/* { dg-error "from non-wide" } */
-const wchar_t   s3[]    = u8"ab";	/* { dg-error "from non-wide" } */
+const char16_t	s1[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
+const char32_t  s2[]    = u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
+const wchar_t   s3[]    = u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
 const char      t0[0]   = u8"ab";	/* { dg-warning "chars is too long" } */
 const char      t1[1]   = u8"ab";	/* { dg-warning "chars is too long" } */
Joseph Myers Jan. 17, 2019, 8:24 p.m. UTC | #7
On Thu, 17 Jan 2019, Jason Merrill wrote:

> This updated patch removes {short ,}unsigned int from the expected
> diagnostics.  And also improves error_init to accept additional arguments,
> like pedwarn_init already does.

This version is OK.
Rainer Orth Jan. 18, 2019, 12:51 p.m. UTC | #8
Hi Jason,

> On 1/15/19 12:59 PM, Joseph Myers wrote:
>> On Tue, 15 Jan 2019, Jason Merrill wrote:
>>
>>> I actually incorporated the C++ part of these changes into yesterday's
>>> commit,
>>> using Martin's first suggestion.  Here's the adjusted C patch, which I'd like
>>> a C maintainer to approve.
>>
>> The front-end changes are OK.  However, in the testcase changes, some of
>> the new expected diagnostics are hardcoding that "unsigned int" is th
>> type of char32_t, which isn't correct for all platforms (for example, it's
>> definitely not the type when int is 16-bit).  In principle the same
>> applies to diagnostics hardcoding the choice of char16_t, although
>> variations are at least less likely there.
>
> This updated patch removes {short ,}unsigned int from the expected
> diagnostics.  And also improves error_init to accept additional arguments,
> like pedwarn_init already does.
>
> Tested x86_64-pc-linux-gnu.

there are now a couple of failures on several (32-bit?) targets:

+FAIL: gcc.dg/utf-array.c  (test for errors, line 15)
+FAIL: gcc.dg/utf-array.c  (test for errors, line 21)
+FAIL: gcc.dg/utf-array.c  (test for errors, line 33)

I'm seeing it on i386-pc-solaris2.11 (32-bit only), and there are also
gcc-testresults reports on i686-pc-linux-gnu, m68k-unknown-linux-gnu,
and x86_64-pc-linux-gnu.

	Rainer
Christophe Lyon Jan. 18, 2019, 2:45 p.m. UTC | #9
On Fri, 18 Jan 2019 at 13:52, Rainer Orth <ro@cebitec.uni-bielefeld.de> wrote:
>
> Hi Jason,
>
> > On 1/15/19 12:59 PM, Joseph Myers wrote:
> >> On Tue, 15 Jan 2019, Jason Merrill wrote:
> >>
> >>> I actually incorporated the C++ part of these changes into yesterday's
> >>> commit,
> >>> using Martin's first suggestion.  Here's the adjusted C patch, which I'd like
> >>> a C maintainer to approve.
> >>
> >> The front-end changes are OK.  However, in the testcase changes, some of
> >> the new expected diagnostics are hardcoding that "unsigned int" is th
> >> type of char32_t, which isn't correct for all platforms (for example, it's
> >> definitely not the type when int is 16-bit).  In principle the same
> >> applies to diagnostics hardcoding the choice of char16_t, although
> >> variations are at least less likely there.
> >
> > This updated patch removes {short ,}unsigned int from the expected
> > diagnostics.  And also improves error_init to accept additional arguments,
> > like pedwarn_init already does.
> >
> > Tested x86_64-pc-linux-gnu.
>
> there are now a couple of failures on several (32-bit?) targets:
>
> +FAIL: gcc.dg/utf-array.c  (test for errors, line 15)
> +FAIL: gcc.dg/utf-array.c  (test for errors, line 21)
> +FAIL: gcc.dg/utf-array.c  (test for errors, line 33)
>
> I'm seeing it on i386-pc-solaris2.11 (32-bit only), and there are also
> gcc-testresults reports on i686-pc-linux-gnu, m68k-unknown-linux-gnu,
> and x86_64-pc-linux-gnu.
>

Seeing similar errors on arm and aarch64 too.

>         Rainer
>
> --
> -----------------------------------------------------------------------------
> Rainer Orth, Center for Biotechnology, Bielefeld University
diff mbox series

Patch

diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 9d09b8d65fd..4d2129dff2f 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -7447,6 +7447,7 @@  digest_init (location_t init_loc, tree type, tree init, tree origtype,
 	{
 	  struct c_expr expr;
 	  tree typ2 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)));
+	  bool incompat_string_cst = false;
 	  expr.value = inside_init;
 	  expr.original_code = (strict_string ? STRING_CST : ERROR_MARK);
 	  expr.original_type = NULL;
@@ -7464,27 +7465,22 @@  digest_init (location_t init_loc, tree type, tree init, tree origtype,
 	    {
 	      if (typ2 != char_type_node)
 		{
-		  error_init (init_loc, "char-array initialized from wide "
-			      "string");
-		  return error_mark_node;
+		  incompat_string_cst = true;
 		}
 	    }
-	  else
+	  else if (!comptypes(typ1, typ2))
 	    {
-	      if (typ2 == char_type_node)
-		{
-		  error_init (init_loc, "wide character array initialized "
-			      "from non-wide string");
-		  return error_mark_node;
-		}
-	      else if (!comptypes(typ1, typ2))
-		{
-		  error_init (init_loc, "wide character array initialized "
-			      "from incompatible wide string");
-		  return error_mark_node;
-		}
+	      incompat_string_cst = true;
 	    }
 
+          if (incompat_string_cst)
+            {
+	      error_at (init_loc, "cannot initialize array of type %qT from "
+	                "a string literal with type array of %qT",
+	                typ1, typ2);
+	      return error_mark_node;
+            }
+
 	  if (TYPE_DOMAIN (type) != NULL_TREE
 	      && TYPE_SIZE (type) != NULL_TREE
 	      && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 782fd7f9cd5..ae3b53dc001 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1060,46 +1060,43 @@  digest_init_r (tree type, tree init, int nested, int flags,
 	  && TREE_CODE (init) == STRING_CST)
 	{
 	  tree char_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (init)));
+	  bool incompat_string_cst = false;
 
-	  if (TYPE_PRECISION (typ1) == BITS_PER_UNIT)
+	  if (typ1 != char_type)
 	    {
-	      if (typ1 != char8_type_node && char_type == char8_type_node)
+	      /* The array element type does not match the initializing string
+	         literal element type. This is only allowed when initializing
+	         an array of signed char or unsigned char.  */
+	      if (TYPE_PRECISION (typ1) == BITS_PER_UNIT)
 		{
-		  if (complain & tf_error)
-		    error_at (loc, "char-array initialized from UTF-8 string");
-		  return error_mark_node;
-		}
-	      else if (typ1 == char8_type_node && char_type == char_type_node)
-		{
-		  if (complain & tf_error)
-		    error_at (loc, "char8_t-array initialized from ordinary "
-			      "string");
-		  return error_mark_node;
+		  if (typ1 == char8_type_node)
+		    {
+		      /* char8_t array initialized with a non-char8_t
+		         string literal.  */
+		      incompat_string_cst = true;
+		    }
+		  else if (char_type != char_type_node)
+		    {
+		      /* singed or unsigned char array initialized with a
+		         char8_t or wide string literal.  */
+		      incompat_string_cst = true;
+		    }
 		}
-	      else if (char_type != char_type_node
-		       && char_type != char8_type_node)
+	      else
 		{
-		  if (complain & tf_error)
-		    error_at (loc, "char-array initialized from wide string");
-		  return error_mark_node;
+		  /* Wide char array initialized with a string literal with a
+		     mismatched element type.  */
+		  incompat_string_cst = true;
 		}
 	    }
-	  else
+
+	  if (incompat_string_cst)
 	    {
-	      if (char_type == char_type_node)
-		{
-		  if (complain & tf_error)
-		    error_at (loc,
-			      "int-array initialized from non-wide string");
-		  return error_mark_node;
-		}
-	      else if (char_type != typ1)
-		{
-		  if (complain & tf_error)
-		    error_at (loc, "int-array initialized from incompatible "
-			      "wide string");
-		  return error_mark_node;
-		}
+	      if (complain & tf_error)
+		error_at (loc, "cannot initialize array of type %qT from "
+		          "a string literal with type array of %qT",
+		          typ1, char_type);
+	      return error_mark_node;
 	    }
 
 	  if (nested == 2 && !TYPE_DOMAIN (type))
diff --git a/gcc/testsuite/g++.dg/ext/char8_t-init-2.C b/gcc/testsuite/g++.dg/ext/char8_t-init-2.C
index 7a7a3a6b208..c713bc12266 100644
--- a/gcc/testsuite/g++.dg/ext/char8_t-init-2.C
+++ b/gcc/testsuite/g++.dg/ext/char8_t-init-2.C
@@ -21,13 +21,13 @@  const char8_t (&rca4)[2] = u8"x";
 const char8_t (&rca5)[2] = u"x"; // { dg-error "invalid initialization of reference of type .const char8_t ....... from expression of type .const char16_t ...." "char8_t" }
 
 char ca1[] = "x";
-char ca2[] = u8"x"; // { dg-error "char-array initialized from UTF-8 string" "char8_t" }
-char8_t ca3[] = "x"; // { dg-error "char8_t-array initialized from ordinary string" "char8_t" }
+char ca2[] = u8"x"; // { dg-error "from a string literal with type array of .char8_t." "char8_t" }
+char8_t ca3[] = "x"; // { dg-error "from a string literal with type array of .char." "char8_t" }
 char8_t ca4[] = u8"x";
-char8_t ca5[] = u"x"; // { dg-error "char-array initialized from wide string" "char8_t" }
+char8_t ca5[] = u"x"; // { dg-error "from a string literal with type array of .char16_t." "char8_t" }
 
 signed char sca1[] = "x";
-signed char sca2[] = u8"x"; // { dg-error "char-array initialized from UTF-8 string" "char8_t" }
+signed char sca2[] = u8"x"; // { dg-error "from a string literal with type array of .char8_t." "char8_t" }
 
 unsigned char uca1[] = "x";
-unsigned char uca2[] = u8"x"; // { dg-error "char-array initialized from UTF-8 string" "char8_t" }
+unsigned char uca2[] = u8"x"; // { dg-error "from a string literal with type array of .char8_t." "char8_t" }
diff --git a/gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C b/gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C
index 6e0e4a0c7e9..617e9f0d4bf 100644
--- a/gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C
+++ b/gcc/testsuite/g++.dg/ext/utf-array-short-wchar.C
@@ -4,16 +4,16 @@ 
 /* { dg-options "-fshort-wchar" } */
 
 const char	s_0[]	= "ab";
-const char	s_1[]	= u"ab";	/* { dg-error "from wide string" } */
-const char	s_2[]	= U"ab";	/* { dg-error "from wide string" } */
-const char	s_3[]	= L"ab";	/* { dg-error "from wide string" } */
+const char	s_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .char16_t." } */
+const char	s_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .char32_t." } */
+const char	s_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .wchar_t." } */
 const char	s_4[]	= u8"ab";
 
-const char16_t	s16_0[]	= "ab";		/* { dg-error "from non-wide" } */
+const char16_t	s16_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
 const char16_t	s16_1[]	= u"ab";
-const char16_t	s16_2[]	= U"ab";	/* { dg-error "from incompatible" } */
-const char16_t	s16_3[]	= L"ab";	/* { dg-error "from incompatible" } */
-const char16_t	s16_4[]	= u8"ab";	/* { dg-error "from non-wide" } */
+const char16_t	s16_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .char32_t." } */
+const char16_t	s16_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .wchar_t." } */
+const char16_t	s16_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
 const char16_t	s16_5[0] = u"ab";	/* { dg-error "chars is too long" } */
 const char16_t	s16_6[1] = u"ab";	/* { dg-error "chars is too long" } */
@@ -21,11 +21,11 @@  const char16_t	s16_7[2] = u"ab";	/* { dg-error "chars is too long" } */
 const char16_t	s16_8[3] = u"ab";
 const char16_t	s16_9[4] = u"ab";
 
-const char32_t	s32_0[]	= "ab";		/* { dg-error "from non-wide" } */
-const char32_t	s32_1[]	= u"ab";	/* { dg-error "from incompatible" } */
+const char32_t	s32_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
+const char32_t	s32_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .char16_t." } */
 const char32_t	s32_2[]	= U"ab";
-const char32_t	s32_3[]	= L"ab";	/* { dg-error "from incompatible" } */
-const char32_t	s32_4[]	= u8"ab";	/* { dg-error "from non-wide" } */
+const char32_t	s32_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .wchar_t." } */
+const char32_t	s32_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
 const char32_t	s32_5[0] = U"ab";	/* { dg-error "chars is too long" } */
 const char32_t	s32_6[1] = U"ab";	/* { dg-error "chars is too long" } */
@@ -33,8 +33,8 @@  const char32_t	s32_7[2] = U"ab";	/* { dg-error "chars is too long" } */
 const char32_t	s32_8[3] = U"ab";
 const char32_t	s32_9[4] = U"ab";
 
-const wchar_t	sw_0[]	= "ab";		/* { dg-error "from non-wide" } */
-const wchar_t	sw_1[]	= u"ab";	/* { dg-error "from incompatible" } */
-const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from incompatible" } */
+const wchar_t	sw_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
+const wchar_t	sw_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .char16_t." } */
+const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .char32_t." } */
 const wchar_t	sw_3[]	= L"ab";
-const wchar_t	sw_4[]	= u8"ab";	/* { dg-error "from non-wide" } */
+const wchar_t	sw_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
diff --git a/gcc/testsuite/g++.dg/ext/utf-array.C b/gcc/testsuite/g++.dg/ext/utf-array.C
index fcdf75d7650..3e77c880963 100644
--- a/gcc/testsuite/g++.dg/ext/utf-array.C
+++ b/gcc/testsuite/g++.dg/ext/utf-array.C
@@ -4,16 +4,16 @@ 
 // { dg-options "" }
 
 const char	s_0[]	= "ab";
-const char	s_1[]	= u"ab";	/* { dg-error "from wide string" } */
-const char	s_2[]	= U"ab";	/* { dg-error "from wide string" } */
-const char	s_3[]	= L"ab";	/* { dg-error "from wide string" } */
+const char	s_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .char16_t." } */
+const char	s_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .char32_t." } */
+const char	s_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .wchar_t." } */
 const char	s_4[]	= u8"ab";
 
-const char16_t	s16_0[]	= "ab";		/* { dg-error "from non-wide" } */
+const char16_t	s16_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
 const char16_t	s16_1[]	= u"ab";
-const char16_t	s16_2[]	= U"ab";	/* { dg-error "from incompatible" } */
-const char16_t	s16_3[]	= L"ab";	/* { dg-error "from incompatible" } */
-const char16_t	s16_4[]	= u8"ab";	/* { dg-error "from non-wide" } */
+const char16_t	s16_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .char32_t." } */
+const char16_t	s16_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .wchar_t." } */
+const char16_t	s16_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
 const char16_t	s16_5[0] = u"ab";	/* { dg-error "chars is too long" } */
 const char16_t	s16_6[1] = u"ab";	/* { dg-error "chars is too long" } */
@@ -21,11 +21,11 @@  const char16_t	s16_7[2] = u"ab";	/* { dg-error "chars is too long" } */
 const char16_t	s16_8[3] = u"ab";
 const char16_t	s16_9[4] = u"ab";
 
-const char32_t	s32_0[]	= "ab";		/* { dg-error "from non-wide" } */
-const char32_t	s32_1[]	= u"ab";	/* { dg-error "from incompatible" } */
+const char32_t	s32_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
+const char32_t	s32_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .char16_t." } */
 const char32_t	s32_2[]	= U"ab";
-const char32_t	s32_3[]	= L"ab";	/* { dg-error "from incompatible" } */
-const char32_t	s32_4[]	= u8"ab";	/* { dg-error "from non-wide" } */
+const char32_t	s32_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .wchar_t." } */
+const char32_t	s32_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
 const char32_t	s32_5[0] = U"ab";	/* { dg-error "chars is too long" } */
 const char32_t	s32_6[1] = U"ab";	/* { dg-error "chars is too long" } */
@@ -33,8 +33,8 @@  const char32_t	s32_7[2] = U"ab";	/* { dg-error "chars is too long" } */
 const char32_t	s32_8[3] = U"ab";
 const char32_t	s32_9[4] = U"ab";
 
-const wchar_t	sw_0[]	= "ab";		/* { dg-error "from non-wide" } */
-const wchar_t	sw_1[]	= u"ab";	/* { dg-error "from incompatible" } */
-const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from incompatible" } */
+const wchar_t	sw_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
+const wchar_t	sw_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .char16_t." } */
+const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .char32_t." } */
 const wchar_t	sw_3[]	= L"ab";
-const wchar_t	sw_4[]	= u8"ab";	/* { dg-error "from non-wide" } */
+const wchar_t	sw_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
diff --git a/gcc/testsuite/g++.dg/ext/utf8-2.C b/gcc/testsuite/g++.dg/ext/utf8-2.C
index bafe6e8351c..abf60430176 100644
--- a/gcc/testsuite/g++.dg/ext/utf8-2.C
+++ b/gcc/testsuite/g++.dg/ext/utf8-2.C
@@ -2,9 +2,9 @@ 
 // { dg-options "" }
 
 const char	s0[]	= u8"ab";
-const char16_t	s1[]	= u8"ab";	// { dg-error "from non-wide" }
-const char32_t  s2[]    = u8"ab";	// { dg-error "from non-wide" }
-const wchar_t   s3[]    = u8"ab";	// { dg-error "from non-wide" }
+const char16_t	s1[]	= u8"ab";	// { dg-error "from a string literal with type array of .char." }
+const char32_t  s2[]    = u8"ab";	// { dg-error "from a string literal with type array of .char." }
+const wchar_t   s3[]    = u8"ab";	// { dg-error "from a string literal with type array of .char." }
 
 const char      t0[0]   = u8"ab";	// { dg-error "chars is too long" }
 const char      t1[1]   = u8"ab";	// { dg-error "chars is too long" }
diff --git a/gcc/testsuite/gcc.dg/init-string-2.c b/gcc/testsuite/gcc.dg/init-string-2.c
index 9efd44b3d2f..9b11073c913 100644
--- a/gcc/testsuite/gcc.dg/init-string-2.c
+++ b/gcc/testsuite/gcc.dg/init-string-2.c
@@ -28,8 +28,8 @@  uchar a8[] = "foo"; /* { dg-error "string constant" "a8" } */
 const schar a9[] = "foo"; /* { dg-error "string constant" "a9" } */
 short a10[] = L"foo"; /* { dg-error "string constant" "a10" } */
 const sshrt a11[] = L"foo"; /* { dg-error "string constant" "a11" } */
-char a12[] = L"foo"; /* { dg-error "from wide string" "a12" } */
-wchar_t a13[] = "foo"; /* { dg-error "non-wide string" "a13" } */
+char a12[] = L"foo"; /* { dg-error "from a string literal with type array of .short unsigned int." "a12" } */
+wchar_t a13[] = "foo"; /* { dg-error "from a string literal with type array of .char." "a13" } */
 
 char b0[] = { "foo" };
 const signed char b2[4] = { "foo" };
@@ -43,8 +43,8 @@  uchar b8[] = { "foo" }; /* { dg-error "string constant" "b8" } */
 const schar b9[] = { "foo" }; /* { dg-error "string constant" "b9" } */
 short b10[] = { L"foo" }; /* { dg-error "string constant" "b10" } */
 const sshrt b11[] = { L"foo" }; /* { dg-error "string constant" "b11" } */
-char b12[] = { L"foo" }; /* { dg-error "from wide string" "b12" } */
-wchar_t b13[] = { "foo" }; /* { dg-error "non-wide string" "b13" } */
+char b12[] = { L"foo" }; /* { dg-error "from a string literal with type array of .short unsigned int." "b12" } */
+wchar_t b13[] = { "foo" }; /* { dg-error "from a string literal with type array of .char." "b13" } */
 
 struct s { signed char a[10]; int b; ushrt c[10]; };
 
diff --git a/gcc/testsuite/gcc.dg/pr61096-1.c b/gcc/testsuite/gcc.dg/pr61096-1.c
index 6678d812eb5..c414d0a472c 100644
--- a/gcc/testsuite/gcc.dg/pr61096-1.c
+++ b/gcc/testsuite/gcc.dg/pr61096-1.c
@@ -19,9 +19,9 @@  struct g
   struct f f; /* { dg-warning "invalid use of structure with flexible array member" } */
 };
 
-char w1[] = L"foo"; /* { dg-error "13:char-array initialized from wide string" } */
-__WCHAR_TYPE__ w2[] = "foo"; /* { dg-error "23:wide character array initialized from non-wide string" } */
-__WCHAR_TYPE__ w3[] = U"foo"; /* { dg-error "23:wide character array initialized from incompatible wide string" } */
+char w1[] = L"foo"; /* { dg-error "13:array of type .char. from a string literal with type array of .short unsigned int." } */
+__WCHAR_TYPE__ w2[] = "foo"; /* { dg-error "23:array of type .short unsigned int. from a string literal with type array of .char." } */
+__WCHAR_TYPE__ w3[] = U"foo"; /* { dg-error "23:array of type .short unsigned int. from a string literal with type array of .unsigned int." } */
 schar a1[] = "foo"; /* { dg-error "14:array of inappropriate type initialized from string constant" } */
 int a2[] = (int[]) { 1 }; /* { dg-warning "12:initializer element is not constant" } */
 
diff --git a/gcc/testsuite/gcc.dg/utf-array-short-wchar.c b/gcc/testsuite/gcc.dg/utf-array-short-wchar.c
index c5da939f34e..1691bbc0475 100644
--- a/gcc/testsuite/gcc.dg/utf-array-short-wchar.c
+++ b/gcc/testsuite/gcc.dg/utf-array-short-wchar.c
@@ -10,16 +10,16 @@  typedef __CHAR16_TYPE__ char16_t;
 typedef __CHAR32_TYPE__ char32_t;
 
 const char	s_0[]	= "ab";
-const char	s_1[]	= u"ab";	/* { dg-error "from wide string" } */
-const char	s_2[]	= U"ab";	/* { dg-error "from wide string" } */
-const char	s_3[]	= L"ab";	/* { dg-error "from wide string" } */
+const char	s_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .short unsigned int." } */
+const char	s_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .unsigned int." } */
+const char	s_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .short unsigned int." } */
 const char	s_4[]	= u8"ab";
 
-const char16_t	s16_0[]	= "ab";		/* { dg-error "from non-wide" } */
+const char16_t	s16_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
 const char16_t	s16_1[]	= u"ab";
-const char16_t	s16_2[]	= U"ab";	/* { dg-error "from incompatible" } */
+const char16_t	s16_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .unsigned int." } */
 const char16_t	s16_3[]	= L"ab";
-const char16_t	s16_4[]	= u8"ab";	/* { dg-error "from non-wide" } */
+const char16_t	s16_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
 const char16_t	s16_5[0] = u"ab";	/* { dg-warning "chars is too long" } */
 const char16_t	s16_6[1] = u"ab";	/* { dg-warning "chars is too long" } */
@@ -27,11 +27,11 @@  const char16_t	s16_7[2] = u"ab";
 const char16_t	s16_8[3] = u"ab";
 const char16_t	s16_9[4] = u"ab";
 
-const char32_t	s32_0[]	= "ab";		/* { dg-error "from non-wide" } */
-const char32_t	s32_1[]	= u"ab";	/* { dg-error "from incompatible" } */
+const char32_t	s32_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
+const char32_t	s32_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .short unsigned int." } */
 const char32_t	s32_2[]	= U"ab";
-const char32_t	s32_3[]	= L"ab";	/* { dg-error "from incompatible" } */
-const char32_t	s32_4[]	= u8"ab";	/* { dg-error "from non-wide" } */
+const char32_t	s32_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .short unsigned int." } */
+const char32_t	s32_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
 const char32_t	s32_5[0] = U"ab";	/* { dg-warning "chars is too long" } */
 const char32_t	s32_6[1] = U"ab";	/* { dg-warning "chars is too long" } */
@@ -39,8 +39,8 @@  const char32_t	s32_7[2] = U"ab";	/* { dg-warning "chars is too long" "" { target
 const char32_t	s32_8[3] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
 const char32_t	s32_9[4] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
 
-const wchar_t	sw_0[]	= "ab";		/* { dg-error "from non-wide" } */
+const wchar_t	sw_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
 const wchar_t	sw_1[]	= u"ab";
-const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from incompatible" } */
+const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .unsigned int." } */
 const wchar_t	sw_3[]	= L"ab";
-const wchar_t	sw_4[]	= u8"ab";	/* { dg-error "from non-wide" } */
+const wchar_t	sw_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
diff --git a/gcc/testsuite/gcc.dg/utf-array.c b/gcc/testsuite/gcc.dg/utf-array.c
index 1d864220c98..da6a0c9233a 100644
--- a/gcc/testsuite/gcc.dg/utf-array.c
+++ b/gcc/testsuite/gcc.dg/utf-array.c
@@ -10,16 +10,16 @@  typedef __CHAR16_TYPE__	char16_t;
 typedef __CHAR32_TYPE__	char32_t;
 
 const char	s_0[]	= "ab";
-const char	s_1[]	= u"ab";	/* { dg-error "from wide string" } */
-const char	s_2[]	= U"ab";	/* { dg-error "from wide string" } */
-const char	s_3[]	= L"ab";	/* { dg-error "from wide string" } */
+const char	s_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .short unsigned int." } */
+const char	s_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .unsigned int." } */
+const char	s_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .int." } */
 const char	s_4[]	= u8"ab";
 
-const char16_t	s16_0[]	= "ab";		/* { dg-error "from non-wide" } */
+const char16_t	s16_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
 const char16_t	s16_1[]	= u"ab";
-const char16_t	s16_2[]	= U"ab";	/* { dg-error "from incompatible" } */
-const char16_t	s16_3[]	= L"ab";	/* { dg-error "from incompatible" "" { target { ! wchar_t_char16_t_compatible } } } */
-const char16_t	s16_4[]	= u8"ab";	/* { dg-error "from non-wide" } */
+const char16_t	s16_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .unsigned int." } */
+const char16_t	s16_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .int." "" { target { ! wchar_t_char16_t_compatible } } } */
+const char16_t	s16_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
 const char16_t	s16_5[0] = u"ab";	/* { dg-warning "chars is too long" } */
 const char16_t	s16_6[1] = u"ab";	/* { dg-warning "chars is too long" } */
@@ -27,11 +27,11 @@  const char16_t	s16_7[2] = u"ab";
 const char16_t	s16_8[3] = u"ab";
 const char16_t	s16_9[4] = u"ab";
 
-const char32_t	s32_0[]	= "ab";		/* { dg-error "from non-wide" } */
-const char32_t	s32_1[]	= u"ab";	/* { dg-error "from incompatible" } */
+const char32_t	s32_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
+const char32_t	s32_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .short unsigned int." } */
 const char32_t	s32_2[]	= U"ab";
-const char32_t	s32_3[]	= L"ab";	/* { dg-error "from incompatible" "" { target { ! wchar_t_char32_t_compatible } } } */
-const char32_t	s32_4[]	= u8"ab";	/* { dg-error "from non-wide" } */
+const char32_t	s32_3[]	= L"ab";	/* { dg-error "from a string literal with type array of .int." "" { target { ! wchar_t_char32_t_compatible } } } */
+const char32_t	s32_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
 const char32_t	s32_5[0] = U"ab";	/* { dg-warning "chars is too long" } */
 const char32_t	s32_6[1] = U"ab";	/* { dg-warning "chars is too long" } */
@@ -39,8 +39,8 @@  const char32_t	s32_7[2] = U"ab";	/* { dg-warning "chars is too long" "" { target
 const char32_t	s32_8[3] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
 const char32_t	s32_9[4] = U"ab";	/* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */
 
-const wchar_t	sw_0[]	= "ab";		/* { dg-error "from non-wide" } */
-const wchar_t	sw_1[]	= u"ab";	/* { dg-error "from incompatible" "" { target { ! wchar_t_char16_t_compatible } } } */
-const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from incompatible" "" { target { ! wchar_t_char32_t_compatible } } } */
+const wchar_t	sw_0[]	= "ab";		/* { dg-error "from a string literal with type array of .char." } */
+const wchar_t	sw_1[]	= u"ab";	/* { dg-error "from a string literal with type array of .short unsigned int." "" { target { ! wchar_t_char16_t_compatible } } } */
+const wchar_t	sw_2[]	= U"ab";	/* { dg-error "from a string literal with type array of .unsigned int." "" { target { ! wchar_t_char32_t_compatible } } } */
 const wchar_t	sw_3[]	= L"ab";
-const wchar_t	sw_4[]	= u8"ab";	/* { dg-error "from non-wide" } */
+const wchar_t	sw_4[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
diff --git a/gcc/testsuite/gcc.dg/utf8-2.c b/gcc/testsuite/gcc.dg/utf8-2.c
index f3b83fe3341..d96b15dccb7 100644
--- a/gcc/testsuite/gcc.dg/utf8-2.c
+++ b/gcc/testsuite/gcc.dg/utf8-2.c
@@ -8,9 +8,9 @@  typedef __CHAR16_TYPE__	char16_t;
 typedef __CHAR32_TYPE__ char32_t;
 
 const char	s0[]	= u8"ab";
-const char16_t	s1[]	= u8"ab";	/* { dg-error "from non-wide" } */
-const char32_t  s2[]    = u8"ab";	/* { dg-error "from non-wide" } */
-const wchar_t   s3[]    = u8"ab";	/* { dg-error "from non-wide" } */
+const char16_t	s1[]	= u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
+const char32_t  s2[]    = u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
+const wchar_t   s3[]    = u8"ab";	/* { dg-error "from a string literal with type array of .char." } */
 
 const char      t0[0]   = u8"ab";	/* { dg-warning "chars is too long" } */
 const char      t1[1]   = u8"ab";	/* { dg-warning "chars is too long" } */