Improve the C error for mismatched array string literal initialization.
authorTom Honermann <tom@honermann.net>
Thu, 17 Jan 2019 20:43:38 +0000 (20:43 +0000)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 17 Jan 2019 20:43:38 +0000 (15:43 -0500)
* 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.

Co-Authored-By: Jason Merrill <jason@redhat.com>
From-SVN: r268047

gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/testsuite/gcc.dg/init-string-2.c
gcc/testsuite/gcc.dg/pr61096-1.c
gcc/testsuite/gcc.dg/utf-array-short-wchar.c
gcc/testsuite/gcc.dg/utf-array.c
gcc/testsuite/gcc.dg/utf8-2.c

index 167c78a..2accb8f 100644 (file)
@@ -1,3 +1,10 @@
+2019-01-16  Tom Honermann  <tom@honermann.net>
+           Jason Merrill  <jason@redhat.com>
+
+       * 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.
+
 2019-01-12  Jakub Jelinek  <jakub@redhat.com>
 
        * c-typeck.c (convert_for_assignment): Fix a comment typo.
index 63d177f..6da1f32 100644 (file)
@@ -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
index 9efd44b..ded9bf2 100644 (file)
@@ -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]; };
 
index 6678d81..111585d 100644 (file)
@@ -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" } */
 
index ec47812..a582e71 100644 (file)
@@ -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." } */
index 433ddcf..74a0c0c 100644 (file)
@@ -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_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 char32_t s32_0[] = "ab";         /* { dg-error "from non-wide" } */
-const char32_t s32_1[] = 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";        /* { 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" } */
+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 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_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 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 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" } */
+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 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." } */
index f3b83fe..d96b15d 100644 (file)
@@ -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" } */