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:
parent
344a0c91f2
commit
1432912ae8
|
@ -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.
|
||||||
|
|
Reference in New Issue