summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2023-04-12 11:55:24 +0100
committerJonathan Wakely <jwakely@redhat.com>2023-04-12 13:15:12 +0100
commit9f10b4957ca6058d1a801c5e4bfe11bf159da809 (patch)
treef629d59ee1176896a45a7f407ab09445c98677e9 /libstdc++-v3/include
parent88ed90187ffff3870a9514007672f13476ff96a7 (diff)
downloadgcc-9f10b4957ca6058d1a801c5e4bfe11bf159da809.tar.gz
libstdc++: Initialize all members of basic_endpoint union [PR109482]
On Solaris the in_addr struct contains a union and value-initializing it does not make the s_addr member active. This means we can't access that member later during constant evaluation. Make the constructors explicitly set every member that we might want to read later in constexpr member functions. This means even the default constructor can only be constexpr for C++20, because we can't change the active member of a union in older standards. libstdc++-v3/ChangeLog: PR libstdc++/109482 * include/experimental/internet (basic_endpoint::basic_endpoint()): Ensure that the required union members are active. Only define as constexpr for C++20 and later. (basic_endpoint::basic_endpoint(const protocol_type&, port_type)): Likewise. * testsuite/experimental/net/internet/endpoint/cons.cc: Only check constexpr default constructor for C++20 and later. * testsuite/experimental/net/internet/endpoint/extensible.cc: Likewise.
Diffstat (limited to 'libstdc++-v3/include')
-rw-r--r--libstdc++-v3/include/experimental/internet22
1 files changed, 18 insertions, 4 deletions
diff --git a/libstdc++-v3/include/experimental/internet b/libstdc++-v3/include/experimental/internet
index eb23ae21cdc..1f63c61ce85 100644
--- a/libstdc++-v3/include/experimental/internet
+++ b/libstdc++-v3/include/experimental/internet
@@ -1512,9 +1512,14 @@ namespace ip
// constructors:
- constexpr
+ _GLIBCXX20_CONSTEXPR
basic_endpoint() noexcept : _M_data()
- { _M_data._M_v4.sin_family = protocol_type::v4().family(); }
+ {
+ _M_data._M_v4.sin_family = protocol_type::v4().family();
+ // If in_addr contains a union, make the correct member active:
+ if (std::__is_constant_evaluated())
+ std::_Construct(&_M_data._M_v4.sin_addr.s_addr);
+ }
_GLIBCXX20_CONSTEXPR
basic_endpoint(const protocol_type& __proto,
@@ -1523,19 +1528,25 @@ namespace ip
{
if (__proto == protocol_type::v4())
{
- _M_data._M_v4.sin_family = __proto.family();
+ _M_data._M_v4.sin_family = protocol_type::v4().family();
_M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num);
+ if (std::__is_constant_evaluated())
+ std::_Construct(&_M_data._M_v4.sin_addr.s_addr);
}
else if (__proto == protocol_type::v6())
{
std::_Construct(&_M_data._M_v6);
_M_data._M_v6.sin6_family = __proto.family();
_M_data._M_v6.sin6_port = address_v4::_S_hton_16(__port_num);
+ _M_data._M_v6.sin6_scope_id = 0;
+ if (std::__is_constant_evaluated())
+ std::_Construct(&_M_data._M_v6.sin6_addr.s6_addr);
}
else
{
__glibcxx_assert(__proto == protocol_type::v4()
|| __proto == protocol_type::v6());
+
}
}
@@ -1548,13 +1559,16 @@ namespace ip
{
_M_data._M_v4.sin_family = protocol_type::v4().family();
_M_data._M_v4.sin_port = address_v4::_S_hton_16(__port_num);
- _M_data._M_v4.sin_addr.s_addr = __addr._M_v4._M_addr;
+ std::_Construct(&_M_data._M_v4.sin_addr.s_addr,
+ __addr._M_v4._M_addr);
}
else
{
std::_Construct(&_M_data._M_v6);
_M_data._M_v6.sin6_family = protocol_type::v6().family();
_M_data._M_v6.sin6_port = address_v4::_S_hton_16(__port_num);
+ if (std::__is_constant_evaluated())
+ std::_Construct(&_M_data._M_v6.sin6_addr.s6_addr);
uint8_t* __s6a = _M_data._M_v6.sin6_addr.s6_addr;
for (int __i = 0; __i < 16; ++__i)
__s6a[__i] = __addr._M_v6._M_bytes[__i];