Force `Rep` size to be at least 8 bytes when running under a sanitizer

Sanitizers are picky for container start addresses to be aligned at 8 byte aligned offsets, which causes issues under 32 bit compilations as we lay out the internal layout as {arena*, elements[...]}. This change forces the minimum header size to be at least 8 bytes, adding padding as needed.

PiperOrigin-RevId: 527596133
pull/12573/head
Martijn Vels 2 years ago committed by Copybara-Service
parent a1b6dd9247
commit c224676c2d
  1. 18
      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<Element*>(reinterpret_cast<char*>(this) +
kRepHeaderSize);
}
union {
alignas(8) Arena* arena;
Element unused;
};
Element* elements() { return reinterpret_cast<Element*>(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

Loading…
Cancel
Save