libstdc++: Fix constexpr functions in <experimental/internet>
authorJonathan Wakely <jwakely@redhat.com>
Wed, 22 Mar 2023 17:00:11 +0000 (17:00 +0000)
committerJonathan Wakely <jwakely@redhat.com>
Wed, 29 Mar 2023 23:36:08 +0000 (00:36 +0100)
commite0d77144aaa56ee6e00fd0ba520b0a5c7e052423
treead7e99c748a4247dbb64374a33d8e35979271fa7
parentce39714a1ce58f2f32e8a44a224061290670db0f
libstdc++: Fix constexpr functions in <experimental/internet>

Change ip::basic_endpoint to work in constant expressions, but only for
C++20 and later (due to the use of a union, which cannot change active
member in constexpr evaluation until C++20).

During constant evaluation we cannot inspect the common initial sequence
of basic_endpoint's union members to check whether sin_family == AF_INET
or AF_INET6.  This means we need to store an additional boolean member
that remembers whether we have a v4 or v6 address. The address type can
change behind our backs if a user copies an address to the data()
pointer and then calls resize(n), so we need to inspect the sa_family_t
member in the union after a resize and update the boolean. POSIX only
guarantees that the sa_family_t member of each protocol-specific address
structure is at the same offset and of the same type, not that there is
a common initial sequence. The check in resize is done using memcmp, so
that we avoid accessing an inactive member of the union if the
sockaddr_in and sockaddr_in6 structures do not have a common initial
sequence that includes the sa_family_t member.

libstdc++-v3/ChangeLog:

* include/experimental/internet (ip::make_address): Implement
missing overload.
(ip::address_v4::broadcast()): Avoid undefined shift.
(ip::basic_endpoint): Fix member functions for constexpr.
(ip::basic_endpoint::_M_is_v6): Replace member function with
data member, adjust member functions using it.
(ip::basic_endpoint::resize): Update _M_is_v6 based on sockaddr
content.
* testsuite/experimental/net/internet/address/v4/cons.cc: Fix
constexpr checks to work in C++14.
* testsuite/experimental/net/internet/address/v4/creation.cc:
Likewise.
* testsuite/experimental/net/internet/endpoint/cons.cc:
Likewise.
* testsuite/experimental/net/internet/network/v4/cons.cc:
Likewise.
* testsuite/experimental/net/internet/network/v4/members.cc:
Likewise.
* testsuite/experimental/net/internet/endpoint/extensible.cc: New test.
libstdc++-v3/include/experimental/internet
libstdc++-v3/testsuite/experimental/net/internet/address/v4/cons.cc
libstdc++-v3/testsuite/experimental/net/internet/address/v4/creation.cc
libstdc++-v3/testsuite/experimental/net/internet/endpoint/cons.cc
libstdc++-v3/testsuite/experimental/net/internet/endpoint/extensible.cc [new file with mode: 0644]
libstdc++-v3/testsuite/experimental/net/internet/network/v4/cons.cc
libstdc++-v3/testsuite/experimental/net/internet/network/v4/members.cc