From b3b55cf716ffb57ffa20d0a025ee79bc9dc5eeff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikkel=20Fahn=C3=B8e=20J=C3=B8rgensen?= Date: Fri, 8 Mar 2024 21:38:29 +0100 Subject: [PATCH] Use portable memory accessors instead of pointer casts --- include/flatcc/flatcc_accessors.h | 23 ++++++++++++++--------- include/flatcc/flatcc_flatbuffers.h | 9 +++++++++ 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/include/flatcc/flatcc_accessors.h b/include/flatcc/flatcc_accessors.h index 084ecb1b1..97e45e9f0 100644 --- a/include/flatcc/flatcc_accessors.h +++ b/include/flatcc/flatcc_accessors.h @@ -9,7 +9,16 @@ extern "C" { #include #endif + +/* __flatcc_copy_word defined in flatcc_flatbuffers.h, can be redefined. + Used for handling strict aliasing memory access. + Note that type punning via union casts is valid in C, but not in C++. */ + #define __flatcc_basic_scalar_accessors_impl(N, T, W, E) \ +static inline T N ## _read(const void *p) \ +{ T v; __flatcc_copy_word(&v, p, sizeof(T)); return v; } \ +static inline void N ## _write(void *p, T v) \ +{ __flatcc_copy_word(p, &v, sizeof(T)); } \ static inline size_t N ## __size(void) \ { return sizeof(T); } \ static inline T *N ## __ptr_add(T *p, size_t i) \ @@ -17,19 +26,15 @@ static inline T *N ## __ptr_add(T *p, size_t i) \ static inline const T *N ## __const_ptr_add(const T *p, size_t i) \ { return p + i; } \ static inline T N ## _read_from_pe(const void *p) \ -{ return N ## _cast_from_pe(*(T *)p); } \ +{ return N ## _cast_from_pe(N ## _read(p)); } \ static inline T N ## _read_to_pe(const void *p) \ -{ return N ## _cast_to_pe(*(T *)p); } \ -static inline T N ## _read(const void *p) \ -{ return *(T *)p; } \ +{ return N ## _cast_to_pe(N ## _read(p)); } \ static inline void N ## _write_from_pe(void *p, T v) \ -{ *(T *)p = N ## _cast_from_pe(v); } \ +{ N ## _write(p, N ## _cast_from_pe(v)); } \ static inline void N ## _write_to_pe(void *p, T v) \ -{ *(T *)p = N ## _cast_to_pe(v); } \ -static inline void N ## _write(void *p, T v) \ -{ *(T *)p = v; } \ +{ N ## _write(p, N ## _cast_to_pe(v)); } \ static inline T N ## _read_from_le(const void *p) \ -{ return N ## _cast_from_le(*(T *)p); } \ +{ return N ## _cast_from_le(N ## _read(p)); } \ typedef struct { int is_null; T value; } N ## _option_t; #define __flatcc_define_integer_accessors_impl(N, T, W, E) \ diff --git a/include/flatcc/flatcc_flatbuffers.h b/include/flatcc/flatcc_flatbuffers.h index 4bfc74352..916656673 100644 --- a/include/flatcc/flatcc_flatbuffers.h +++ b/include/flatcc/flatcc_flatbuffers.h @@ -38,6 +38,15 @@ extern "C" { * or compatible definitions. */ #include "flatcc/portable/pendian.h" + +/* Needed by flatcc_accessors.h to handle strict aliasing rules. + Option to configure own implementation if target has better solution. */ +#ifndef __flatcc_copy_word +#include "flatcc/portable/pmemaccess.h" +/* Fast memcpy for memory words. */ +#define __flatcc_copy_word(dest, src, len) mem_copy_word(dest, src, len) +#endif + #include "flatcc/flatcc_types.h" #include "flatcc/flatcc_endian.h" #include "flatcc/flatcc_identifier.h"