From patchwork Sun Sep 15 19:39:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Honermann X-Patchwork-Id: 1162523 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-509026-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=honermann.net Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="yxm2U34L"; dkim=pass (1024-bit key; unprotected) header.d=honermann.net header.i=@honermann.net header.b="XszNMrkH"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46WfqL4v2Pz9sN1 for ; Mon, 16 Sep 2019 05:40:30 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; q=dns; s= default; b=edFZuHsi53L6eB6PHLpq0V/YfUP4ultV4yBc4lNM+6RP+NhsWq0NP KaNHQT5DWTV7D9OAAr6NWH8DpRHCSRiQAtGIfAfo3xV5dgtWAim1TsRsbWN4FKEJ ZJcr1i1gVbWGjB+R53e2usRhu9gJlwVxftH5ELELMJ2F7MMRaNaYg8= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :subject:to:message-id:date:mime-version:content-type; s= default; bh=8bOLwKlWGnWWRhnP6bQeDplTZ7Q=; b=yxm2U34LBWbZLg4d9Yj/ ABl+sY2FQKDBCjBo7LNys9xje1mrYgAZM74vd5qkjtEv9R7R2cjeGYbp6QP70bqo +OJQ8CSVdZHNbNKC9jiimbLcvNZg5+k1YlnAz06HRXISdyYo9wQZyblN5xOHB7fj 8YoTuqsXOqE0IZR8pyRuoZ0= Received: (qmail 4099 invoked by alias); 15 Sep 2019 19:39:49 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 4022 invoked by uid 89); 15 Sep 2019 19:39:48 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-15.8 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=increments X-HELO: smtp117.iad3b.emailsrvr.com Received: from smtp117.iad3b.emailsrvr.com (HELO smtp117.iad3b.emailsrvr.com) (146.20.161.117) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sun, 15 Sep 2019 19:39:45 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=honermann.net; s=20180930-2j89z3ji; t=1568576383; bh=+Kva1kBkSOJpmQYiylbRZNFlOzU7/+9M5fRucL32ffs=; h=From:Subject:To:Date:From; b=XszNMrkHlIL4bety1G6J16fIPBI7Cbaicz8A9CSPKZsuspzwKVUoQc4M/38P8MYPp I7ctCM0SLVf8Jn9qTdQTljHLYasvXOIfGqN+HGM0MwwfLjTtC/x/N3/1bVCWH0+xL4 D7bAz5lHjAJcZR3x/8GTNpdD0yeSu4H5L9elhJkM= X-Auth-ID: tom@honermann.net Received: by smtp15.relay.iad3b.emailsrvr.com (Authenticated sender: tom-AT-honermann.net) with ESMTPSA id 99EE0C00BB; Sun, 15 Sep 2019 15:39:43 -0400 (EDT) X-Sender-Id: tom@honermann.net Received: from [192.168.1.20] (pool-72-84-244-119.rcmdva.fios.verizon.net [72.84.244.119]) (using TLSv1.2 with cipher AES128-SHA) by 0.0.0.0:25 (trex/5.7.12); Sun, 15 Sep 2019 15:39:43 -0400 From: Tom Honermann Subject: [PATCH 2/4]: C++ P1423R3 char8_t remediation: Update feature test macro, add deleted operators, update u8path To: "libstdc++@gcc.gnu.org" , gcc-patches Message-ID: <05f9b7ab-b89a-4348-e758-e7ef9077261a@honermann.net> Date: Sun, 15 Sep 2019 15:39:41 -0400 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 X-IsSubscribed: yes This patch increments the __cpp_lib_char8_t feature test macro, adds deleted operator<< overloads for basic_ostream, and modifies u8path to accept sequences of char8_t for both the C++17 implementation of std::filesystem, and the filesystem TS implementation. The implementation mechanism used for u8path differs between the C++17 and filesystem TS implementations. The changes to the former take advantage of C++17 'if constexpr'. The changes to the latter retain C++11 compatibility and rely on tag dispatching. libstdc++-v3/ChangeLog: 2019-09-15 Tom Honermann * libstdc++-v3/include/bits/c++config: Bumped the value of the __cpp_lib_char8_t feature test macro. * libstdc++-v3/include/bits/fs_path.h (u8path): Modified u8path to accept sequences of char8_t. * libstdc++-v3/include/experimental/bits/fs_path.h (u8path): Modified u8path to accept sequences of char8_t. * libstdc++-v3/include/std/ostream: Added deleted overloads of wchar_t, char8_t, char16_t, and char32_t for ordinary and wide formatted character and string inserters. Tom. diff --git a/libstdc++-v3/include/bits/c++config b/libstdc++-v3/include/bits/c++config index c8e099aaadd..5bcf32d95ef 100644 --- a/libstdc++-v3/include/bits/c++config +++ b/libstdc++-v3/include/bits/c++config @@ -620,7 +620,7 @@ namespace std # endif #endif #ifdef _GLIBCXX_USE_CHAR8_T -# define __cpp_lib_char8_t 201811L +# define __cpp_lib_char8_t 201907L #endif /* Define if __float128 is supported on this host. */ diff --git a/libstdc++-v3/include/bits/fs_path.h b/libstdc++-v3/include/bits/fs_path.h index 71354515403..f3f539412fc 100644 --- a/libstdc++-v3/include/bits/fs_path.h +++ b/libstdc++-v3/include/bits/fs_path.h @@ -153,9 +153,24 @@ namespace __detail template())), - typename _Val = typename std::iterator_traits<_Iter>::value_type> + typename _Val = typename std::iterator_traits<_Iter>::value_type, + typename _UnqualVal = std::remove_const_t<_Val>> using __value_type_is_char - = std::enable_if_t, char>>; + = std::enable_if_t, + _UnqualVal>; + + template())), + typename _Val = typename std::iterator_traits<_Iter>::value_type, + typename _UnqualVal = std::remove_const_t<_Val>> + using __value_type_is_char_or_char8_t + = std::enable_if_t<__or_v< + std::is_same<_UnqualVal, char> +#ifdef _GLIBCXX_USE_CHAR8_T + ,std::is_same<_UnqualVal, char8_t> +#endif + >, + _UnqualVal>; // @} group filesystem-detail } // namespace __detail @@ -639,29 +654,41 @@ namespace __detail /// Create a path from a UTF-8-encoded sequence of char template, - typename _Require2 = __detail::__value_type_is_char<_InputIterator>> + typename _CharT = + __detail::__value_type_is_char_or_char8_t<_InputIterator>> inline path u8path(_InputIterator __first, _InputIterator __last) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - // XXX This assumes native wide encoding is UTF-16. - std::codecvt_utf8_utf16 __cvt; - path::string_type __tmp; - if constexpr (is_pointer_v<_InputIterator>) +#ifdef _GLIBCXX_USE_CHAR8_T + if constexpr (is_same_v<_CharT, char8_t>) { - if (__str_codecvt_in_all(__first, __last, __tmp, __cvt)) - return path{ __tmp }; + return path{ __first, __last }; } else { - const std::string __u8str{__first, __last}; - const char* const __ptr = __u8str.data(); - if (__str_codecvt_in_all(__ptr, __ptr + __u8str.size(), __tmp, __cvt)) - return path{ __tmp }; +#endif + // XXX This assumes native wide encoding is UTF-16. + std::codecvt_utf8_utf16 __cvt; + path::string_type __tmp; + if constexpr (is_pointer_v<_InputIterator>) + { + if (__str_codecvt_in_all(__first, __last, __tmp, __cvt)) + return path{ __tmp }; + } + else + { + const std::string __u8str{__first, __last}; + const char* const __ptr = __u8str.data(); + if (__str_codecvt_in_all(__ptr, __ptr + __u8str.size(), __tmp, __cvt)) + return path{ __tmp }; + } + _GLIBCXX_THROW_OR_ABORT(filesystem_error( + "Cannot convert character sequence", + std::make_error_code(errc::illegal_byte_sequence))); +#ifdef _GLIBCXX_USE_CHAR8_T } - _GLIBCXX_THROW_OR_ABORT(filesystem_error( - "Cannot convert character sequence", - std::make_error_code(errc::illegal_byte_sequence))); +#endif #else // This assumes native normal encoding is UTF-8. return path{ __first, __last }; @@ -671,21 +698,32 @@ namespace __detail /// Create a path from a UTF-8-encoded sequence of char template, - typename _Require2 = __detail::__value_type_is_char<_Source>> + typename _CharT = __detail::__value_type_is_char_or_char8_t<_Source>> inline path u8path(const _Source& __source) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - if constexpr (is_convertible_v) +#ifdef _GLIBCXX_USE_CHAR8_T + if constexpr (is_same_v<_CharT, char8_t>) { - const std::string_view __s = __source; - return filesystem::u8path(__s.data(), __s.data() + __s.size()); + return path{ __source }; } else { - std::string __s = path::_S_string_from_iter(__source); - return filesystem::u8path(__s.data(), __s.data() + __s.size()); +#endif + if constexpr (is_convertible_v) + { + const std::string_view __s = __source; + return filesystem::u8path(__s.data(), __s.data() + __s.size()); + } + else + { + std::string __s = path::_S_string_from_iter(__source); + return filesystem::u8path(__s.data(), __s.data() + __s.size()); + } +#ifdef _GLIBCXX_USE_CHAR8_T } +#endif #else return path{ __source }; #endif diff --git a/libstdc++-v3/include/experimental/bits/fs_path.h b/libstdc++-v3/include/experimental/bits/fs_path.h index 3f9a69514a1..7a8cd8d20de 100644 --- a/libstdc++-v3/include/experimental/bits/fs_path.h +++ b/libstdc++-v3/include/experimental/bits/fs_path.h @@ -169,10 +169,23 @@ namespace __detail template())), - typename _Val = typename std::iterator_traits<_Iter>::value_type> + typename _Val = typename std::iterator_traits<_Iter>::value_type, + typename _UnqualVal = typename std::remove_const<_Val>::type> using __value_type_is_char = typename std::enable_if< - std::is_same::type, char>::value - >::type; + std::is_same<_UnqualVal, char>::value, + _UnqualVal>::type; + + template())), + typename _Val = typename std::iterator_traits<_Iter>::value_type, + typename _UnqualVal = typename std::remove_const<_Val>::type> + using __value_type_is_char_or_char8_t = typename std::enable_if< + __or_< + std::is_same<_UnqualVal, char> +#ifdef _GLIBCXX_USE_CHAR8_T + ,std::is_same<_UnqualVal, char8_t> +#endif + >::value, _UnqualVal>::type; // @} group filesystem-ts-detail } // namespace __detail @@ -592,13 +605,11 @@ namespace __detail } /// Create a path from a UTF-8-encoded sequence of char - template, - typename _Require2 = __detail::__value_type_is_char<_InputIterator>> +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS + template inline path - u8path(_InputIterator __first, _InputIterator __last) + __u8path(_InputIterator __first, _InputIterator __last, char) { -#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS // XXX This assumes native wide encoding is UTF-16. std::codecvt_utf8_utf16 __cvt; path::string_type __tmp; @@ -609,21 +620,61 @@ namespace __detail _GLIBCXX_THROW_OR_ABORT(filesystem_error( "Cannot convert character sequence", std::make_error_code(errc::illegal_byte_sequence))); + } + +#ifdef _GLIBCXX_USE_CHAR8_T + template + inline path + __u8path(_InputIterator __first, _InputIterator __last, char8_t) + { + return path{ __first, __last }; + } +#endif // _GLIBCXX_USE_CHAR8_T +#endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS + + template, + typename _CharT = + __detail::__value_type_is_char_or_char8_t<_InputIterator>> + inline path + u8path(_InputIterator __first, _InputIterator __last) + { +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS + return __u8path(__first, __last, _CharT{}); #else return path{ __first, __last }; #endif } /// Create a path from a UTF-8-encoded sequence of char +#ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS + template + inline path + __u8path(const _Source& __source, char) + { + std::string __s = path::_S_string_from_iter(__source); + return filesystem::u8path(__s.data(), __s.data() + __s.size()); + } + +#ifdef _GLIBCXX_USE_CHAR8_T + template + inline path + __u8path(const _Source& __source, char8_t) + { + return path{ __source }; + } +#endif // _GLIBCXX_USE_CHAR8_T +#endif // _GLIBCXX_FILESYSTEM_IS_WINDOWS + template, - typename _Require2 = __detail::__value_type_is_char<_Source>> + typename _CharT = + __detail::__value_type_is_char_or_char8_t<_Source>> inline path u8path(const _Source& __source) { #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS - std::string __s = path::_S_string_from_iter(__source); - return filesystem::u8path(__s.data(), __s.data() + __s.size()); + return __u8path(__source, _CharT{}); #else return path{ __source }; #endif diff --git a/libstdc++-v3/include/std/ostream b/libstdc++-v3/include/std/ostream index 2541d978886..94308d5de04 100644 --- a/libstdc++-v3/include/std/ostream +++ b/libstdc++-v3/include/std/ostream @@ -527,6 +527,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline basic_ostream& operator<<(basic_ostream& __out, unsigned char __c) { return (__out << static_cast(__c)); } + +#ifdef _GLIBCXX_USE_CHAR8_T + // The following deleted overloads prevent formatting character values as + // numeric values. + + template + basic_ostream& + operator<<(basic_ostream&, wchar_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char8_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char16_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char32_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char8_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char16_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char32_t) = delete; +#endif // _GLIBCXX_USE_CHAR8_T //@} //@{ @@ -582,6 +615,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline basic_ostream & operator<<(basic_ostream& __out, const unsigned char* __s) { return (__out << reinterpret_cast(__s)); } + +#ifdef _GLIBCXX_USE_CHAR8_T + // The following deleted overloads prevent formatting strings as + // pointer values. + + template + basic_ostream& + operator<<(basic_ostream&, const wchar_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char8_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char16_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char32_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char8_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char16_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char32_t*) = delete; +#endif // _GLIBCXX_USE_CHAR8_T //@} // Standard basic_ostream manipulators