From: Jonathan Wakely Date: Tue, 10 Sep 2019 09:08:20 +0000 (+0100) Subject: LWG 3266. to_chars(bool) should be deleted X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=28f0075742ed5864991a1b0fef2ad6fae15c5e3b;p=gcc.git LWG 3266. to_chars(bool) should be deleted The standard requires overloads of std::to_chars for char and (un)signed integer types. This means that our constrained function template is non-conforming, because the difference is observable when using types that convert to an integer (e.g. wchar_t, which promotes). As well as defining the deleted bool overload for LWG 3266, replace the constrained function template with overloads for each type. * include/std/charconv (to_chars): Rename to __to_chars_i. Define non-template overloads for each signed and unsigned integer type and char. Define deleted overload for bool (LWG 3266). * testsuite/20_util/to_chars/1_neg.cc: Remove. * testsuite/20_util/to_chars/3.cc: New test. * testsuite/20_util/to_chars/lwg3266.cc: New test. From-SVN: r275588 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index f5d2146cdd0..b7f823e4a82 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,12 @@ +2019-09-10 Jonathan Wakely + + * include/std/charconv (to_chars): Rename to __to_chars_i. Define + non-template overloads for each signed and unsigned integer type and + char. Define deleted overload for bool (LWG 3266). + * testsuite/20_util/to_chars/1_neg.cc: Remove. + * testsuite/20_util/to_chars/3.cc: New test. + * testsuite/20_util/to_chars/lwg3266.cc: New test. + 2019-09-10 Christophe Lyon * acinclude.m4: Handle uclinux*. diff --git a/libstdc++-v3/include/std/charconv b/libstdc++-v3/include/std/charconv index ceefa3b6778..65f183f61f4 100644 --- a/libstdc++-v3/include/std/charconv +++ b/libstdc++-v3/include/std/charconv @@ -305,7 +305,7 @@ namespace __detail template __detail::__integer_to_chars_result_type<_Tp> - to_chars(char* __first, char* __last, _Tp __value, int __base = 10) + __to_chars_i(char* __first, char* __last, _Tp __value, int __base = 10) { __glibcxx_assert(2 <= __base && __base <= 36); @@ -341,6 +341,43 @@ namespace __detail } } +#define _GLIBCXX_TO_CHARS(T) \ + inline to_chars_result \ + to_chars(char* __first, char* __last, T __value, int __base = 10) \ + { return std::__to_chars_i(__first, __last, __value, __base); } +_GLIBCXX_TO_CHARS(char) +_GLIBCXX_TO_CHARS(signed char) +_GLIBCXX_TO_CHARS(unsigned char) +_GLIBCXX_TO_CHARS(signed short) +_GLIBCXX_TO_CHARS(unsigned short) +_GLIBCXX_TO_CHARS(signed int) +_GLIBCXX_TO_CHARS(unsigned int) +_GLIBCXX_TO_CHARS(signed long) +_GLIBCXX_TO_CHARS(unsigned long) +_GLIBCXX_TO_CHARS(signed long long) +_GLIBCXX_TO_CHARS(unsigned long long) +#if defined(__GLIBCXX_TYPE_INT_N_0) +_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_0) +_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_0) +#endif +#if defined(__GLIBCXX_TYPE_INT_N_1) +_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_1) +_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_1) +#endif +#if defined(__GLIBCXX_TYPE_INT_N_2) +_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_2) +_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_2) +#endif +#if defined(__GLIBCXX_TYPE_INT_N_3) +_GLIBCXX_TO_CHARS(signed __GLIBCXX_TYPE_INT_N_3) +_GLIBCXX_TO_CHARS(unsigned __GLIBCXX_TYPE_INT_N_3) +#endif +#undef _GLIBCXX_TO_CHARS + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // 3266. to_chars(bool) should be deleted + to_chars_result to_chars(char*, char*, bool, int = 10) = delete; + namespace __detail { template diff --git a/libstdc++-v3/testsuite/20_util/to_chars/1_neg.cc b/libstdc++-v3/testsuite/20_util/to_chars/1_neg.cc deleted file mode 100644 index d125eda5883..00000000000 --- a/libstdc++-v3/testsuite/20_util/to_chars/1_neg.cc +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2017-2019 Free Software Foundation, Inc. -// -// This file is part of the GNU ISO C++ Library. This library is free -// software; you can redistribute it and/or modify it under the -// terms of the GNU General Public License as published by the -// Free Software Foundation; either version 3, or (at your option) -// any later version. - -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License along -// with this library; see the file COPYING3. If not see -// . - -// { dg-options "-std=gnu++17" } -// { dg-do compile { target c++17 } } - -#include - -void -test01(char* first, char* last) -{ -#if _GLIBCXX_USE_WCHAR_T - std::to_chars(first, last, L'\x1'); // { dg-error "no matching" } - std::to_chars(first, last, L'\x1', 10); // { dg-error "no matching" } -#endif - - std::to_chars(first, last, u'\x1'); // { dg-error "no matching" } - std::to_chars(first, last, u'\x1', 10); // { dg-error "no matching" } - std::to_chars(first, last, U'\x1'); // { dg-error "no matching" } - std::to_chars(first, last, U'\x1', 10); // { dg-error "no matching" } -} - -// { dg-prune-output "enable_if" } diff --git a/libstdc++-v3/testsuite/20_util/to_chars/3.cc b/libstdc++-v3/testsuite/20_util/to_chars/3.cc new file mode 100644 index 00000000000..f8372fd7013 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/to_chars/3.cc @@ -0,0 +1,60 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++17" } +// { dg-do run { target c++17 } } +// { dg-require-string-conversions "" } + +#include +#include +#include + +template +bool +check_to_chars(C val) +{ + using std::string_view; + + char buf1[32], buf2[32], buf3[32]; + std::to_chars_result r1 = std::to_chars(buf1, buf1+sizeof(buf1), val); + if (r1.ec != std::errc{}) + return false; + std::to_chars_result r2 = std::to_chars(buf2, buf2+sizeof(buf2), val, 10); + if (r2.ec != std::errc{}) + return false; + if (string_view(buf1, r1.ptr - buf1) != string_view(buf2, r2.ptr - buf2)) + return false; + std::to_chars_result r3 = std::to_chars(buf3, buf3+sizeof(buf3), (long)val); + if (string_view(buf1, r1.ptr - buf1) != string_view(buf3, r3.ptr - buf3)) + return false; + return true; +} + +void +test01() +{ + VERIFY( check_to_chars(u'\x21') ); + VERIFY( check_to_chars(U'\x21') ); +#if _GLIBCXX_USE_WCHAR_T + VERIFY( check_to_chars(L'\x21') ); +#endif +} + +int main() +{ + test01(); +} diff --git a/libstdc++-v3/testsuite/20_util/to_chars/lwg3266.cc b/libstdc++-v3/testsuite/20_util/to_chars/lwg3266.cc new file mode 100644 index 00000000000..01c2c6ccbee --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/to_chars/lwg3266.cc @@ -0,0 +1,30 @@ +// Copyright (C) 2019 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +// { dg-options "-std=gnu++17" } +// { dg-do compile { target c++17 } } + +#include + +void +test01(char* first, char* last) +{ + // LWG 3266. to_chars(bool) should be deleted + char buf; + std::to_chars(&buf, &buf + 1, true); // { dg-error "deleted function" } + std::to_chars(&buf, &buf + 1, false, 10); // { dg-error "deleted function" } +}