Skip to content

Commit

Permalink
non-UB type punning function
Browse files Browse the repository at this point in the history
  • Loading branch information
braindigitalis committed Oct 4, 2024
1 parent 27c1b07 commit 5838f50
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 8 deletions.
25 changes: 25 additions & 0 deletions include/dpp/convert_to.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <cstring>
#include <array>
#include <memory>
#include <new>

/**
* @brief Safely convert one type to another without UB.
* This is produces identical assembly to reinterpret_cast.
*
* @param ptr Input pointer type
* @return Converted pointer type
*
* @tparam IN source type
* @tparam OUT destination type
*
* This is essentially std::start_lifetime_as(), without
* the requirement for C++23.
*
* @note Based on code by Krystian Stasiowski
* (https://github.com/sdkrystian)
*/
template<typename IN, typename OUT> OUT* convert_to(IN* ptr)
{
return std::launder(static_cast<OUT*>(std::memmove(ptr, ptr, sizeof(OUT))));
}
1 change: 1 addition & 0 deletions include/dpp/dpp.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,4 @@
#include <dpp/timed_listener.h>
#include <dpp/collector.h>
#include <dpp/bignum.h>
#include <dpp/convert_to.h>
4 changes: 2 additions & 2 deletions library-vcpkg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ target_compile_options(
PRIVATE
"$<$<PLATFORM_ID:Windows>:$<$<CONFIG:Debug>:/sdl;/Od;/DEBUG;/MP;/DFD_SETSIZE=1024>>"
"$<$<PLATFORM_ID:Windows>:$<$<CONFIG:Release>:/O2;/Oi;/Oy;/GL;/Gy;/sdl;/MP;/DFD_SETSIZE=1024>>"
"$<$<PLATFORM_ID:Linux>:$<$<CONFIG:Debug>:-fPIC;-Wall;-Wempty-body;-Wno-psabi;-Wunknown-pragmas;-Wignored-qualifiers;-Wimplicit-fallthrough;-Wmissing-field-initializers;-Wsign-compare;-Wtype-limits;-Wuninitialized;-Wshift-negative-value;-pthread;-g;-Og;-fPIC>>"
"$<$<PLATFORM_ID:Linux>:$<$<CONFIG:Release>:-fPIC;-Wall;-Wempty-body;-Wno-psabi;-Wunknown-pragmas;-Wignored-qualifiers;-Wimplicit-fallthrough;-Wmissing-field-initializers;-Wsign-compare;-Wtype-limits;-Wuninitialized;-Wshift-negative-value;-pthread;-O3;-fPIC>>"
"$<$<PLATFORM_ID:Linux>:$<$<CONFIG:Debug>:-fPIC;-Wall;-Wempty-body;-Wno-class-memaccess;-Wno-psabi;-Wunknown-pragmas;-Wignored-qualifiers;-Wimplicit-fallthrough;-Wmissing-field-initializers;-Wsign-compare;-Wtype-limits;-Wuninitialized;-Wshift-negative-value;-pthread;-g;-Og;-fPIC>>"
"$<$<PLATFORM_ID:Linux>:$<$<CONFIG:Release>:-fPIC;-Wall;-Wempty-body;-Wno-class-memaccess;-Wno-psabi;-Wunknown-pragmas;-Wignored-qualifiers;-Wimplicit-fallthrough;-Wmissing-field-initializers;-Wsign-compare;-Wtype-limits;-Wuninitialized;-Wshift-negative-value;-pthread;-O3;-fPIC>>"
"${AVX_FLAG}"
)

Expand Down
2 changes: 1 addition & 1 deletion library/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ if(MSVC)
endif()
string(REGEX REPLACE "/W[1|2|3|4]" "/W3" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wall -Wno-unused-private-field -Wno-psabi -Wempty-body -Wignored-qualifiers -Wimplicit-fallthrough -Wmissing-field-initializers -Wsign-compare -Wtype-limits -Wuninitialized -Wshift-negative-value -pthread")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wall -Wno-class-memaccess -Wno-unused-private-field -Wno-psabi -Wempty-body -Wignored-qualifiers -Wimplicit-fallthrough -Wmissing-field-initializers -Wsign-compare -Wtype-limits -Wuninitialized -Wshift-negative-value -pthread")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og")

if (NOT MINGW)
Expand Down
10 changes: 5 additions & 5 deletions src/dpp/voice/enabled/discover_ip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include <dpp/exception.h>
#include <dpp/discordvoiceclient.h>
#include <dpp/convert_to.h>
#include "enabled.h"

#ifdef _WIN32
Expand Down Expand Up @@ -88,23 +89,22 @@ std::string discord_voice_client::discover_ip() {

if (socket.fd >= 0) {
sockaddr_in servaddr{};
memset(&servaddr, 0, sizeof(sockaddr_in));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(0);
if (bind(socket.fd, (sockaddr*)&servaddr, sizeof(servaddr)) < 0) {
if (bind(socket.fd, convert_to<sockaddr_in, const sockaddr>(&servaddr), sizeof(servaddr)) < 0) {
log(ll_warning, "Could not bind socket for IP discovery");
return "";
}
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(this->port);
servaddr.sin_addr.s_addr = inet_addr(this->ip.c_str());
if (::connect(socket.fd, (const sockaddr*)&servaddr, sizeof(sockaddr_in)) < 0) {
if (::connect(socket.fd, convert_to<sockaddr_in, const sockaddr>(&servaddr), sizeof(sockaddr_in)) < 0) {
log(ll_warning, "Could not connect socket for IP discovery");
return "";
}
if (::send(socket.fd, reinterpret_cast<const char*>(&discovery), sizeof(discovery), 0) == -1) {
if (::send(socket.fd, convert_to<ip_discovery_packet, const char>(&discovery), sizeof(discovery), 0) == -1) {
log(ll_warning, "Could not send packet for IP discovery");
return "";
}
Expand All @@ -121,7 +121,7 @@ std::string discord_voice_client::discover_ip() {
log(ll_warning, "Timed out in IP discovery");
return "";
default:
if (recv(socket.fd, reinterpret_cast<char*>(&discovery), sizeof(discovery), 0) == -1) {
if (recv(socket.fd, convert_to<ip_discovery_packet, char>(&discovery), sizeof(discovery), 0) == -1) {
log(ll_warning, "Could not receive packet for IP discovery");
return "";
}
Expand Down

0 comments on commit 5838f50

Please sign in to comment.