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 <ja...@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" } */

Reply via email to