diff --git a/src/google/protobuf/repeated_field.h b/src/google/protobuf/repeated_field.h index 4acbe87b75..16b8b4b71a 100644 --- a/src/google/protobuf/repeated_field.h +++ b/src/google/protobuf/repeated_field.h @@ -423,17 +423,17 @@ class RepeatedField final return prev_size; } - // Pad the Rep after arena allow for power-of-two byte sizes when - // sizeof(Element) > sizeof(Arena*). eg for 16-byte objects. - static PROTOBUF_CONSTEXPR const size_t kRepHeaderSize = - sizeof(Arena*) < sizeof(Element) ? sizeof(Element) : sizeof(Arena*); + // Pad the rep to being max(Arena*, Element) with a minimum align + // of 8 as sanitizers are picky on the alignment of containers to + // start at 8 byte offsets even when compiling for 32 bit platforms. struct Rep { - Arena* arena; - Element* elements() { - return reinterpret_cast(reinterpret_cast(this) + - kRepHeaderSize); - } + union { + alignas(8) Arena* arena; + Element unused; + }; + Element* elements() { return reinterpret_cast(this + 1); } }; + static PROTOBUF_CONSTEXPR const size_t kRepHeaderSize = sizeof(Rep); // If total_size_ == 0 this points to an Arena otherwise it points to the // elements member of a Rep struct. Using this invariant allows the storage of