@@ -576,6 +576,9 @@ class PROTOBUF_EXPORT TcParser final {
576
576
static const char * FastMlS1 (PROTOBUF_TC_PARAM_DECL);
577
577
static const char * FastMlS2 (PROTOBUF_TC_PARAM_DECL);
578
578
579
+ // NOTE: Do not dedup RefAt by having one call the other with a const_cast. It
580
+ // causes ICEs of gcc 7.5.
581
+ // https://github.com/protocolbuffers/protobuf/issues/13715
579
582
template <typename T>
580
583
static inline T& RefAt (void * x, size_t offset) {
581
584
T* target = reinterpret_cast <T*>(static_cast <char *>(x) + offset);
@@ -595,7 +598,20 @@ class PROTOBUF_EXPORT TcParser final {
595
598
596
599
template <typename T>
597
600
static inline const T& RefAt (const void * x, size_t offset) {
598
- return RefAt<T>(const_cast <void *>(x), offset);
601
+ const T* target =
602
+ reinterpret_cast <const T*>(static_cast <const char *>(x) + offset);
603
+ #if !defined(NDEBUG) && !(defined(_MSC_VER) && defined(_M_IX86))
604
+ // Check the alignment in debug mode, except in 32-bit msvc because it does
605
+ // not respect the alignment as expressed by `alignof(T)`
606
+ if (PROTOBUF_PREDICT_FALSE (
607
+ reinterpret_cast <uintptr_t >(target) % alignof (T) != 0 )) {
608
+ AlignFail (std::integral_constant<size_t , alignof (T)>(),
609
+ reinterpret_cast <uintptr_t >(target));
610
+ // Explicit abort to let compilers know this code-path does not return
611
+ abort ();
612
+ }
613
+ #endif
614
+ return *target;
599
615
}
600
616
601
617
template <typename T>
0 commit comments