vi: Add std::is_trivially_copyable checks to Read and Write functions

It's undefined behavior to memcpy an object that isn't considered
trivially copyable, so put a compile-time check in to make sure this
doesn't occur.
This commit is contained in:
Lioncash 2018-07-23 14:52:32 -04:00
parent 344a0c91f2
commit 1432912ae8

View File

@ -5,6 +5,7 @@
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <memory> #include <memory>
#include <type_traits>
#include <utility> #include <utility>
#include <boost/optional.hpp> #include <boost/optional.hpp>
#include "common/alignment.h" #include "common/alignment.h"
@ -44,7 +45,9 @@ public:
template <typename T> template <typename T>
T Read() { T Read() {
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
ASSERT(read_index + sizeof(T) <= buffer.size()); ASSERT(read_index + sizeof(T) <= buffer.size());
T val; T val;
std::memcpy(&val, buffer.data() + read_index, sizeof(T)); std::memcpy(&val, buffer.data() + read_index, sizeof(T));
read_index += sizeof(T); read_index += sizeof(T);
@ -54,7 +57,9 @@ public:
template <typename T> template <typename T>
T ReadUnaligned() { T ReadUnaligned() {
static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
ASSERT(read_index + sizeof(T) <= buffer.size()); ASSERT(read_index + sizeof(T) <= buffer.size());
T val; T val;
std::memcpy(&val, buffer.data() + read_index, sizeof(T)); std::memcpy(&val, buffer.data() + read_index, sizeof(T));
read_index += sizeof(T); read_index += sizeof(T);
@ -88,8 +93,12 @@ public:
template <typename T> template <typename T>
void Write(const T& val) { void Write(const T& val) {
if (buffer.size() < write_index + sizeof(T)) static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
if (buffer.size() < write_index + sizeof(T)) {
buffer.resize(buffer.size() + sizeof(T) + DefaultBufferSize); buffer.resize(buffer.size() + sizeof(T) + DefaultBufferSize);
}
std::memcpy(buffer.data() + write_index, &val, sizeof(T)); std::memcpy(buffer.data() + write_index, &val, sizeof(T));
write_index += sizeof(T); write_index += sizeof(T);
write_index = Common::AlignUp(write_index, 4); write_index = Common::AlignUp(write_index, 4);
@ -97,7 +106,9 @@ public:
template <typename T> template <typename T>
void WriteObject(const T& val) { void WriteObject(const T& val) {
u32_le size = static_cast<u32>(sizeof(val)); static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable.");
const u32_le size = static_cast<u32>(sizeof(val));
Write(size); Write(size);
// TODO(Subv): Support file descriptors. // TODO(Subv): Support file descriptors.
Write<u32_le>(0); // Fd count. Write<u32_le>(0); // Fd count.