https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108846

--- Comment #32 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jonathan Wakely <r...@gcc.gnu.org>:

https://gcc.gnu.org/g:3abe751ea86e3472fa2c97bf2014f9f93f569019

commit r15-4473-g3abe751ea86e3472fa2c97bf2014f9f93f569019
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Wed Oct 9 12:55:54 2024 +0100

    libstdc++: Refactor std::uninitialized_{copy,fill,fill_n} algos [PR68350]

    This refactors the std::uninitialized_copy, std::uninitialized_fill and
    std::uninitialized_fill_n algorithms to directly perform memcpy/memset
    optimizations instead of dispatching to std::copy/std::fill/std::fill_n.

    The reasons for this are:

    - Use 'if constexpr' to simplify and optimize compilation throughput, so
      dispatching to specialized class templates is only needed for C++98
      mode.
    - Use memcpy instead of memmove, because the conditions on
      non-overlapping ranges are stronger for std::uninitialized_copy than
      for std::copy. Using memcpy might be a minor optimization.
    - No special case for creating a range of one element, which std::copy
      needs to deal with (see PR libstdc++/108846). The uninitialized algos
      create new objects, which reuses storage and is allowed to clobber
      tail padding.
    - Relax the conditions for using memcpy/memset, because the C++20 rules
      on implicit-lifetime types mean that we can rely on memcpy to begin
      lifetimes of trivially copyable types.  We don't need to require
      trivially default constructible, so don't need to limit the
      optimization to trivial types. See PR 68350 for more details.
    - Remove the dependency on std::copy and std::fill. This should mean
      that stl_uninitialized.h no longer needs to include all of
      stl_algobase.h.  This isn't quite true yet, because we still use
      std::fill in __uninitialized_default and still use std::fill_n in
      __uninitialized_default_n. That will be fixed later.

    Several tests need changes to the diagnostics matched by dg-error
    because we no longer use the __constructible() function that had a
    static assert in. Now we just get straightforward errors for attempting
    to use a deleted constructor.

    Two tests needed more signficant changes to the actual expected results
    of executing the tests, because they were checking for old behaviour
    which was incorrect according to the standard.
    20_util/specialized_algorithms/uninitialized_copy/64476.cc was expecting
    std::copy to be used for a call to std::uninitialized_copy involving two
    trivially copyable types. That was incorrect behaviour, because a
    non-trivial constructor should have been used, but using std::copy used
    trivial default initialization followed by assignment.
    20_util/specialized_algorithms/uninitialized_fill_n/sizes.cc was testing
    the behaviour with a non-integral Size passed to uninitialized_fill_n,
    but I wrote the test looking at the requirements of uninitialized_copy_n
    which are not the same as uninitialized_fill_n. The former uses --n and
    tests n > 0, but the latter just tests n-- (which will never be false
    for a floating-point value with a fractional part).

    libstdc++-v3/ChangeLog:

            PR libstdc++/68350
            PR libstdc++/93059
            * include/bits/stl_uninitialized.h (__check_constructible)
            (_GLIBCXX_USE_ASSIGN_FOR_INIT): Remove.
            [C++98] (__unwrappable_niter): New trait.
            (__uninitialized_copy<true>): Replace use of std::copy.
            (uninitialized_copy): Fix Doxygen comments. Open-code memcpy
            optimization for C++11 and later.
            (__uninitialized_fill<true>): Replace use of std::fill.
            (uninitialized_fill): Fix Doxygen comments. Open-code memset
            optimization for C++11 and later.
            (__uninitialized_fill_n<true>): Replace use of std::fill_n.
            (uninitialized_fill_n): Fix Doxygen comments. Open-code memset
            optimization for C++11 and later.
            *
testsuite/20_util/specialized_algorithms/uninitialized_copy/64476.cc:
            Adjust expected behaviour to match what the standard specifies.
            *
testsuite/20_util/specialized_algorithms/uninitialized_fill_n/sizes.cc:
            Likewise.
            * testsuite/20_util/specialized_algorithms/uninitialized_copy/1.cc:
            Adjust dg-error directives.
            *
testsuite/20_util/specialized_algorithms/uninitialized_copy/89164.cc:
            Likewise.
            *
testsuite/20_util/specialized_algorithms/uninitialized_copy_n/89164.cc:
            Likewise.
            *
testsuite/20_util/specialized_algorithms/uninitialized_fill/89164.cc:
            Likewise.
            *
testsuite/20_util/specialized_algorithms/uninitialized_fill_n/89164.cc:
            Likewise.
            * testsuite/23_containers/vector/cons/89164.cc: Likewise.
            * testsuite/23_containers/vector/cons/89164_c++17.cc: Likewise.

    Reviewed-by: Patrick Palka <ppa...@redhat.com>

Reply via email to