diff --git a/src/google/protobuf/generated_message_tctable_impl.h b/src/google/protobuf/generated_message_tctable_impl.h index 019ff5078a4d..4b7e5edad311 100644 --- a/src/google/protobuf/generated_message_tctable_impl.h +++ b/src/google/protobuf/generated_message_tctable_impl.h @@ -576,6 +576,9 @@ class PROTOBUF_EXPORT TcParser final { static const char* FastMlS1(PROTOBUF_TC_PARAM_DECL); static const char* FastMlS2(PROTOBUF_TC_PARAM_DECL); + // NOTE: Do not dedup RefAt by having one call the other with a const_cast. It + // causes ICEs of gcc 7.5. + // https://github.com/protocolbuffers/protobuf/issues/13715 template static inline T& RefAt(void* x, size_t offset) { T* target = reinterpret_cast(static_cast(x) + offset); @@ -595,7 +598,20 @@ class PROTOBUF_EXPORT TcParser final { template static inline const T& RefAt(const void* x, size_t offset) { - return RefAt(const_cast(x), offset); + const T* target = + reinterpret_cast(static_cast(x) + offset); +#if !defined(NDEBUG) && !(defined(_MSC_VER) && defined(_M_IX86)) + // Check the alignment in debug mode, except in 32-bit msvc because it does + // not respect the alignment as expressed by `alignof(T)` + if (PROTOBUF_PREDICT_FALSE( + reinterpret_cast(target) % alignof(T) != 0)) { + AlignFail(std::integral_constant(), + reinterpret_cast(target)); + // Explicit abort to let compilers know this code-path does not return + abort(); + } +#endif + return *target; } template