tint: make utils::Bitcast not trigger gcc warning

When useing Bitcast to or from a class type, gcc warns even if the type
is trivially copyable. Fixed this by static_asserting that both types
are trivially copyable, and casting the pointers to std::byte*.

Change-Id: Ibb420f2dcdd35cfb187d74983fa8ab9b50d10c85
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/115180
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
Antonio Maiorano 2022-12-20 17:13:39 +00:00 committed by Dawn LUCI CQ
parent c4673b7386
commit ffa83ad1f7
1 changed files with 15 additions and 1 deletions

View File

@ -15,7 +15,9 @@
#ifndef SRC_TINT_UTILS_BITCAST_H_
#define SRC_TINT_UTILS_BITCAST_H_
#include <cstddef>
#include <cstring>
#include <type_traits>
namespace tint::utils {
@ -29,8 +31,20 @@ namespace tint::utils {
template <typename TO, typename FROM>
inline TO Bitcast(FROM&& from) {
static_assert(sizeof(FROM) == sizeof(TO));
// gcc warns in cases where either TO or FROM are classes, even if they are trivially
// copyable, with for example:
//
// error: void* memcpy(void*, const void*, size_t) copying an object of
// non-trivial type struct tint::Number<unsigned int> from an array of float
// [-Werror=class-memaccess]
//
// We avoid this by asserting that both types are indeed trivially copyable, and casting both
// args to std::byte*.
static_assert(std::is_trivially_copyable_v<std::decay_t<FROM>>);
static_assert(std::is_trivially_copyable_v<std::decay_t<TO>>);
TO to;
memcpy(&to, &from, sizeof(TO));
memcpy(reinterpret_cast<std::byte*>(&to), reinterpret_cast<const std::byte*>(&from),
sizeof(TO));
return to;
}