public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jason Merrill <jason@redhat.com>
To: Marek Polacek <polacek@redhat.com>,
	GCC Patches <gcc-patches@gcc.gnu.org>
Subject: Re: [PATCH] c++: P2513R4, char8_t Compatibility and Portability Fix [PR106656]
Date: Mon, 26 Sep 2022 13:18:20 -0400	[thread overview]
Message-ID: <abf53eb4-8096-788a-2122-677e6cba7545@redhat.com> (raw)
In-Reply-To: <20220924011611.433106-1-polacek@redhat.com>

On 9/23/22 21:16, Marek Polacek wrote:
> P0482R6, which added char8_t, didn't allow
> 
>    const char arr[] = u8"howdy";
> 
> because it said "Declarations of arrays of char may currently be initialized
> with UTF-8 string literals. Under this proposal, such initializations would
> become ill-formed."  This caused too many issues, so P2513R4 alleviates some
> of those compatibility problems.  In particular, "Arrays of char or unsigned
> char may now be initialized with a UTF-8 string literal."  This restriction
> has been lifted for initialization only, not implicit conversions.  Also,
> my reading is that 'signed char' was excluded from the allowable conversions.
> 
> This is supposed to be treated as a DR in C++20.
> 
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

OK.

> 	PR c++/106656
> 
> gcc/c-family/ChangeLog:
> 
> 	* c-cppbuiltin.cc (c_cpp_builtins): Update value of __cpp_char8_t
> 	for C++20.
> 
> gcc/cp/ChangeLog:
> 
> 	* typeck2.cc (array_string_literal_compatible_p): Allow
> 	initializing arrays of char or unsigned char by a UTF-8 string literal.
> 
> gcc/testsuite/ChangeLog:
> 
> 	* g++.dg/cpp23/feat-cxx2b.C: Adjust.
> 	* g++.dg/cpp2a/feat-cxx2a.C: Likewise.
> 	* g++.dg/ext/char8_t-feature-test-macro-2.C: Likewise.
> 	* g++.dg/ext/char8_t-init-2.C: Likewise.
> 	* g++.dg/cpp2a/char8_t3.C: New test.
> 	* g++.dg/cpp2a/char8_t4.C: New test.
> ---
>   gcc/c-family/c-cppbuiltin.cc                  |  2 +-
>   gcc/cp/typeck2.cc                             |  9 +++++
>   gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C       |  4 +-
>   gcc/testsuite/g++.dg/cpp2a/char8_t3.C         | 37 +++++++++++++++++++
>   gcc/testsuite/g++.dg/cpp2a/char8_t4.C         | 17 +++++++++
>   gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C       |  4 +-
>   .../g++.dg/ext/char8_t-feature-test-macro-2.C |  4 +-
>   gcc/testsuite/g++.dg/ext/char8_t-init-2.C     |  4 +-
>   8 files changed, 72 insertions(+), 9 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/char8_t3.C
>   create mode 100644 gcc/testsuite/g++.dg/cpp2a/char8_t4.C
> 
> diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
> index a1557eb23d5..b709f845c81 100644
> --- a/gcc/c-family/c-cppbuiltin.cc
> +++ b/gcc/c-family/c-cppbuiltin.cc
> @@ -1112,7 +1112,7 @@ c_cpp_builtins (cpp_reader *pfile)
>         if (flag_threadsafe_statics)
>   	cpp_define (pfile, "__cpp_threadsafe_static_init=200806L");
>         if (flag_char8_t)
> -        cpp_define (pfile, "__cpp_char8_t=201811L");
> +	cpp_define (pfile, "__cpp_char8_t=202207L");
>   #ifndef THREAD_MODEL_SPEC
>         /* Targets that define THREAD_MODEL_SPEC need to define
>   	 __STDCPP_THREADS__ in their config/XXX/XXX-c.c themselves.  */
> diff --git a/gcc/cp/typeck2.cc b/gcc/cp/typeck2.cc
> index 75fd0e2a9bf..739097a9734 100644
> --- a/gcc/cp/typeck2.cc
> +++ b/gcc/cp/typeck2.cc
> @@ -1118,6 +1118,15 @@ array_string_literal_compatible_p (tree type, tree init)
>     if (ordinary_char_type_p (to_char_type)
>         && ordinary_char_type_p (from_char_type))
>       return true;
> +
> +  /* P2513 (C++20/C++23): "an array of char or unsigned char may
> +     be initialized by a UTF-8 string literal, or by such a string
> +     literal enclosed in braces."  */
> +  if (from_char_type == char8_type_node
> +      && (to_char_type == char_type_node
> +	  || to_char_type == unsigned_char_type_node))
> +    return true;
> +
>     return false;
>   }
>   
> diff --git a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
> index d3e40724085..0537e1d24b5 100644
> --- a/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
> +++ b/gcc/testsuite/g++.dg/cpp23/feat-cxx2b.C
> @@ -504,8 +504,8 @@
>   
>   #ifndef __cpp_char8_t
>   #  error "__cpp_char8_t"
> -#elif __cpp_char8_t != 201811
> -#  error "__cpp_char8_t != 201811"
> +#elif __cpp_char8_t != 202207
> +#  error "__cpp_char8_t != 202207"
>   #endif
>   
>   #ifndef __cpp_designated_initializers
> diff --git a/gcc/testsuite/g++.dg/cpp2a/char8_t3.C b/gcc/testsuite/g++.dg/cpp2a/char8_t3.C
> new file mode 100644
> index 00000000000..071a718c4d0
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/char8_t3.C
> @@ -0,0 +1,37 @@
> +// PR c++/106656 - P2513 - char8_t Compatibility and Portability Fixes
> +// { dg-do compile { target c++20 } }
> +
> +const char *p1 = u8""; // { dg-error "invalid conversion" }
> +const unsigned char *p2 = u8""; // { dg-error "invalid conversion" }
> +const signed char *p3 = u8""; // { dg-error "invalid conversion" }
> +const char *p4 = { u8"" }; // { dg-error "invalid conversion" }
> +const unsigned char *p5 = { u8"" }; // { dg-error "invalid conversion" }
> +const signed char *p6 = { u8"" }; // { dg-error "invalid conversion" }
> +const char *p7 = static_cast<const char *>(u8""); // { dg-error "invalid" }
> +const char a1[] = u8"text";
> +const unsigned char a2[] = u8"";
> +const signed char a3[] = u8""; // { dg-error "cannot initialize array" }
> +const char a4[] = { u8"text" };
> +const unsigned char a5[] = { u8"" };
> +const signed char a6[] = { u8"" }; // { dg-error "cannot initialize array" }
> +
> +const char *
> +resource_id ()
> +{
> +  static const char res_id[] = u8"";
> +  return res_id;
> +}
> +
> +const char8_t x[] = "fail"; // { dg-error "cannot initialize array" }
> +
> +void fn (const char a[]);
> +void
> +g ()
> +{
> +  fn (u8"z"); // { dg-error "invalid conversion" }
> +}
> +
> +char c = u8'c';
> +unsigned char uc = u8'c';
> +signed char sc = u8'c';
> +char8_t c8 = 'c';
> diff --git a/gcc/testsuite/g++.dg/cpp2a/char8_t4.C b/gcc/testsuite/g++.dg/cpp2a/char8_t4.C
> new file mode 100644
> index 00000000000..c18081b66fb
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp2a/char8_t4.C
> @@ -0,0 +1,17 @@
> +// PR c++/106656 - P2513 - char8_t Compatibility and Portability Fixes
> +// { dg-do compile { target c++20 } }
> +// [diff.cpp20.dcl]
> +
> +struct A {
> +	char8_t s[10];
> +};
> +struct B {
> +	char s[10];
> +};
> +
> +void f(A);
> +void f(B);
> +
> +int main() {
> +	f({u8""}); // { dg-error "ambiguous" }
> +}
> diff --git a/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C b/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
> index c65ea6bf48a..02f3a377fd0 100644
> --- a/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
> +++ b/gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C
> @@ -504,8 +504,8 @@
>   
>   #ifndef __cpp_char8_t
>   #  error "__cpp_char8_t"
> -#elif __cpp_char8_t != 201811
> -#  error "__cpp_char8_t != 201811"
> +#elif __cpp_char8_t != 202207
> +#  error "__cpp_char8_t != 202207"
>   #endif
>   
>   #ifndef __cpp_designated_initializers
> diff --git a/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C b/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C
> index df1063f6aa1..2d0f9045acf 100644
> --- a/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C
> +++ b/gcc/testsuite/g++.dg/ext/char8_t-feature-test-macro-2.C
> @@ -5,6 +5,6 @@
>   
>   #if !defined(__cpp_char8_t)
>   #  error __cpp_char8_t is not defined!
> -#elif __cpp_char8_t != 201811
> -#  error __cpp_char8_t != 201811
> +#elif __cpp_char8_t != 202207
> +#  error __cpp_char8_t != 202207
>   #endif
> 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 c713bc12266..02a96ffe5a4 100644
> --- a/gcc/testsuite/g++.dg/ext/char8_t-init-2.C
> +++ b/gcc/testsuite/g++.dg/ext/char8_t-init-2.C
> @@ -21,7 +21,7 @@ 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 "from a string literal with type array of .char8_t." "char8_t" }
> +char ca2[] = u8"x";
>   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 "from a string literal with type array of .char16_t." "char8_t" }
> @@ -30,4 +30,4 @@ signed char sca1[] = "x";
>   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 "from a string literal with type array of .char8_t." "char8_t" }
> +unsigned char uca2[] = u8"x";
> 
> base-commit: f5072839c46acd185f40a5692aca06fac4ed6a48


      reply	other threads:[~2022-09-26 17:18 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-09-24  1:16 Marek Polacek
2022-09-26 17:18 ` Jason Merrill [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=abf53eb4-8096-788a-2122-677e6cba7545@redhat.com \
    --to=jason@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=polacek@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).