This uses variable templates and constraints to define a much simpler
std::destructible concept. This avoids instantiating the trait
std::is_nothrow_destructible and all its implementation in terms of
__is_destructible_safe and __is_destructible_impl.
If we had an intrinsic we could just use that (PR c++/107600).
libstdc++-v3/ChangeLog:
* include/std/concepts (__detail::__destructible_impl)
(__detail::__destructible): New variable templates.
(destructible): Use __detail::__destructible.
* testsuite/std/concepts/concepts.lang/concept.destructible/1.cc:
Add more checks for array and reference types.
Fix some problems noticed with -Wsystem-headers.
libstdc++-v3/ChangeLog:
* include/bits/stl_tempbuf.h (_Temporary_buffer): Disable
warnings about get_temporary_buffer being deprecated.
* include/ext/functional (mem_fun1, mem_fun1_ref): Disable
warnings about mem_fun1_t, const_mem_fun1_t, mem_fun1_ref_t and
const_mem_fun1_ref_t being deprecated.
* include/std/array (__array_traits<T, 0>): Remove artificial
attributes which give warnings about being ignored.
* include/std/spanstream (basic_spanbuf::setbuf): Add assertion
and adjust to avoid narrowing warning.
* libsupc++/exception_ptr.h [!__cpp_rtti && !__cpp_exceptions]
(make_exception_ptr): Add missing inline specifier.
This reduces the abstraction penalty for allocator support in
unoptimized code. Constructing and using allocators in containers calls
many one-line (or completely empty) inline functions. Those can all be
inlined to reduce code size and function call overhead for -O0.
libstdc++-v3/ChangeLog:
* include/bits/alloc_traits.h (allocator_traits): Add
always_inline attribute to all member functions.
(__do_alloc_on_copy, __alloc_on_copy, __do_alloc_on_move)
(__alloc_on_move, __do_alloc_on_swap, __alloc_on_swap)
(_Destroy(FwdIter, FwdIter, allocator<T>&)): : Add
always_inline attribute.
* include/bits/allocator.h (allocator): Add always_inline
attribute to all member functions and equality operators.
* include/bits/new_allocator.h (__new_allocator): Likewise.
* include/ext/alloc_traits.h (__gnu_cxx::__alloc_traits):
Likewise.
`basic_filebuf::xsputn` would bypass the buffer when passed a chunk of
size 1024 and above, seemingly as an optimisation.
This can have a significant performance impact if the overhead of a
`write` syscall is non-negligible, e.g. on a slow disk, on network
filesystems, or simply during IO contention because instead of flushing
every `BUFSIZ` (by default), we can flush every 1024 char.
The impact is even greater with custom larger buffers, e.g. for network
filesystems, because the code could issue `write` for example 1000X more
often than necessary with respect to the buffer size.
It also introduces a significant discontinuity in performance when
writing chunks of size 1024 and above.
Instead, it makes sense to only bypass the buffer if the amount of data
to be written is larger than the buffer capacity.
Signed-off-by: Charles-Francois Natali <cf.natali@gmail.com>
libstdc++-v3/ChangeLog:
PR libstdc++/63746
* include/bits/fstream.tcc (basic_filbuf::xsputn): Remove
1024-byte chunking that bypasses the buffer for large writes.
* testsuite/27_io/basic_filebuf/sputn/char/63746.cc: New test.
Until now operator+(char*, string) and operator+(string, char*) had
different performance characteristics. The former required a single
memory allocation and the latter required two. This patch makes the
performance equal.
After consultation with Jonathan, it seemed like a good idea to create a
single function that performed one-allocation string concatenation that
could be used by various different version of operator+. This patch adds
such a function and calls it from the relevant implementations.
Co-authored-by: Jonathan Wakely <jwakely@redhat.com>
libstdc++-v3/ChangeLog:
* include/bits/basic_string.h (__str_cat): Add common function
that performs single-allocation string concatenation.
(operator+): Use __str_cat.
* include/bits/basic_string.tcc (operator+): Move to .h and
define inline using __str_cat.
Signed-off-by: Will Hawkins <whh8b@obs.cr>
As r13-3609-g6d9dbdf51f9afe8 has been committed, we can now enable
even the denorm_min test.
2022-11-08 Jakub Jelinek <jakub@redhat.com>
* testsuite/20_util/to_chars/float128_c++23.cc (test): Uncomment
denorm_min test.
This fixes a spurious comma before the list of authors in the PDF
version of the libstdc++ manual.
Also fix the commented-out examples which should show <personblurb> not
<authorblurb>.
libstdc++-v3/ChangeLog:
* doc/xml/authors.xml: Remove empty author element.
* doc/xml/manual/spine.xml: Likewise.
* doc/html/manual/index.html: Regenerate.
This paper is resolving the problem of well-formed C++17 code becoming
ambiguous in C++20 due to asymmetrical operator== being compared with itself
in reverse. I had previously implemented a tiebreaker such that if the two
candidates were functions with the same parameter types, we would prefer the
non-reversed candidate. But the committee went with a different approach:
if there's an operator!= with the same parameter types as the operator==,
don't consider the reversed form of the ==.
So this patch implements that, and changes my old tiebreaker to give a
pedwarn if it is used. I also noticed that we were giving duplicate errors
for some testcases, and fixed the tourney logic to avoid that.
As a result, a lot of tests of the form
struct A { bool operator==(const A&); };
need to be fixed to add a const function-cv-qualifier, e.g.
struct A { bool operator==(const A&) const; };
The committee thought such code ought to be fixed, so breaking it was fine.
18_support/comparisons/algorithms/fallback.cc also breaks with this patch,
because of the similarly asymmetrical
bool operator==(const S&, S&) { return true; }
As a result, some of the asserts need to be reversed.
The H test in spaceship-eq15.C is specified in the standard to be
well-formed because the op!= in the inline namespace is not found by the
search, but that seems wrong to me. I've implemented that behavior, but
disabled it for now; if we decide that is the way we want to go, we can just
remove the "0 &&" in add_candidates to enable it.
Co-authored-by: Jakub Jelinek <jakub@redhat.com>
gcc/cp/ChangeLog:
* cp-tree.h (fns_correspond): Declare.
* decl.cc (fns_correspond): New.
* call.cc (add_candidates): Look for op!= matching op==.
(joust): Complain about non-standard reversed tiebreaker.
(tourney): Fix champ_compared_to_predecessor logic.
(build_new_op): Don't complain about error_mark_node not having
'bool' type.
* pt.cc (tsubst_copy_and_build): Don't try to be permissive
when seen_error().
gcc/testsuite/ChangeLog:
* g++.dg/cpp2a/spaceship-eq15.C: New test.
* g++.dg/cpp0x/defaulted3.C: Add const.
* g++.dg/cpp2a/bit-cast7.C: Add const.
* g++.dg/cpp2a/spaceship-rewrite1.C: Expect error.
* g++.dg/cpp2a/spaceship-rewrite5.C: Expect error.
* g++.old-deja/g++.jason/byval2.C: Expect error.
* g++.old-deja/g++.other/overload13.C: Add const.
libstdc++-v3/ChangeLog:
* testsuite/18_support/comparisons/algorithms/fallback.cc: Adjust
asserts.
On Mon, Nov 07, 2022 at 05:48:42PM +0000, Jonathan Wakely wrote:
> On Mon, 7 Nov 2022 at 16:11, Joseph Myers <joseph@codesourcery.com> wrote:
> >
> > On Wed, 2 Nov 2022, Jakub Jelinek via Gcc-patches wrote:
> >
> > > APIs. So that one can build gcc against older glibc and then compile
> > > user programs on newer glibc, the patch uses weak references unless
> > > gcc is compiled against glibc 2.26+. strfromf128 unfortunately can't
> >
> > This support for older glibc doesn't actually seem to be working, on an
> > older system with glibc 2.19 I'm seeing
> >
> > /scratch/jmyers/fsf/gcc-mainline/libstdc++-v3/src/c++17/floating_to_chars.cc:52:3: error: expected initializer before '__asm'
> > 52 | __asm ("strfromf128");
> > | ^~~~~
> >
> > and a series of subsequent errors.
>
> This seems to "fix" it (not sure if it's right though):
>
> #ifndef _GLIBCXX_HAVE_FLOAT128_MATH
> extern "C" _Float128 __strtof128(const char*, char**)
> __attribute__((__weak__));
> #endif
> extern "C" _Float128 __strtof128(const char*, char**)
> __asm ("strtof128");
It is, but floating_from_chars.cc has the same problem,
and I think we can avoid the duplication, like this:
2022-11-08 Jakub Jelinek <jakub@redhat.com>
PR libstdc++/107562
* src/c++17/floating_from_chars.cc (__strtof128): Put __asm before
__attribute__.
* src/c++17/floating_to_chars.cc (__strfromf128): Likewise.
This also implements the proposed resolutions of the tentatively ready
LWG issues 3760, 3761 and 3801 for cartesian_product_view.
I'm not sure how/if we should implement the recommended practice of:
iterator::difference_type should be the smallest signed-integer-like
type that is sufficiently wide to store the product of the maximum
sizes of all underlying ranges if such a type exists
because for e.g.
extern std::vector<int> x, y;
auto v = views::cartesian_product(x, y);
IIUC it'd mean difference_type should be __int128 (on 64-bit systems),
which seems quite wasteful: in practice the size of any cartesian product
probably won't exceed the precision of say ptrdiff_t, and using anything
larger will just incur unnecessary space/time overhead. It's also
probably not worth the complexity to use less precision than ptrdiff_t
(when possible) either. So this patch defines difference_type as
common_type_t<ptrdiff_t, range_difference_t<_First>, range_difference_t<_Vs>...>
which should mean it's least as large as the difference_type of each
underlying range, and at least as large as ptrdiff_t. This patch also
adds assertions to catch any overflow that occurs due to this choice of
difference_type.
libstdc++-v3/ChangeLog:
* include/std/ranges (__maybe_const_t): New alias for
__detail::__maybe_const_t.
(__detail::__cartesian_product_is_random_access): Define.
(__detail::__cartesian_product_common_arg): Define.
(__detail::__cartesian_product_is_bidirectional): Define.
(__detail::__cartesian_product_is_common): Define.
(__detail::__cartesian_product_is_sized): Define.
(__detail::__cartesian_is_sized_sentinel): Define.
(__detail::__cartesian_common_arg_end): Define.
(cartesian_product_view): Define.
(cartesian_product_view::_Iterator): Define.
(views::__detail::__can_cartesian_product_view): Define.
(views::_CartesianProduct, views::cartesian_product): Define.
* testsuite/std/ranges/cartesian_product/1.cc: New test.
The following patch updates from fast_float trunk. That way
it grabs two of the 4 LOCAL_PATCHES, some smaller tweaks, to_extended
cleanups and most importantly fix for the incorrect rounding case,
PR107468 aka https://github.com/fastfloat/fast_float/issues/149
Using std::fegetround showed in benchmarks too slow, so instead of
doing that the patch limits the fast path where it uses floating
point multiplication rather than integral to cases where we can
prove there will be no rounding (the multiplication will be exact, not
just that the two multiplication or division operation arguments are
exactly representable).
2022-11-07 Jakub Jelinek <jakub@redhat.com>
PR libstdc++/107468
* src/c++17/fast_float/MERGE: Adjust for merge from upstream.
* src/c++17/fast_float/LOCAL_PATCHES: Remove commits that were
upstreamed.
* src/c++17/fast_float/README.md: Merge from fast_float
662497742fea7055f0e0ee27e5a7ddc382c2c38e commit.
* src/c++17/fast_float/fast_float.h: Likewise.
* testsuite/20_util/from_chars/pr107468.cc: New test.
The following patch adds std::{to,from}_chars support for std::float128_t
on glibc 2.26+ for {i?86,x86_64,ia64,powerpc64le}-linux.
When long double is already IEEE quad, previous changes already handle
it by using long double overloads in _Float128 overloads.
The powerpc64le case (with explicit or implicit -mabi=ibmlongdouble)
is handled by using the __float128/__ieee128 entrypoints which are
already in the library and used for -mabi=ieeelongdouble.
For i?86, x86_64 and ia64 this patch adds new library entrypoints,
mostly by enabling the code that was already there for powerpc64le-linux.
Those use __float128 or __ieee128, the patch uses _Float128 for the
exported overloads and internally as template parameter. While
powerpc64le-linux uses __sprintfieee128 and __strtoieee128,
for _Float128 the patch uses the glibc 2.26 strfromf128 and strtof128
APIs. So that one can build gcc against older glibc and then compile
user programs on newer glibc, the patch uses weak references unless
gcc is compiled against glibc 2.26+. strfromf128 unfortunately can't
handle %.0Lf and %.*Le, %.*Lf, %.*Lg format strings sprintf/__sprintfieee128
use, we need to remove the L from those and replace * with actually
directly printing the precision into the format string (i.e. it can
handle %.0f and %.27f (floating point type is implied from the function
name)).
Unlike the std::{,b}float16_t support, this one actually exports APIs
with std::float128_t aka _Float128 in the mangled name, because no
standard format is superset of it. On the other side, e.g. on i?86/x86_64
it doesn't have restrictions like for _Float16/__bf16 which ISAs need
to be enabled in order to use it.
The denorm_min case in the testcase is temporarily commented out because
of the ERANGE subnormal issue Patrick posted patch for.
2022-11-07 Jakub Jelinek <jakub@redhat.com>
* include/std/charconv (from_chars, to_chars): Add _Float128
overfloads if _GLIBCXX_HAVE_FLOAT128_MATH is defined.
* config/abi/pre/gnu.ver (GLIBCXX_3.4.31): Export
_ZSt8to_charsPcS_DF128_, _ZSt8to_charsPcS_DF128_St12chars_format,
_ZSt8to_charsPcS_DF128_St12chars_formati and
_ZSt10from_charsPKcS0_RDF128_St12chars_format.
* src/c++17/floating_from_chars.cc (USE_STRTOF128_FOR_FROM_CHARS):
Define if needed.
(__strtof128): Declare.
(from_chars_impl): Handle _Float128.
(from_chars): New _Float128 overload if USE_STRTOF128_FOR_FROM_CHARS
is define.
* src/c++17/floating_to_chars.cc (__strfromf128): Declare.
(FLOAT128_TO_CHARS): Define even when _Float128 is supported and
wider than long double.
(F128_type): Use _Float128 for that case.
(floating_type_traits): Specialize for F128_type rather than
__float128.
(sprintf_ld): Add length argument. Handle _Float128.
(__floating_to_chars_shortest, __floating_to_chars_precision):
Pass length to sprintf_ld.
(to_chars): Add _Float128 overloads for the F128_type being
_Float128 cases.
* testsuite/20_util/to_chars/float128_c++23.cc: New test.
The changes inside the regex_constants and execution namespaces seem to
be (the only) unimplemented parts of P0607R0 "Inline Variable for the
Standard Library"; the rest of the changes are to implementation details.
libstdc++-v3/ChangeLog:
* include/bits/atomic_wait.h (_detail::__platform_wait_alignment):
Declare inline. Remove redundant static specifier.
(__detail::__atomic_spin_count_relax): Declare inline.
(__detail::__atomic_spin_count): Likewise.
* include/bits/regex_automaton.h (__detail::_S_invalid_state_id):
Declare inline for C++17. Declare constexpr. Remove
redundant const and static specifiers.
* include/bits/regex_error.h (regex_constants::error_collate):
Declare inline for C++17 as per P0607R0.
(regex_constants::error_ctype): Likewise.
(regex_constants::error_escape): Likewise.
(regex_constants::error_backref): Likewise.
(regex_constants::error_brack): Likewise.
(regex_constants::error_paren): Likewise.
(regex_constants::error_brace): Likewise.
(regex_constants::error_badbrace): Likewise.
(regex_constants::error_range): Likewise.
(regex_constants::error_space): Likewise.
(regex_constants::error_badrepeat): Likewise.
(regex_constants::error_complexity): Likewise.
(regex_constants::error_stack): Likewise.
* include/ext/concurrence.h (__gnu_cxx::__default_lock_policy):
Likewise. Remove redundant static specifier.
* include/pstl/execution_defs.h (execution::seq): Declare inline
for C++17 as per P0607R0.
(execution::par): Likewise.
(execution::par_unseq): Likewise.
(execution::unseq): Likewise.
This patch moves the static object for constructing the standard streams
out from <iostream> and into the compiled library on systems that support
init priorities. This'll mean <iostream> no longer introduces a separate
global constructor in each TU that includes it.
We can do this only if the init_priority attribute is supported because
we need a way to ensure the stream initialization runs first before any
user global initializer, particularly when linking with a static
libstdc++.a.
PR libstdc++/44952
PR libstdc++/39796
PR libstdc++/98108
libstdc++-v3/ChangeLog:
* include/std/iostream (__ioinit): No longer define here if
the init_priority attribute is usable.
* src/c++98/ios_init.cc (__ioinit): Define here instead if
init_priority is usable, via ...
* src/c++98/ios_base_init.h: ... this new file.
__pbase_type_info::__do_catch(), used to catch pointer type exceptions,
did not check if the type info object to compare against is a pointer
type info object before doing a static down-cast to a pointer type info
object. If RTTI is disabled, this leads to the following situation:
Since a pointer type info object has additional fields, they would
end up being undefined if the actual type info object was not a pointer
type info object.
A simple check has been added before the down-cast happens.
Note that a consequence of this check is that exceptions of type
pointer-to-member cannot be caught anymore.
In case RTTI is enabled, this does not seem to be a problem because
RTTI-based checks would run before and prevent running into the bad
down-cast. Hence, the fix is disabled if RTTI is enabled and exceptions
of type pointer-to-member can still be caught.
libstdc++-v3/ChangeLog:
PR libstdc++/105387
* libsupc++/pbase_type_info.cc (__do_catch) [!__cpp_rtti]: Add
check that the thrown type is actually a pointer.
* testsuite/18_support/105387.cc: New test.
* testsuite/18_support/105387_memptr.cc: New test.
Signed-off-by: Jakob Hasse <jakob.hasse@espressif.com>
As the PR notes, the current conversion operators are defined as
function templates so that we can use SFINAE. But this changes how they
are considered for overload resolution. This moves those operators into
base classes that can be specialized so the operators are obsent unless
the constraints are satisfied.
libstdc++-v3/ChangeLog:
PR libstdc++/107525
* include/experimental/propagate_const (operator element_type*()):
Move into base class that can be partially specilized to iompose
constraints.
(operator const element_type*()): Likewise.
* testsuite/experimental/propagate_const/observers/107525.cc: New test.
Since this is a trivial type, we probably don't need to do anything to
ensure it's still accessible after other static dtors.
libstdc++-v3/ChangeLog:
PR libstdc++/107500
* libsupc++/eh_globals.cc (eh_globals): Remove immortalizing
wrapper.
(__cxxabiv1::__cxa_get_globals_fast): Adjust.
(__cxxabiv1::__cxa_get_globals): Adjust.
As in r12-6867-ge20486d508afdf we need to define _GNU_SOURCE explicitly
for Cygwin, because configure finds it in libc but it isn't declared
unless we request it.
libstdc++-v3/ChangeLog:
PR libstdc++/107511
* libsupc++/eh_alloc.cc (_GNU_SOURCE): Define.
This is needed to support a move-only output iterator when the input
iterators are specializations of __normal_iterator.
libstdc++-v3/ChangeLog:
* include/bits/ranges_algobase.h (__detail::__copy_or_move):
Move output iterator.
* testsuite/25_algorithms/copy/constrained.cc: Check copying to
move-only output iterator.
We don't need these 'unused' members because they're never used, and a
union with a single variant member is fine.
libstdc++-v3/ChangeLog:
* libsupc++/eh_globals.cc (constant_init::unused): Remove.
* src/c++11/system_error.cc (constant_init::unused): Remove.
* src/c++17/memory_resource.cc (constant_init::unused): Remove.
The fallback implementation of floating-point std::from_chars (used for
formats other than binary32/64) just calls the C library's strtod family
of functions. In case of overflow, the behavior of these functions is
rigidly specified:
If the correct value overflows and default rounding is in effect, plus
or minus HUGE_VAL, HUGE_VALF, or HUGE_VALL is returned (according to
the return type and sign of the value), and the value of the macro
ERANGE is stored in errno.
But in case of underflow, implementations are given more leeway:
If the result underflows the functions return a value whose magnitude
is no greater than the smallest normalized positive number in the
return type; whether errno acquires the value ERANGE is
implementation-defined.
Thus the fallback implementation can (and does) portably detect overflow,
but it can't portably detect underflow. However, glibc (and presumably
other high-quality C library implementations) will reliably set errno to
ERANGE in case of underflow as well, and it'll also return the nearest
denormal number to the correct value (zero in case of true underflow),
which allows callers to succesfully parse denormal numbers.
So since we can't be perfect here, this patch takes the best effort
approach of assuming a high quality C library implementation with
respect to this underflow behavior, and refines our implementation
to try to distiguish between a denormal result and true underflow
by inspecting strtod's return value.
libstdc++-v3/ChangeLog:
* src/c++17/floating_from_chars.cc (from_chars_impl): In the
ERANGE case, distinguish between a denormal result and true
underflow by checking if the return value is 0.
Hui Xie pointed out that we don't need a dummy member in the union,
because all constructors always initialize either _M_val or _M_unex.
We still need the _M_void member of the expected<void, E>
specialization, because the constructor has to initialize something when
not using the _M_unex member.
libstdc++-v3/ChangeLog:
* include/std/expected (expected::_M_invalid): Remove.
The warning is wrong here, the qualifier serves a purpose and is not
ignored (c.f. PR c++/107492).
libstdc++-v3/ChangeLog:
* include/std/variant (__variant::_Multi_array::__untag_result):
Use pragma to suppress warning.
Jon pointed out that we have TODO: _Bfloat16 in <compare>.
Right now _S_fp_fmt() returns _Binary16 for _Float16, __fp16 as well
as __bf16 and it actually works because we don't have a special handling
of _Binary16. So, either we could just document that, but I'm a little bit
afraid if HPPA or MIPS don't start supporting _Float16 and/or __bf16.
If they do, we have the
#if defined __hppa__ || (defined __mips__ && !defined __mips_nan2008)
// IEEE 754-1985 allowed the meaning of the quiet/signaling
// bit to be reversed. Flip that to give desired ordering.
if (__builtin_isnan(__x) && __builtin_isnan(__y))
{
using _Int = decltype(__ix);
constexpr int __nantype = __fmt == _Binary32 ? 22
: __fmt == _Binary64 ? 51
: __fmt == _Binary128 ? 111
: -1;
constexpr _Int __bit = _Int(1) << __nantype;
__ix ^= __bit;
__iy ^= __bit;
}
#endif
code, the only one where we actually care whether something is
_Binary{32,64,128} (elsewhere we just care about the x86 and m68k 80bits
or double double or just floating point type's sizeof) and we'd need
to handle there _Binary16 and/or _Bfloat16.
So this patch uses different enum for it even when it isn't needed right
now, after all _Binary16 isn't needed either and we could just use
_Binary32...
2022-11-02 Jakub Jelinek <jakub@redhat.com>
* libsupc++/compare (_Strong_order::_Fp_fmt): Add _Bfloat16.
(_Strong_order::_Bfloat16): New static data member.
(_Strong_order::_S_fp_fmt): Return _Bfloat16 for std::bfloat16_t.
On Fri, Oct 28, 2022 at 12:52:44PM -0400, Patrick Palka wrote:
> > The following patch on top of
> > https://gcc.gnu.org/pipermail/libstdc++/2022-October/054849.html
> > adds std::{,b}float16_t support for std::to_chars.
> > When precision is specified (or for std::bfloat16_t for hex mode even if not),
> > I believe we can just use the std::to_chars float (when float is mode
> > compatible with std::float32_t) overloads, both formats are proper subsets
> > of std::float32_t.
> > Unfortunately when precision is not specified and we are supposed to emit
> > shortest string, the std::{,b}float16_t strings are usually much shorter.
> > E.g. 1.e7p-14f16 shortest fixed representation is
> > 0.0001161 and shortest scientific representation is
> > 1.161e-04 while 1.e7p-14f32 (same number promoted to std::float32_t)
> > 0.00011610985 and
> > 1.1610985e-04.
> > Similarly for 1.38p-112bf16,
> > 0.000000000000000000000000000000000235
> > 2.35e-34 vs. 1.38p-112f32
> > 0.00000000000000000000000000000000023472271
> > 2.3472271e-34
> > For std::float16_t there are differences even in the shortest hex, say:
> > 0.01p-14 vs. 1p-22
> > but only for denormal std::float16_t values (where all std::float16_t
> > denormals converted to std::float32_t are normal), __FLT16_MIN__ and
> > everything larger in absolute value than that is the same. Unless
> > that is a bug and we should try to discover shorter representations
> > even for denormals...
>
> IIRC for hex formatting of denormals I opted to be consistent with how
> glibc printf formats them, instead of outputting the truly shortest
> form.
>
> I wouldn't be against using the float32 overloads even for shortest hex
> formatting of float16. The output is shorter but equivalent so it
> shouldn't cause any problems.
The following patch changes the behavior of the shortest hex denormals,
such that they are printed like normals (so for has_implicit_leading_bit
with 1p-149 instead of 0.000002p-126 etc., otherwise (Intel extended)
with the leading digit before dot being [89abcdef]). I think for all the
supported format it is never longer, it can be equal length e.g. for
0.fffffep-126 vs. 1.fffffcp-127 but fortunately no largest subnormal
in any format has the unbiased exponent like -9, -99, -999, -9999 because
then it would be longer and often it is shorter, sometimes much shorter.
For the cases with precision it keeps the handling as is.
While for !has_implicit_leading_bit we for normals or with this patch
even denormals have really shortest representation, for other formats
we sometimes do not, but this patch doesn't deal with that (we
always use 1.NNN while we could use 1.NNN up to f.NNN and by that shortening
by the last hexit if the last hexit doesn't have least significant bit set
and unbiased exponent is not -9, -99, -999 or -9999.
2022-11-02 Jakub Jelinek <jakub@redhat.com>
* src/c++17/floating_to_chars.cc (__floating_to_chars_hex): Drop const
from unbiased_exponent. Canonicalize denormals such that they have
the leading bit set by shifting effective mantissa up and decreasing
unbiased_exponent.
(__floating_to_chars_shortest): Don't instantiate
__floating_to_chars_hex for float16_t either and use float instead.
* testsuite/20_util/to_chars/float.cc (float_to_chars_test_cases):
Adjust testcases for shortest hex denormals.
* testsuite/20_util/to_chars/double.cc (double_to_chars_test_cases):
Likewise.
The following patch adds std::from_chars support, similarly to the
previous std::to_chars patch through APIs that use float instead of
the 16-bit floating point formats as container.
The patch uses the fast_float library and doesn't need any changes
to it, like the previous patch it introduces wrapper classes around
float that represent the float holding float16_t or bfloat16_t value,
and specializes binary_format etc. from fast_float for these classes.
The new test verifies exhaustively to_chars and from_chars afterward
results in the original value (except for nans) in all the fmt cases.
2022-11-01 Jakub Jelinek <jakub@redhat.com>
* include/std/charconv (__from_chars_float16_t,
__from_chars_bfloat16_t): Declare.
(from_chars): Add _Float16 and __gnu_cxx::__bfloat16_t overloads.
* config/abi/pre/gnu.ver (GLIBCXX_3.4.31): Export
_ZSt22__from_chars_float16_tPKcS0_RfSt12chars_format and
_ZSt23__from_chars_bfloat16_tPKcS0_RfSt12chars_format.
* src/c++17/floating_from_chars.cc
(fast_float::floating_type_float16_t,
fast_float::floating_type_bfloat16_t): New classes.
(fast_float::binary_format<floating_type_float16_t>,
fast_float::binary_format<floating_type_bfloat16_t>): New
specializations.
(fast_float::to_float<floating_type_float16_t>,
fast_float::to_float<floating_type_bfloat16_t>,
fast_float::to_extended<floating_type_float16_t>,
fast_float::to_extended<floating_type_bfloat16_t>): Likewise.
(fast_float::from_chars_16): New template function.
(__floating_from_chars_hex): Allow instantiation with
fast_float::floating_type_{,b}float16_t.
(from_chars): Formatting fixes for float/double/long double overloads.
(__from_chars_float16_t, __from_chars_bfloat16_t): New functions.
* testsuite/20_util/to_chars/float16_c++23.cc: New test.
The following patch on top of
https://gcc.gnu.org/pipermail/libstdc++/2022-October/054849.html
adds std::{,b}float16_t support for std::to_chars.
When precision is specified (or for std::bfloat16_t for hex mode even if not),
I believe we can just use the std::to_chars float (when float is mode
compatible with std::float32_t) overloads, both formats are proper subsets
of std::float32_t.
Unfortunately when precision is not specified and we are supposed to emit
shortest string, the std::{,b}float16_t strings are usually much shorter.
E.g. 1.e7p-14f16 shortest fixed representation is
0.0001161 and shortest scientific representation is
1.161e-04 while 1.e7p-14f32 (same number promoted to std::float32_t)
0.00011610985 and
1.1610985e-04.
Similarly for 1.38p-112bf16,
0.000000000000000000000000000000000235
2.35e-34 vs. 1.38p-112f32
0.00000000000000000000000000000000023472271
2.3472271e-34
For std::float16_t there are differences even in the shortest hex, say:
0.01p-14 vs. 1p-22
but only for denormal std::float16_t values (where all std::float16_t
denormals converted to std::float32_t are normal), __FLT16_MIN__ and
everything larger in absolute value than that is the same. Unless
that is a bug and we should try to discover shorter representations
even for denormals...
std::bfloat16_t has the same exponent range as std::float32_t, so all
std::bfloat16_t denormals are also std::float32_t denormals and thus
the shortest hex representations are the same.
As documented, ryu can handle arbitrary IEEE like floating point formats
(probably not wider than IEEE quad) using the generic_128 handling, but
ryu is hidden in libstdc++.so. As only few architectures support
std::float16_t right now and some of them have special ISA requirements
for those (e.g. on i?86 one needs -msse2) and std::bfloat16_t is right
now supported only on x86 (again with -msse2), perhaps with aarch64/arm
coming next if ARM is interested, but I think it is possible that more
will be added later, instead of exporting APIs from the library to handle
directly the std::{,b}float16_t overloads this patch instead exports
functions which take a float which is a superset of those and expects
the inline overloads to promote the 16-bit formats to 32-bit, then inside
of the library it ensures they are printed right.
With the added [[gnu::cold]] attribute because I think most users
will primarily use these formats as storage formats and perform arithmetics
in the excess precision for them and print also as std::float32_t the
added support doesn't seem to be too large, on x86_64:
readelf -Ws libstdc++.so.6.0.31 | grep float16_t
912: 00000000000ae824 950 FUNC GLOBAL DEFAULT 13 _ZSt21__to_chars_bfloat16_tPcS_fSt12chars_format@@GLIBCXX_3.4.31
5767: 00000000000ae4a1 899 FUNC GLOBAL DEFAULT 13 _ZSt20__to_chars_float16_tPcS_fSt12chars_format@@GLIBCXX_3.4.31
842: 000000000016d430 106 FUNC LOCAL DEFAULT 13 _ZN12_GLOBAL__N_113get_ieee_reprINS_23floating_type_float16_tEEENS_6ieee_tIT_EES3_
865: 0000000000170980 1613 FUNC LOCAL DEFAULT 13
+_ZSt23__floating_to_chars_hexIN12_GLOBAL__N_123floating_type_float16_tEESt15to_chars_resultPcS3_T_St8optionalIiE.constprop.0.isra.0
7205: 00000000000ae824 950 FUNC GLOBAL DEFAULT 13 _ZSt21__to_chars_bfloat16_tPcS_fSt12chars_format
7985: 00000000000ae4a1 899 FUNC GLOBAL DEFAULT 13 _ZSt20__to_chars_float16_tPcS_fSt12chars_format
so 3568 code bytes together or so.
Tested with the attached test (which doesn't prove the shortest
representation, just prints std::{,b}float16_t and std::float32_t
shortest strings side by side, then tries to verify it can be
emitted even into the exact sized range and can't be into range
one smaller than that and tries to read what is printed
back using from_chars float32_t overload (so there could be
double rounding, but apparently there is none for the shortest strings).
The only differences printed are for NaNs, where sNaNs are canonicalized
to canonical qNaNs and as to_chars doesn't print NaN mantissa, even qNaNs
other than the canonical one are read back just as the canonical NaN.
Also attaching what Patrick wrote to generate the pow10_adjustment_tab,
for std::float16_t only 1.0, 10.0, 100.0, 1000.0 and 10000.0 are powers
of 10 in the range because __FLT16_MAX__ is 65504.0, and all of the above
are exactly representable in std::float16_t, so we want to use 0 in
pow10_adjustment_tab.
2022-11-01 Jakub Jelinek <jakub@redhat.com>
* include/std/charconv (__to_chars_float16_t, __to_chars_bfloat16_t):
Declare.
(to_chars): Add _Float16 and __gnu_cxx::__bfloat16_t overloads.
* config/abi/pre/gnu.ver (GLIBCXX_3.4.31): Export
_ZSt20__to_chars_float16_tPcS_fSt12chars_format and
_ZSt21__to_chars_bfloat16_tPcS_fSt12chars_format.
* src/c++17/floating_to_chars.cc (floating_type_float16_t,
floating_type_bfloat16_t): New types.
(floating_type_traits<floating_type_float16_t>,
floating_type_traits<floating_type_bfloat16_t>,
get_ieee_repr<floating_type_float16_t>,
get_ieee_repr<floating_type_bfloat16_t>,
__handle_special_value<floating_type_float16_t>,
__handle_special_value<floating_type_bfloat16_t>): New specializations.
(floating_to_shortest_scientific): Handle floating_type_float16_t
and floating_type_bfloat16_t like IEEE quad.
(__floating_to_chars_shortest): For floating_type_bfloat16_t call
__floating_to_chars_hex<float> rather than
__floating_to_chars_hex<floating_type_bfloat16_t> to avoid
instantiating the latter.
(__to_chars_float16_t, __to_chars_bfloat16_t): New functions.
The following patch adds the easy part of <charconv>, <istream> and
<ostream> changes for extended floats.
In particular, for the first one only overloads where the _Float* has
the same format as float/double/long double and for the latter two
everything but the _GLIBCXX_HAVE_FLOAT128_MATH case.
For charconv, I'm not really familiar with it, I'm pretty sure
we need new libstdc++.so.6 side implementation of from_chars for
{,b}float16_t and for to_chars not really sure but for unspecified precision
if it should emit minimum characters that to_chars then can unambiguously
parse, I think it is less than in the float case. For float128_t
{to,from}_chars I think we even have it on the library side already, just
ifdefed for powerpc64le only.
For i/o stream operator<</>>, not sure what is better, if not providing
anything at all, or doing what we in the end do if user doesn't override
the virtual functions, or use {to,from}_chars under the hood, something
else?
Besides this, the patch adds some further missed
// { dg-options "-std=gnu++2b" }
spots, I've also noticed I got the formatting wrong in some testcases
by not using spaces around VERIFY conditions and elsewhere by having
space before ( for calls.
The testsuite coverage is limited, I've added test for from_chars because
it was easy to port, but not really sure what to do about to_chars, it has
for float/double huge testcases which would be excessive to repeat.
And for i/ostream not really sure what exactly is worth testing.
2022-11-01 Jakub Jelinek <jakub@redhat.com>
* include/std/charconv (from_chars, to_chars): Add _Float{32,64,128}
overloads for cases where those types match {float,double,long double}.
* include/std/istream (basic_istream::operator>>): Add
_Float{16,32,64,128} and __gnu_cxx::__bfloat16_t overloads.
* include/std/ostream (basic_ostream::operator<<): Add
_Float{16,32,64,128} and __gnu_cxx::__bfloat16_t overloads.
* testsuite/20_util/from_chars/8.cc: New test.
* testsuite/26_numerics/headers/cmath/nextafter_c++23.cc (test):
Formatting fixes.
* testsuite/26_numerics/headers/cmath/functions_std_c++23.cc: Add
dg-options "-std=gnu++2b".
(test_functions, main): Formatting fixes.
* testsuite/26_numerics/headers/cmath/c99_classification_macros_c++23.cc:
Add dg-options "-std=gnu++2b".
The following patch adds <complex> support for extended floating point
types.
C++23 removes the float/double/long double specializations from the spec
and instead adds explicit(bool) specifier on the converting constructor.
The patch uses that for converting constructor of the base template as well
as the float/double/long double specializations's converting constructors
(e.g. so that it handles convertion construction also from complex of extended
floating point types). Copy ctor was already defaulted as the spec now
requires.
The patch also adds partial specialization for the _Float{16,32,64,128}
and __gnu_cxx::__bfloat16_t types because the base template doesn't use
__complex__ but a pair of floating point values.
The g++.dg/cpp23/ testcase verifies explicit(bool) works correctly.
2022-10-31 Jakub Jelinek <jakub@redhat.com>
gcc/testsuite/
* g++.dg/cpp23/ext-floating12.C: New test.
libstdc++-v3/
* include/std/complex (complex::complex converting ctor): For C++23
use explicit specifier with constant expression. Explicitly cast
both parts to _Tp.
(__complex_abs, __complex_arg, __complex_cos, __complex_cosh,
__complex_exp, __complex_log, __complex_sin, __complex_sinh,
__complex_sqrt, __complex_tan, __complex_tanh, __complex_pow): Add
__complex__ _Float{16,32,64,128} and __complex__ decltype(0.0bf16)
overloads.
(complex<float>::complex converting ctor,
complex<double>::complex converting ctor,
complex<long double>::complex converting ctor): For C++23 implement
as template with explicit specifier with constant expression
and explicit casts.
(__complex_type): New template.
(complex): New partial specialization for types with extended floating
point types.
(__complex_acos, __complex_asin, __complex_atan, __complex_acosh,
__complex_asinh, __complex_atanh): Add __complex__ _Float{16,32,64,128}
and __complex__ decltype(0.0bf16) overloads.
(__complex_proj): Likewise. Add template for complex of extended
floating point types.
* include/bits/cpp_type_traits.h (__is_floating): Specialize for
_Float{16,32,64,128} and __gnu_cxx::__bfloat16_t.
* testsuite/26_numerics/complex/ext_c++23.cc: New test.
The following patch
1) enables the std::float128_t overloads for x86 with glibc 2.26+
2) makes std::nextafter(std::float16_t, std::float16_t) and
std::nextafter(std::bfloat16_t, std::bfloat16_t) constexpr
3) adds (small) testsuite coverage for that
2022-10-21 Jakub Jelinek <jakub@redhat.com>
* config/os/gnu-linux/os_defines.h (_GLIBCXX_HAVE_FLOAT128_MATH):
Uncomment.
* include/c_global/cmath (nextafter(_Float16, _Float16)): Make it constexpr.
If std::__is_constant_evaluated() call __builtin_nextafterf16.
(nextafter(__gnu_cxx::__bfloat16_t, __gnu_cxx::__bfloat16_t)): Similarly
but call __builtin_nextafterf16b.
* testsuite/26_numerics/headers/cmath/nextafter_c++23.cc (test): Add
static assertions to test constexpr nextafter.
This slightly lowers the dependency of generated code on libstdc++.so.
libstdc++-v3/ChangeLog:
* include/std/functional: Make placeholders inline, if possible.
The PR points out that we assume the match_results allocator is default
constuctible, which might not be true. We also have a related issue with
unwanted propagation from an object that might have an unequal
allocator.
Ideally we use the same allocator type for _State_info::_M_match_queue
but that would be an ABI change now. We should investigate if that can
be done without breaking anything, which might be possible because the
_Executor object is short-lived and never leaks out of the regex_match,
regex_search, and regex_replace algorithms. If we change the mangled
name for _Executor then there would be no ODR violations when mixing old
and new definitions. This commit does not attempt that.
libstdc++-v3/ChangeLog:
PR libstdc++/107376
* include/bits/regex_executor.h (_Executor::_Executor): Use same
allocator for _M_cur_results and _M_results.
* include/bits/regex_executor.tcc (_Executor::_M_main_dispatch):
Prevent possibly incorrect allocator propagating to
_M_cur_results.
* testsuite/28_regex/algorithms/regex_match/107376.cc: New test.
This patch implements a new experimental warning (enabled by -Wall) to
detect references bound to temporaries whose lifetime has ended. The
primary motivation is the Note in
<https://en.cppreference.com/w/cpp/algorithm/max>:
Capturing the result of std::max by reference produces a dangling reference
if one of the parameters is a temporary and that parameter is returned:
int n = 1;
const int& r = std::max(n-1, n+1); // r is dangling
That's because both temporaries for n-1 and n+1 are destroyed at the end
of the full expression. With this warning enabled, you'll get:
g.C:3:12: warning: possibly dangling reference to a temporary [-Wdangling-reference]
3 | const int& r = std::max(n-1, n+1);
| ^
g.C:3:24: note: the temporary was destroyed at the end of the full expression 'std::max<int>((n - 1), (n + 1))'
3 | const int& r = std::max(n-1, n+1);
| ~~~~~~~~^~~~~~~~~~
The warning works by checking if a reference is initialized with a function
that returns a reference, and at least one parameter of the function is
a reference that is bound to a temporary. It assumes that such a function
actually returns one of its arguments! (I added code to check_return_expr
to suppress the warning when we've seen the definition of the function
and we can say that it can return a variable with static storage
duration.)
It warns when the function in question is a member function, but only if
the function is invoked on a temporary object, otherwise the warning
would emit loads of warnings for valid code like obj.emplace<T>({0}, 0).
It does detect the dangling reference in:
struct S {
const S& self () { return *this; }
};
const S& s = S().self();
It warns in member initializer lists as well:
const int& f(const int& i) { return i; }
struct S {
const int &r;
S() : r(f(10)) { }
};
I've run the testsuite/bootstrap with the warning enabled by default.
There were just a few FAILs, all of which look like genuine bugs.
A bootstrap with the warning enabled by default passed as well.
When testing a previous version of the patch, there were many FAILs in
libstdc++'s 22_locale/; all of them because the warning triggered on
const test_type& obj = std::use_facet<test_type>(std::locale());
but this code looks valid -- std::use_facet doesn't return a reference
to its parameter. Therefore I added a #pragma and code to suppress the
warning.
PR c++/106393
gcc/c-family/ChangeLog:
* c.opt (Wdangling-reference): New.
gcc/cp/ChangeLog:
* call.cc (expr_represents_temporary_p): New, factored out of...
(conv_binds_ref_to_temporary): ...here. Don't return false just
because a ck_base is missing. Use expr_represents_temporary_p.
(do_warn_dangling_reference): New.
(maybe_warn_dangling_reference): New.
(extend_ref_init_temps): Call maybe_warn_dangling_reference.
* cp-tree.h: Adjust comment.
* typeck.cc (check_return_expr): Suppress -Wdangling-reference
warnings.
gcc/ChangeLog:
* doc/invoke.texi: Document -Wdangling-reference.
libstdc++-v3/ChangeLog:
* include/bits/locale_classes.tcc: Add #pragma to disable
-Wdangling-reference with std::use_facet.
gcc/testsuite/ChangeLog:
* g++.dg/cpp23/elision4.C: Use -Wdangling-reference, add dg-warning.
* g++.dg/cpp23/elision7.C: Likewise.
* g++.dg/warn/Wdangling-pointer-2.C: Use -Wno-dangling-reference.
* g++.dg/warn/Wdangling-reference1.C: New test.
* g++.dg/warn/Wdangling-reference2.C: New test.
* g++.dg/warn/Wdangling-reference3.C: New test.