public inbox for libstdc++-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-6325] libstdc++: Fix conversion to/from net::ip::address_v4::bytes_type
@ 2023-02-24 14:26 Jonathan Wakely
0 siblings, 0 replies; only message in thread
From: Jonathan Wakely @ 2023-02-24 14:26 UTC (permalink / raw)
To: gcc-cvs, libstdc++-cvs
https://gcc.gnu.org/g:36ecfb75e053d54dd36dd3900d3096004f6d9aae
commit r13-6325-g36ecfb75e053d54dd36dd3900d3096004f6d9aae
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Fri Feb 24 10:08:26 2023 +0000
libstdc++: Fix conversion to/from net::ip::address_v4::bytes_type
I messed up the endianness of the address_v4::bytes_type array, which
should always be in network byte order. We can just use bit_cast to
convert the _M_addr member to/from bytes_type.
libstdc++-v3/ChangeLog:
* include/experimental/internet (address_4(const bytes_type&)):
Use __builtin_bit_cast if available, otherwise convert to
network byte order.
(address_v4::to_bytes()): Likewise, but convert from network
byte order.
* testsuite/experimental/net/internet/address/v4/cons.cc: Fix
incorrect tests. Check for constexpr too.
* testsuite/experimental/net/internet/address/v4/creation.cc:
Likewise.
* testsuite/experimental/net/internet/address/v4/members.cc:
Check that bytes_type is a standard-layout type.
Diff:
---
libstdc++-v3/include/experimental/internet | 20 +++++++++----
.../experimental/net/internet/address/v4/cons.cc | 33 ++++++++++++++--------
.../net/internet/address/v4/creation.cc | 24 +++++++++++++---
.../net/internet/address/v4/members.cc | 3 ++
4 files changed, 60 insertions(+), 20 deletions(-)
diff --git a/libstdc++-v3/include/experimental/internet b/libstdc++-v3/include/experimental/internet
index 08bd0db4bb2..3fd200251fa 100644
--- a/libstdc++-v3/include/experimental/internet
+++ b/libstdc++-v3/include/experimental/internet
@@ -198,7 +198,12 @@ namespace ip
constexpr
address_v4(const bytes_type& __b)
- : _M_addr((__b[0] << 24) | (__b[1] << 16) | (__b[2] << 8) | __b[3])
+#if __has_builtin(__builtin_bit_cast)
+ : _M_addr(__builtin_bit_cast(uint_type, __b))
+#else
+ : _M_addr(_S_hton_32((__b[0] << 24) | (__b[1] << 16)
+ | (__b[2] << 8) | __b[3]))
+#endif
{ }
explicit constexpr
@@ -227,12 +232,17 @@ namespace ip
constexpr bytes_type
to_bytes() const noexcept
{
+#if __has_builtin(__builtin_bit_cast)
+ return __builtin_bit_cast(bytes_type, _M_addr);
+#else
+ auto __host = to_uint();
return bytes_type{
- (_M_addr >> 24) & 0xFF,
- (_M_addr >> 16) & 0xFF,
- (_M_addr >> 8) & 0xFF,
- _M_addr & 0xFF
+ (__host >> 24) & 0xFF,
+ (__host >> 16) & 0xFF,
+ (__host >> 8) & 0xFF,
+ __host & 0xFF
};
+#endif
}
constexpr uint_type
diff --git a/libstdc++-v3/testsuite/experimental/net/internet/address/v4/cons.cc b/libstdc++-v3/testsuite/experimental/net/internet/address/v4/cons.cc
index 65f23642de4..af9fef2215e 100644
--- a/libstdc++-v3/testsuite/experimental/net/internet/address/v4/cons.cc
+++ b/libstdc++-v3/testsuite/experimental/net/internet/address/v4/cons.cc
@@ -24,41 +24,45 @@
using std::experimental::net::ip::address_v4;
-void
-test01()
+#if __cplusplus < 202002L
+// Naughty, but operator== for std::array is not constexpr until C++20.
+constexpr bool
+operator==(const address_v4::bytes_type& lhs, const address_v4::bytes_type& rhs)
{
- bool test __attribute__((unused)) = false;
+ return lhs[0] == rhs[0] && lhs[1] == rhs[1]
+ && lhs[2] == rhs[2] && lhs[3] == rhs[3];
+}
+#endif
+constexpr void
+test01()
+{
address_v4 a0;
VERIFY( a0.to_uint() == 0 );
VERIFY( a0.to_bytes() == address_v4::bytes_type{} );
}
-void
+constexpr void
test02()
{
- bool test __attribute__((unused)) = false;
-
address_v4 a0{ address_v4::bytes_type{} };
VERIFY( a0.to_uint() == 0 );
VERIFY( a0.to_bytes() == address_v4::bytes_type{} );
address_v4::bytes_type b1{ 1, 2, 3, 4 };
address_v4 a1{ b1 };
- VERIFY( a1.to_uint() == ntohl((1 << 24) | (2 << 16) | (3 << 8) | 4) );
+ VERIFY( a1.to_uint() == ((1 << 24) | (2 << 16) | (3 << 8) | 4) );
VERIFY( a1.to_bytes() == b1 );
}
-void
+constexpr void
test03()
{
- bool test __attribute__((unused)) = false;
-
address_v4 a0{ 0u };
VERIFY( a0.to_uint() == 0 );
VERIFY( a0.to_bytes() == address_v4::bytes_type{} );
- address_v4::uint_type u1 = ntohl((5 << 24) | (6 << 16) | (7 << 8) | 8);
+ address_v4::uint_type u1 = (5 << 24) | (6 << 16) | (7 << 8) | 8;
address_v4 a1{ u1 };
VERIFY( a1.to_uint() == u1 );
VERIFY( a1.to_bytes() == address_v4::bytes_type( 5, 6, 7, 8 ) );
@@ -70,4 +74,11 @@ main()
test01();
test02();
test03();
+
+ constexpr bool c = []{
+ test01();
+ test02();
+ test03();
+ return true;
+ };
}
diff --git a/libstdc++-v3/testsuite/experimental/net/internet/address/v4/creation.cc b/libstdc++-v3/testsuite/experimental/net/internet/address/v4/creation.cc
index 441c832bf54..84aebbb7adc 100644
--- a/libstdc++-v3/testsuite/experimental/net/internet/address/v4/creation.cc
+++ b/libstdc++-v3/testsuite/experimental/net/internet/address/v4/creation.cc
@@ -25,7 +25,17 @@
namespace net = std::experimental::net;
using net::ip::address_v4;
-void
+#if __cplusplus < 202002L
+// Naughty, but operator== for std::array is not constexpr until C++20.
+constexpr bool
+operator==(const address_v4::bytes_type& lhs, const address_v4::bytes_type& rhs)
+{
+ return lhs[0] == rhs[0] && lhs[1] == rhs[1]
+ && lhs[2] == rhs[2] && lhs[3] == rhs[3];
+}
+#endif
+
+constexpr void
test01()
{
auto a0 = make_address_v4( address_v4::bytes_type{} );
@@ -34,18 +44,18 @@ test01()
address_v4::bytes_type b1{ 1, 2, 3, 4 };
auto a1 = make_address_v4( b1 );
- VERIFY( a1.to_uint() == ntohl((1 << 24) | (2 << 16) | (3 << 8) | 4) );
+ VERIFY( a1.to_uint() == ((1 << 24) | (2 << 16) | (3 << 8) | 4) );
VERIFY( a1.to_bytes() == b1 );
}
-void
+constexpr void
test02()
{
auto a0 = net::ip::make_address_v4(0u);
VERIFY( a0.to_uint() == 0 );
VERIFY( a0.to_bytes() == address_v4::bytes_type{} );
- address_v4::uint_type u1 = ntohl((5 << 24) | (6 << 16) | (7 << 8) | 8);
+ address_v4::uint_type u1 = ((5 << 24) | (6 << 16) | (7 << 8) | 8);
auto a1 = net::ip::make_address_v4( u1 );
VERIFY( a1.to_uint() == u1 );
VERIFY( a1.to_bytes() == address_v4::bytes_type( 5, 6, 7, 8 ) );
@@ -84,4 +94,10 @@ main()
test01();
test02();
test03();
+
+ constexpr bool c = []{
+ test01();
+ test02();
+ return true;
+ };
}
diff --git a/libstdc++-v3/testsuite/experimental/net/internet/address/v4/members.cc b/libstdc++-v3/testsuite/experimental/net/internet/address/v4/members.cc
index c40a8103664..ac59405c599 100644
--- a/libstdc++-v3/testsuite/experimental/net/internet/address/v4/members.cc
+++ b/libstdc++-v3/testsuite/experimental/net/internet/address/v4/members.cc
@@ -26,6 +26,9 @@
using std::experimental::net::ip::address_v4;
+static_assert(std::is_standard_layout<address_v4::bytes_type>::value,
+ "net::ip::address_v4::bytes_type is a standard layout type");
+
constexpr bool
test01()
{
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-02-24 14:26 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-24 14:26 [gcc r13-6325] libstdc++: Fix conversion to/from net::ip::address_v4::bytes_type Jonathan Wakely
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).