This attempts to simplify and clean up our std::hash code. The primary
benefit is improved diagnostics for users when they do something wrong
involving std::hash or unordered containers. An additional benefit is
that for the unstable ABI (--enable-symvers=gnu-versioned-namespace) we
can reduce the memory footprint of several std::hash specializations.
In the current design, __hash_enum is a base class of the std::hash
primary template, but the partial specialization of __hash_enum for
non-enum types is disabled. This means that if a user forgets to
specialize std::hash for their class type (or forgets to use a custom
hash function for unordered containers) they get error messages about
std::__hash_enum not being constructible. This is confusing when there
is no enum type involved: why should users care about __hash_enum not
being constructible if they're not trying to hash enums?
This change makes the std::hash primary template only derive from
__hash_enum when the template argument type is an enum. Otherwise, it
derives directly from a new class template, __hash_not_enabled. This new
class template defines the deleted members that cause a given std::hash
specialization to be a disabled specialization (as per P0513R0). Now
when users try to use a disabled specialization, they get more
descriptive errors that mention __hash_not_enabled instead of
__hash_enum.
Additionally, adjust __hash_base to remove the deprecated result_type
and argument_type typedefs for C++20 and later.
In the current code we use a __poison_hash base class in the std::hash
specializations for std::unique_ptr, std::optional, and std::variant.
The primary template of __poison_hash has deleted special members, which
is used to conditionally disable the derived std::hash specialization.
This can also result in confusing diagnostics, because seeing "poison"
in an enabled specialization is misleading. Only some uses of
__poison_hash actually "poison" anything, i.e. cause a specialization to
be disabled. In other cases it's just an empty base class that does
nothing.
This change removes __poison_hash and changes the std::hash
specializations that were using it to conditionally derive from
__hash_not_enabled instead. When the std::hash specialization is
enabled, there is no more __poison_hash base class. However, to preserve
the ABI properties of those std::hash specializations, we need to
replace __poison_hash with some other empty base class. This is needed
because in the current code std::hash<std::variant<int, const int>> has
two __poison_hash<int> base classes, which must have unique addresses,
so sizeof(std::hash<std::variant<int, const int>>) == 2. To preserve
this unfortunate property, a new __hash_empty_base class is used as a
base class to re-introduce du0plicate base classes that increase the
class size. For the unstable ABI we don't use __hash_empty_base so the
std::hash<std::variant<T...>> specializations are always size 1, and
the class hierarchy is much simpler so will compile faster.
Additionally, remove the result_type and argument_type typedefs from all
disabled specializations of std::hash for std::unique_ptr,
std::optional, and std::variant. Those typedefs are useless for disabled
specializations, and although the standard doesn't say they must *not*
be present for disabled specializations, it certainly only requires them
for enabled specializations. Finally, for C++20 the typedefs are also
removed from enabled specializations of std::hash for std::unique_ptr,
std::optional, and std::variant.
libstdc++-v3/ChangeLog:
* doc/xml/manual/evolution.xml: Document removal of nested types
from std::hash specializations.
* doc/html/manual/api.html: Regenerate.
* include/bits/functional_hash.h (__hash_base): Remove
deprecated nested types for C++20.
(__hash_empty_base): Define new class template.
(__is_hash_enabled_for): Define new variable template.
(__poison_hash): Remove.
(__hash_not_enabled): Define new class template.
(__hash_enum): Remove partial specialization for non-enums.
(hash): Derive from __hash_not_enabled for non-enums, instead of
__hash_enum.
* include/bits/unique_ptr.h (__uniq_ptr_hash): Derive from
__hash_base. Conditionally derive from __hash_empty_base.
(__uniq_ptr_hash<>): Remove disabled specialization.
(hash): Do not derive from __hash_base unconditionally.
Conditionally derive from either __uniq_ptr_hash or
__hash_not_enabled.
* include/std/optional (__optional_hash_call_base): Remove.
(__optional_hash): Define new class template.
(hash): Derive from either
(hash): Conditionally derive from either __optional_hash or
__hash_not_enabled. Remove nested typedefs.
* include/std/variant (_Base_dedup): Replace __poison_hash with
__hash_empty_base.
(__variant_hash_call_base_impl): Remove.
(__variant_hash): Define new class template.
(hash): Conditionally derive from either __variant_hash or
__hash_not_enabled. Remove nested typedefs.
* testsuite/20_util/optional/hash.cc: Check whether nested types
are present.
* testsuite/20_util/variant/hash.cc: Likewise.
* testsuite/20_util/optional/hash_abi.cc: New test.
* testsuite/20_util/unique_ptr/hash/abi.cc: New test.
* testsuite/20_util/unique_ptr/hash/types.cc: New test.
* testsuite/20_util/variant/hash_abi.cc: New test.
These headers make no sense for C++ programs, because they either define
different content to the corresponding <xxx.h> C header, or define
nothing at all in namespace std. They were all deprecated in C++17, so
add deprecation warnings to them, which can be disabled with
-Wno-deprecated. For C++20 and later these headers are no longer in the
standard at all, so compiling with _GLIBCXX_USE_DEPRECATED defined to 0
will give an error when they are included.
Because #warning is non-standard before C++23 we need to use pragmas to
ignore -Wc++23-extensions for the -Wsystem-headers -pedantic case.
One g++ test needs adjustment because it includes <ciso646>, but that
can be made conditional on the __cplusplus value without any reduction
in test coverage.
For the library tests, consolidate the std_c++0x_neg.cc XFAIL tests into
the macros.cc test, using dg-error with a { target c++98_only }
selector. This avoids having two separate test files, one for C++98 and
one for everything later. Also add tests for the <xxx.h> headers to
ensure that they behave as expected and don't give deprecated warnings.
libstdc++-v3/ChangeLog:
* doc/xml/manual/evolution.xml: Document deprecations.
* doc/html/*: Regenerate.
* include/c_compatibility/complex.h (_GLIBCXX_COMPLEX_H): Move
include guard to start of file. Include <complex> directly
instead of <ccomplex>.
* include/c_compatibility/tgmath.h: Include <cmath> and
<complex> directly, instead of <ctgmath>.
* include/c_global/ccomplex: Add deprecated #warning for C++17
and #error for C++20 if _GLIBCXX_USE_DEPRECATED == 0.
* include/c_global/ciso646: Likewise.
* include/c_global/cstdalign: Likewise.
* include/c_global/cstdbool: Likewise.
* include/c_global/ctgmath: Likewise.
* include/c_std/ciso646: Likewise.
* include/precompiled/stdc++.h: Do not include ccomplex,
ciso646, cstdalign, cstdbool, or ctgmath in C++17 and later.
* testsuite/18_support/headers/cstdalign/macros.cc: Check for
warnings and errors for unsupported dialects.
* testsuite/18_support/headers/cstdbool/macros.cc: Likewise.
* testsuite/26_numerics/headers/ctgmath/complex.cc: Likewise.
* testsuite/27_io/objects/char/1.cc: Do not include <ciso646>.
* testsuite/27_io/objects/wchar_t/1.cc: Likewise.
* testsuite/18_support/headers/cstdbool/std_c++0x_neg.cc: Removed.
* testsuite/18_support/headers/cstdalign/std_c++0x_neg.cc: Removed.
* testsuite/26_numerics/headers/ccomplex/std_c++0x_neg.cc: Removed.
* testsuite/26_numerics/headers/ctgmath/std_c++0x_neg.cc: Removed.
* testsuite/18_support/headers/ciso646/macros.cc: New test.
* testsuite/18_support/headers/ciso646/macros.h.cc: New test.
* testsuite/18_support/headers/cstdbool/macros.h.cc: New test.
* testsuite/26_numerics/headers/ccomplex/complex.cc: New test.
* testsuite/26_numerics/headers/ccomplex/complex.h.cc: New test.
* testsuite/26_numerics/headers/ctgmath/complex.h.cc: New test.
gcc/testsuite/ChangeLog:
* g++.old-deja/g++.other/headers1.C: Do not include ciso646 for
C++17 and later.
Also remove some redundant 'void' parameters from code examples.
libstdc++-v3/ChangeLog:
* doc/xml/manual/using_exceptions.xml: Fix typos and grammatical
errors.
* doc/html/manual/using_exceptions.html: Regenerate.
Too many users don't know about -D_GLIBCXX_ASSERTIONS and so are missing
valuable checks for C++ standard library preconditions. This change
enables libstdc++ assertions by default when compiling with -O0 so that
we diagnose more bugs by default.
When users enable optimization we don't add the assertions by default
(because they have non-zero overhead) so they still need to enable them
manually.
For users who really don't want the assertions even in unoptimized
builds, defining _GLIBCXX_NO_ASSERTIONS will prevent them from being
enabled automatically.
libstdc++-v3/ChangeLog:
PR libstdc++/112808
* doc/xml/manual/using.xml (_GLIBCXX_ASSERTIONS): Document
implicit definition for -O0 compilation.
(_GLIBCXX_NO_ASSERTIONS): Document.
* doc/html/manual/using_macros.html: Regenerate.
* include/bits/c++config [!__OPTIMIZE__] (_GLIBCXX_ASSERTIONS):
Define for unoptimized builds.
This simplifies the implementation of std::aligned_storage. For the
unstable ABI it also fixes the bug where its size is too large when the
default alignment is used. We can't fix that for the stable ABI though,
so just add a comment about the bug.
libstdc++-v3/ChangeLog:
PR libstdc++/61458
* doc/doxygen/user.cfg.in (GENERATE_BUGLIST): Set to NO.
* include/std/type_traits (__aligned_storage_msa): Remove.
(__aligned_storage_max_align_t): New struct.
(__aligned_storage_default_alignment): New function.
(aligned_storage): Use __aligned_storage_default_alignment for
default alignment. Replace union with a struct containing an
aligned buffer. Improve Doxygen comment.
(aligned_storage_t): Use __aligned_storage_default_alignment for
default alignment.
There are several features that are not supported when using the old
std::string ABI. It's possible that PR 81967 will get fixed, but the
missing C++20 features almost certainly won't be. Document this in the
manual.
libstdc++-v3/ChangeLog:
PR libstdc++/116777
* doc/xml/manual/using.xml: Document features that are not
supported for the gcc4-compatible ABI.
* doc/html/manual/using_dual_abi.html: Regenerate.
This makes durations, time points and calendrical types available for
freestanding. The clocks and time zone utilities are disabled for
freestanding, as they require functions in the hosted lib.
Add support for a new macro _GLIBCXX_NO_FREESTANDING_CHRONO which can be
used to explicitly disable <chrono> for freestanding.
libstdc++-v3/ChangeLog:
* doc/xml/manual/using.xml (_GLIBCXX_NO_FREESTANDING_CHRONO):
Document macro.
* doc/html/*: Regenerate.
* include/bits/chrono.h [_GLIBCXX_NO_FREESTANDING_CHRONO]:
Only include <bits/require_hosted.h> when this macro is defined.
[_GLIBCXX_HOSTED]: Only define clocks for hosted.
* include/bits/version.def (chrono_udls): Remove hosted=yes.
* include/bits/version.h: Regenerate.
* include/std/chrono [_GLIBCXX_HOSTED]: Only define clocks and
time zone utilities for hosted.
* testsuite/std/time/freestanding.cc: New test.
There are lots of bugs that affect libstdc++ output from Doxygen, so
using 1.9.6 or later is recommended. Give a lower minimum, because some
distros still use 1.9.1 and that will work, albeit suboptimally.
libstdc++-v3/ChangeLog:
* doc/xml/manual/documentation_hacking.xml: Update minimum
Doxygen version.
* doc/html/*: Regenerate.
Link to the docs for GCC trunk instead. For the release branches, the
link should be to the docs for appropriate release branch.
Also replace the incomplete/outdated list of explicit -std options with
a single entry for the -std option.
libstdc++-v3/ChangeLog:
PR libstdc++/115269
* doc/xml/manual/using.xml: Replace link to gcc-4.3.2 docs.
Replace list of -std=... options with a single entry for -std.
* doc/html/manual/using.html: Regenerate.
This section can be misread to say that shrink_to_fit is available from
GCC 3.4, but it was added later.
libstdc++-v3/ChangeLog:
* doc/xml/manual/strings.xml: Clarify that GCC 4.5 added
std::string::shrink_to_fit.
* doc/html/manual/strings.html: Regenerate.
This simplifies the changes needed after branching for a new release, so
that new line breaks don't need to be introduced every time we branch.
libstdc++-v3/ChangeLog:
* doc/html/manual/status.html: Regenerate.
* doc/xml/manual/status_cxx1998.xml: Adjust whitespace.
* doc/xml/manual/status_cxx2011.xml: Likewise.
* doc/xml/manual/status_cxx2014.xml: Likewise.
* doc/xml/manual/status_cxx2017.xml: Likewise.
* doc/xml/manual/status_cxx2020.xml: Likewise.
* doc/xml/manual/status_cxx2023.xml: Likewise.
* doc/xml/manual/status_cxxtr1.xml: Likewise.
* doc/xml/manual/status_cxxtr24733.xml: Likewise.
We can replace "GCC <next>" with "GCC 14.1.0" now that we're nearing the
release.
libstdc++-v3/ChangeLog:
* doc/xml/manual/abi.xml: Replace "<next>" with "14.1.0".
* doc/html/manual/abi.html: Regenerate.
When we are already touching this topic, here is a patch like r13-5126
which documents the upcoming release symbol versions in the documentation.
2024-04-11 Jakub Jelinek <jakub@redhat.com>
* doc/xml/manual/abi.xml: Add latest library versions.
* doc/html/manual/abi.html: Regenerate.
There are several more sub-directories below 'src' now, with lots more
conveience libraries. Document them all as of GCC 14.
Also document how to regenerate the generated headers under include/bits
and how to update the tzdata.zi file.
libstdc++-v3/ChangeLog:
* doc/xml/manual/build_hacking.xml: Document generated files.
Update list of convenience libraries and sub-directories under
the src directory.
* doc/html/*: Regenerate.
The bug with exceptions thrown during a std::call_once call affects all
targets, so fix the docs that say it only affects non-Linux targets.
libstdc++-v3/ChangeLog:
PR libstdc++/66146
* doc/xml/manual/status_cxx2011.xml: Remove mention of Linux in
note about std::call_once.
* doc/xml/manual/status_cxx2014.xml: Likewise.
* doc/xml/manual/status_cxx2017.xml: Likewise.
* doc/html/manual/status.html: Regenerate.
libstdc++-v3/ChangeLog:
* doc/xml/manual/debug.xml: Improve docs on debug builds and
using ASan. Mention _GLIBCXX_ASSERTIONS. Reorder sections to put
the most relevant ones first.
* doc/xml/manual/using.xml: Add comma.
* doc/html/*: Regenerate.
The macro-based concept checks are unmaintained and do not support C++11
or later, so reject valid code. If nobody plans to update them we should
consider removing them. Alternatively, we could ignore the macro for
C++11 and later, so they have no effect and don't reject valid code.
libstdc++-v3/ChangeLog:
* doc/xml/manual/debug.xml: Document that concept checking might
be removed in future.
* doc/xml/manual/extensions.xml: Likewise.
We don't want a separate ChangeLog submission now.
libstdc++-v3/ChangeLog:
* doc/xml/manual/appendix_contributing.xml: Replace outdated
info on ChangeLog entries.
* doc/html/manual/appendix_contributing.html: Regenerate.
The configure option is no longer necessary.
libstdc++-v3/ChangeLog:
* doc/xml/manual/debug_mode.xml: Update docs for backtraces.
* doc/html/manual/debug_mode_using.html: Regenerate.
The API Evolution section of the manual should mention when the
libstdc++exp.a library was added.
libstdc++-v3/ChangeLog:
* doc/xml/manual/evolution.xml: Document addition of
libstdc++exp.a.
* doc/html/*: Regenerate.
The buildstat.html pages have not existed since gcc-8 so remove
referencs to them in the libstdc++ manual.
libstdc++-v3/ChangeLog:
* doc/html/*: Regenerate.
* doc/xml/faq.xml: Remove reference to buildstat.html pages.
* doc/xml/manual/test.xml: Likewise
The name "_N" is listed as a reserved name on Solaris, so we shouldn't
use it as an example of our naming conventions.
libstdc++-v3/ChangeLog:
* doc/xml/manual/appendix_contributing.xml: Replace example that
uses a BADNAME.
* doc/html/manual/source_code_style.html: Regenerate.
The row for P1466R3 was missing the info on when it was implemented.
libstdc++-v3/ChangeLog:
* doc/xml/manual/status_cxx2020.xml: Tweak P1466R3 status.
* doc/html/manual/status.html: Regenerate.
libstdc++-v3/ChangeLog:
* doc/xml/manual/intro.xml: Clarify that building libstdc++
separately from GCC is not supported.
* doc/xml/manual/prerequisites.xml: Note msgfmt prerequisite for
testing.
* doc/html/manual/setup.html: Regenerate.
This copies the code from the compiler's gcc/testsuite/lib/g++-dg.exp so
that each test can be run multiple times, with different -std options.
This means that we can remove most { dg-options "-std=gnu++20" }
directives from tests, because the testsuite will automatically select
a set of -std options that includes that version.
Tests that should only run for a specific standard (e.g. ones that use
something like { dg-do run { target c++11_only } }) should still specify
that standard with { dg-options "-std=gnu++11" }, which overrides the
automatic selection. But a dg-options that selects a newer standard than
the default can be removed, because that standard will be selected
automatically based on a selector like { target c++20 } in the dg-do
directive. This will allow those tests to be run for more than just the
one they currently hardcode, so that e.g. std::format tests can be run
for all of C++20, C++23 and C++26. Currently that has to be done by
adding a second test file that uses a different dg-options line.
By default most tests will continue to run with only the default dialect
(currently -std=gnu++17) so that the time to run the entire testsuite is
not increased. We can revisit this later if increasing the testsuite
time (and coverage) is acceptable. Libstdc++ developers can easily
override the defaults to run for multiple versions. To test all
versions, either add 'set v3_std_list { 98 11 14 17 20 23 26 }' to
~/.dejagnurc or define GLIBCXX_TESTSUITE_STDS="98,11,14,17,20,23,26" in
the environment.
This should be more efficient than the current way to test with multple
standards, i.e. --target_board=unix{-std=c++14,-std=c++17,-std=c++20},
because today all tests with an explicit -std option hardcoded in them
get run for each target board variation but using the exact same
hardcoded -std every time. With the new approach you can just use the
default --target_board=unix and set GLIBCXX_TESTSUITE_STDS="14,17,20"
and now a test that has { target c++20 } will only run once (and be
UNSUPPORTED twice), instead of running with identical options three
times.
In order to support ~/.dejagnurc and $DEJAGNU files that need to work
with versions of GCC without this change, a new variable is added to
site.tmp to detect whether v3_std_list is supported. That allows e.g.
if { [info exists v3-use-std-list] } {
set v3_std_list { 11 17 23 }
set target_list { "unix{,-m32}" }
} else {
set target_list { "unix{,-std=gnu++2b,-std=gnu++11,-m32}" }
}
libstdc++-v3/ChangeLog:
* doc/xml/manual/test.xml: Update documentation on running and
writing tests.
* doc/html/manual/test.html: Regenerate.
* testsuite/Makefile.am: Add v3-use-std-list to site.tmp
* testsuite/Makefile.in: Regenerate.
* testsuite/lib/dg-options.exp (add_options_for_strict_std): New
proc.
* testsuite/lib/libstdc++.exp (search_for): New utility proc.
(v3-dg-runtest): New proc to replace dg-runtest.
* testsuite/libstdc++-dg/conformance.exp: Use v3-dg-runtest.