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>
diff --git a/src/tint/utils/bitcast.h b/src/tint/utils/bitcast.h
index 4450336..4f72bb8 100644
--- a/src/tint/utils/bitcast.h
+++ b/src/tint/utils/bitcast.h
@@ -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 @@
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;
}