Make QuicFrame a standard-layout struct.
C++ provides certain guarantees about the way union fields interact, which are only valid for standard-layout types. Standard-layout types are not allowed to have data members in both base and derived types; this fixes that by moving QuicInlinedFrame::type into individual frames.
Also, before C++17, using offsetof() on non-standard-layout types is undefined behavor.
Thanks to Stephan Hartmann <stha09@googlemail.com> for pointing this problem out in <https://quiche-review.googlesource.com/c/quiche/+/10600>.
PiperOrigin-RevId: 320195673
Change-Id: I179634af3e3a199b7b7320a031b42898a5644824
diff --git a/quic/core/frames/quic_inlined_frame.h b/quic/core/frames/quic_inlined_frame.h
index 08c4869..cfa32dc 100644
--- a/quic/core/frames/quic_inlined_frame.h
+++ b/quic/core/frames/quic_inlined_frame.h
@@ -5,6 +5,8 @@
#ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_INLINED_FRAME_H_
#define QUICHE_QUIC_CORE_FRAMES_QUIC_INLINED_FRAME_H_
+#include <type_traits>
+
#include "net/third_party/quiche/src/quic/core/quic_types.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_export.h"
@@ -16,13 +18,15 @@
// inline and out-of-line frame types.
template <typename DerivedT>
struct QUIC_EXPORT_PRIVATE QuicInlinedFrame {
- QuicInlinedFrame(QuicFrameType type) : type(type) {
+ QuicInlinedFrame(QuicFrameType type) {
+ static_cast<DerivedT*>(this)->type = type;
+ static_assert(std::is_standard_layout<DerivedT>::value,
+ "Inlined frame must have a standard layout");
static_assert(offsetof(DerivedT, type) == 0,
"type must be the first field.");
static_assert(sizeof(DerivedT) <= 24,
"Frames larger than 24 bytes should not be inlined.");
}
- QuicFrameType type;
};
} // namespace quic