From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 48221 invoked by alias); 16 Sep 2019 02:33:57 -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 48048 invoked by uid 89); 16 Sep 2019 02:33:57 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-20.4 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=shame X-HELO: smtp78.iad3b.emailsrvr.com Received: from smtp78.iad3b.emailsrvr.com (HELO smtp78.iad3b.emailsrvr.com) (146.20.161.78) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 16 Sep 2019 02:33:55 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=honermann.net; s=20180930-2j89z3ji; t=1568601233; bh=a4CYbYlAUaxhEWhZySfTqxgH2aeJ8xxcS+K1zfQkpbg=; h=Subject:From:To:Date:From; b=PbiFWQHYHKTGVxd97PmJFwcLENkm4bUH9CrdLuQywlGcx1tXFS8wGLeDVOKIXPqQb Rt06KeYAEKwNoZ3ASaH3eW/x4XYTRVHnaQQxRlH0Cl1V6Xp48lvnozlKJ/Y2XNTDG1 evEABxnKHwDG5dJEamAIvG+JvhwSbgvi+T20Qsz4= X-Auth-ID: tom@honermann.net Received: by smtp2.relay.iad3b.emailsrvr.com (Authenticated sender: tom-AT-honermann.net) with ESMTPSA id 632AF2009B; Sun, 15 Sep 2019 22:33:53 -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 22:33:53 -0400 Subject: Re: [PATCH 2/4]: C++ P1423R3 char8_t remediation: Update feature test macro, add deleted operators, update u8path From: Tom Honermann To: "libstdc++@gcc.gnu.org" , gcc-patches References: <05f9b7ab-b89a-4348-e758-e7ef9077261a@honermann.net> Message-ID: Date: Mon, 16 Sep 2019 02:33:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.8.0 MIME-Version: 1.0 In-Reply-To: <05f9b7ab-b89a-4348-e758-e7ef9077261a@honermann.net> Content-Type: multipart/mixed; boundary="------------D1550818F7C1025DFDA150A2" X-IsSubscribed: yes X-SW-Source: 2019-09/txt/msg00921.txt.bz2 This is a multi-part message in MIME format. --------------D1550818F7C1025DFDA150A2 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-length: 1558 A revised patch is attached that adds proper preprocessor conditionals around the deleted ostream inserters. Apparently I had previously implemented a quick hack for testing purposes, neglected to add a FIXME comment, and then forgot about the hack. Shame on me. Tom. On 9/15/19 3:39 PM, Tom Honermann wrote: > 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. --------------D1550818F7C1025DFDA150A2 Content-Type: text/x-patch; name="p1423r3-2-2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="p1423r3-2-2.patch" Content-length: 12557 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..771c28db7b7 100644 --- a/libstdc++-v3/include/std/ostream +++ b/libstdc++-v3/include/std/ostream @@ -527,6 +527,47 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline basic_ostream& operator<<(basic_ostream& __out, unsigned char __c) { return (__out << static_cast(__c)); } + +#if __cplusplus > 201703L + // The following deleted overloads prevent formatting character values as + // numeric values. + +#ifdef _GLIBCXX_USE_WCHAR_T + template + basic_ostream& + operator<<(basic_ostream&, wchar_t) = delete; +#endif // _GLIBCXX_USE_WCHAR_T + +#ifdef _GLIBCXX_USE_CHAR8_T + template + basic_ostream& + operator<<(basic_ostream&, char8_t) = delete; +#endif + + template + basic_ostream& + operator<<(basic_ostream&, char16_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char32_t) = delete; + +#ifdef _GLIBCXX_USE_WCHAR_T +#ifdef _GLIBCXX_USE_CHAR8_T + template + basic_ostream& + operator<<(basic_ostream&, char8_t) = delete; +#endif // _GLIBCXX_USE_CHAR8_T + + template + basic_ostream& + operator<<(basic_ostream&, char16_t) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, char32_t) = delete; +#endif // _GLIBCXX_USE_WCHAR_T +#endif // C++20 //@} //@{ @@ -582,6 +623,47 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION inline basic_ostream & operator<<(basic_ostream& __out, const unsigned char* __s) { return (__out << reinterpret_cast(__s)); } + +#if __cplusplus > 201703L + // The following deleted overloads prevent formatting strings as + // pointer values. + +#ifdef _GLIBCXX_USE_WCHAR_T + template + basic_ostream& + operator<<(basic_ostream&, const wchar_t*) = delete; +#endif // _GLIBCXX_USE_WCHAR_T + +#ifdef _GLIBCXX_USE_CHAR8_T + template + basic_ostream& + operator<<(basic_ostream&, const char8_t*) = delete; +#endif // _GLIBCXX_USE_CHAR8_T + + template + basic_ostream& + operator<<(basic_ostream&, const char16_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char32_t*) = delete; + +#ifdef _GLIBCXX_USE_WCHAR_T +#ifdef _GLIBCXX_USE_CHAR8_T + template + basic_ostream& + operator<<(basic_ostream&, const char8_t*) = delete; +#endif + + template + basic_ostream& + operator<<(basic_ostream&, const char16_t*) = delete; + + template + basic_ostream& + operator<<(basic_ostream&, const char32_t*) = delete; +#endif // _GLIBCXX_USE_WCHAR_T +#endif // C++20 //@} // Standard basic_ostream manipulators --------------D1550818F7C1025DFDA150A2--