Commit 17ad43dd by Tom Honermann Committed by Jason Merrill

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.

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

From-SVN: r268047
parent f18aa3a4
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> 2019-01-12 Jakub Jelinek <jakub@redhat.com>
* c-typeck.c (convert_for_assignment): Fix a comment typo. * c-typeck.c (convert_for_assignment): Fix a comment typo.
......
...@@ -6339,17 +6339,21 @@ convert_to_anonymous_field (location_t location, tree type, tree rhs) ...@@ -6339,17 +6339,21 @@ convert_to_anonymous_field (location_t location, tree type, tree rhs)
GMSGID identifies the message. GMSGID identifies the message.
The component name is taken from the spelling stack. */ The component name is taken from the spelling stack. */
static void static void ATTRIBUTE_GCC_DIAG (2,0)
error_init (location_t loc, const char *gmsgid) error_init (location_t loc, const char *gmsgid, ...)
{ {
char *ofwhat; char *ofwhat;
auto_diagnostic_group d; auto_diagnostic_group d;
/* The gmsgid may be a format string with %< and %>. */ /* 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)); ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
if (*ofwhat) if (*ofwhat && warned)
inform (loc, "(near initialization for %qs)", ofwhat); inform (loc, "(near initialization for %qs)", ofwhat);
} }
...@@ -7722,6 +7726,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, ...@@ -7722,6 +7726,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
{ {
struct c_expr expr; struct c_expr expr;
tree typ2 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init))); tree typ2 = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (inside_init)));
bool incompat_string_cst = false;
expr.value = inside_init; expr.value = inside_init;
expr.original_code = (strict_string ? STRING_CST : ERROR_MARK); expr.original_code = (strict_string ? STRING_CST : ERROR_MARK);
expr.original_type = NULL; expr.original_type = NULL;
...@@ -7738,27 +7743,18 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, ...@@ -7738,27 +7743,18 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
if (char_array) if (char_array)
{ {
if (typ2 != char_type_node) if (typ2 != char_type_node)
{ incompat_string_cst = true;
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;
}
} }
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 if (TYPE_DOMAIN (type) != NULL_TREE
&& TYPE_SIZE (type) != NULL_TREE && TYPE_SIZE (type) != NULL_TREE
......
...@@ -28,8 +28,8 @@ uchar a8[] = "foo"; /* { dg-error "string constant" "a8" } */ ...@@ -28,8 +28,8 @@ uchar a8[] = "foo"; /* { dg-error "string constant" "a8" } */
const schar a9[] = "foo"; /* { dg-error "string constant" "a9" } */ const schar a9[] = "foo"; /* { dg-error "string constant" "a9" } */
short a10[] = L"foo"; /* { dg-error "string constant" "a10" } */ short a10[] = L"foo"; /* { dg-error "string constant" "a10" } */
const sshrt a11[] = L"foo"; /* { dg-error "string constant" "a11" } */ const sshrt a11[] = L"foo"; /* { dg-error "string constant" "a11" } */
char a12[] = L"foo"; /* { dg-error "from wide string" "a12" } */ char a12[] = L"foo"; /* { dg-error "from a string literal with type array of" "a12" } */
wchar_t a13[] = "foo"; /* { dg-error "non-wide string" "a13" } */ wchar_t a13[] = "foo"; /* { dg-error "from a string literal with type array of .char." "a13" } */
char b0[] = { "foo" }; char b0[] = { "foo" };
const signed char b2[4] = { "foo" }; const signed char b2[4] = { "foo" };
...@@ -43,8 +43,8 @@ uchar b8[] = { "foo" }; /* { dg-error "string constant" "b8" } */ ...@@ -43,8 +43,8 @@ uchar b8[] = { "foo" }; /* { dg-error "string constant" "b8" } */
const schar b9[] = { "foo" }; /* { dg-error "string constant" "b9" } */ const schar b9[] = { "foo" }; /* { dg-error "string constant" "b9" } */
short b10[] = { L"foo" }; /* { dg-error "string constant" "b10" } */ short b10[] = { L"foo" }; /* { dg-error "string constant" "b10" } */
const sshrt b11[] = { L"foo" }; /* { dg-error "string constant" "b11" } */ const sshrt b11[] = { L"foo" }; /* { dg-error "string constant" "b11" } */
char b12[] = { L"foo" }; /* { dg-error "from wide string" "b12" } */ char b12[] = { L"foo" }; /* { dg-error "from a string literal with type array of" "b12" } */
wchar_t b13[] = { "foo" }; /* { dg-error "non-wide string" "b13" } */ 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]; }; struct s { signed char a[10]; int b; ushrt c[10]; };
......
...@@ -19,9 +19,9 @@ struct g ...@@ -19,9 +19,9 @@ struct g
struct f f; /* { dg-warning "invalid use of structure with flexible array member" } */ 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" } */ 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:wide character array initialized from non-wide string" } */ __WCHAR_TYPE__ w2[] = "foo"; /* { dg-error "23:from a string literal with type array of .char." } */
__WCHAR_TYPE__ w3[] = U"foo"; /* { dg-error "23:wide character array initialized from incompatible wide string" } */ __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" } */ 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" } */ int a2[] = (int[]) { 1 }; /* { dg-warning "12:initializer element is not constant" } */
......
...@@ -10,33 +10,37 @@ typedef __CHAR16_TYPE__ char16_t; ...@@ -10,33 +10,37 @@ typedef __CHAR16_TYPE__ char16_t;
typedef __CHAR32_TYPE__ char32_t; typedef __CHAR32_TYPE__ char32_t;
const char s_0[] = "ab"; const char s_0[] = "ab";
const char s_1[] = u"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 wide string" } */ 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 wide string" } */ 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_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_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[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[1] = u"ab"; /* { dg-warning "chars is too long" } */
const char16_t s16_6[2] = u"ab"; const char16_t s16_7[2] = u"ab";
const char16_t s16_7[3] = u"ab"; const char16_t s16_8[3] = u"ab";
const char16_t s16_8[4] = 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_0[] = "ab"; /* { dg-error "from a string literal with type array of .char." } */
const char32_t s32_1[] = u"ab"; /* { dg-error "from incompatible" } */ 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_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[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[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[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[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_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_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_3[] = L"ab";
const wchar_t sw_4[] = u8"ab"; /* { dg-error "from a string literal with type array of .char." } */
...@@ -10,33 +10,37 @@ typedef __CHAR16_TYPE__ char16_t; ...@@ -10,33 +10,37 @@ typedef __CHAR16_TYPE__ char16_t;
typedef __CHAR32_TYPE__ char32_t; typedef __CHAR32_TYPE__ char32_t;
const char s_0[] = "ab"; const char s_0[] = "ab";
const char s_1[] = u"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 wide string" } */ 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 wide string" } */ 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_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"; /* { dg-error "from incompatible" "" { target { ! wchar_t_char16_t_compatible } } } */ 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_5[0] = u"ab"; /* { dg-warning "chars is too long" } */
const char16_t s16_6[2] = u"ab"; const char16_t s16_6[1] = u"ab"; /* { dg-warning "chars is too long" } */
const char16_t s16_7[3] = u"ab"; const char16_t s16_7[2] = u"ab";
const char16_t s16_8[4] = 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_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_5[0] = 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_6[1] = U"ab"; /* { dg-warning "chars is too long" } */
const char32_t s32_7[3] = U"ab"; /* { dg-warning "chars is too long" "" { target "m32c-*-*" } } */ const char32_t s32_7[2] = 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_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_0[] = "ab"; /* { dg-error "from a string literal with type array of .char." } */
const wchar_t sw_2[] = U"ab"; /* { dg-error "from incompatible" "" { target { ! wchar_t_char32_t_compatible } } } */ 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_3[] = L"ab";
const wchar_t sw_4[] = u8"ab"; /* { dg-error "from a string literal with type array of .char." } */
...@@ -8,9 +8,9 @@ typedef __CHAR16_TYPE__ char16_t; ...@@ -8,9 +8,9 @@ typedef __CHAR16_TYPE__ char16_t;
typedef __CHAR32_TYPE__ char32_t; typedef __CHAR32_TYPE__ char32_t;
const char s0[] = u8"ab"; const char s0[] = u8"ab";
const char16_t s1[] = 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 non-wide" } */ 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 non-wide" } */ 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 t0[0] = u8"ab"; /* { dg-warning "chars is too long" } */
const char t1[1] = u8"ab"; /* { dg-warning "chars is too long" } */ const char t1[1] = u8"ab"; /* { dg-warning "chars is too long" } */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment