From patchwork Sat Sep 24 01:16:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 57986 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 28479385840A for ; Sat, 24 Sep 2022 01:17:36 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 28479385840A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1663982256; bh=qq3KiuaUvCUB/WbpjOfl/l3MpXH55r1278IuwrGBE9o=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=dyzSqOj6xNNabGSUCru6tEabePWg1v/hzFCIa9xMHc2rPEVit8YMoxd87j9UJZ67A 96Uw1YKH6CFbdGaaWdJp/dp+yr8V36r1ys8ldc7sujnnhq62icqaWwCgcW/6n4dghd /fqqrCnVeTuH/1zvjNOm0VgcFHByDMyK9jGZylX8= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 3758A3858D1E for ; Sat, 24 Sep 2022 01:16:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 3758A3858D1E Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-447-cznYu-oJOSiaqBhly_KOvA-1; Fri, 23 Sep 2022 21:16:21 -0400 X-MC-Unique: cznYu-oJOSiaqBhly_KOvA-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 194CE3C021AC for ; Sat, 24 Sep 2022 01:16:21 +0000 (UTC) Received: from pdp-11.redhat.com (unknown [10.22.32.241]) by smtp.corp.redhat.com (Postfix) with ESMTP id EC08817593; Sat, 24 Sep 2022 01:16:20 +0000 (UTC) To: GCC Patches , Jason Merrill Subject: [PATCH] c++: P2513R4, char8_t Compatibility and Portability Fix [PR106656] Date: Fri, 23 Sep 2022 21:16:11 -0400 Message-Id: <20220924011611.433106-1-polacek@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.0 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Marek Polacek via Gcc-patches From: Marek Polacek Reply-To: Marek Polacek Errors-To: gcc-patches-bounces+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" 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? 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 base-commit: f5072839c46acd185f40a5692aca06fac4ed6a48 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(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";