From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 130414 invoked by alias); 15 Jan 2019 15:15:51 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 130315 invoked by uid 89); 15 Jan 2019 15:15:41 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 spammy=flexible, incorporated, b12, init_loc X-HELO: mail-qt1-f176.google.com Received: from mail-qt1-f176.google.com (HELO mail-qt1-f176.google.com) (209.85.160.176) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 15 Jan 2019 15:15:35 +0000 Received: by mail-qt1-f176.google.com with SMTP id l11so3358306qtp.0 for ; Tue, 15 Jan 2019 07:15:26 -0800 (PST) Return-Path: Received: from [192.168.1.115] (209-6-216-142.s141.c3-0.smr-cbr1.sbo-smr.ma.cable.rcncustomer.com. [209.6.216.142]) by smtp.gmail.com with ESMTPSA id o22sm20736167qkk.93.2019.01.15.07.15.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 15 Jan 2019 07:15:24 -0800 (PST) Subject: Re: PATCH: Updated error messages for ill-formed cases of array initialization by string literal To: Tom Honermann , Martin Sebor , gcc-patches , "Joseph S. Myers" , Marek Polacek References: <50dbd993-f778-a2a4-e63c-1c2b3b85de41@gmail.com> <21994e14-d1b8-e893-72d2-86b9674e0fab@honermann.net> From: Jason Merrill Message-ID: <99ca7332-f658-d5fe-fc42-b4199111ad3d@redhat.com> Date: Tue, 15 Jan 2019 15:15:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.3.1 MIME-Version: 1.0 In-Reply-To: <21994e14-d1b8-e893-72d2-86b9674e0fab@honermann.net> Content-Type: multipart/mixed; boundary="------------1F371F247391C54C244862DC" X-IsSubscribed: yes X-SW-Source: 2019-01/txt/msg00844.txt.bz2 This is a multi-part message in MIME format. --------------1F371F247391C54C244862DC Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-length: 1789 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 --------------1F371F247391C54C244862DC Content-Type: text/x-patch; name="c-array-init-diag.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="c-array-init-diag.diff" Content-length: 14440 commit dc77155cc9868b6b5e7c634fd46813b81361e7ee Author: Jason Merrill 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" } */ --------------1F371F247391C54C244862DC--