1diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc 2index 0524fd46226e6..082e5124a023f 100644 3--- a/src/google/protobuf/descriptor.cc 4+++ b/src/google/protobuf/descriptor.cc 5@@ -301,22 +301,16 @@ class FlatAllocation { 6 return ends_.template Get<U>(); 7 } 8 9- // Avoid the reinterpret_cast if the array is empty. 10- // Clang's Control Flow Integrity does not like the cast pointing to memory 11- // that is not yet initialized to be of that type. 12- // (from -fsanitize=cfi-unrelated-cast) 13 template <typename U> 14+ PROTOBUF_NO_SANITIZE("cfi-unrelated-cast", "vptr") 15 U* Begin() const { 16- int begin = BeginOffset<U>(), end = EndOffset<U>(); 17- if (begin == end) return nullptr; 18- return reinterpret_cast<U*>(data() + begin); 19+ return reinterpret_cast<U*>(data() + BeginOffset<U>()); 20 } 21 22 template <typename U> 23+ PROTOBUF_NO_SANITIZE("cfi-unrelated-cast", "vptr") 24 U* End() const { 25- int begin = BeginOffset<U>(), end = EndOffset<U>(); 26- if (begin == end) return nullptr; 27- return reinterpret_cast<U*>(data() + end); 28+ return reinterpret_cast<U*>(data() + EndOffset<U>()); 29 } 30 31 template <typename U> 32diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc 33index cae9ebe01ec2c..b84b55e4d8762 100644 34--- a/src/google/protobuf/port_def.inc 35+++ b/src/google/protobuf/port_def.inc 36@@ -764,6 +764,12 @@ 37 #define PROTOBUF_UNUSED 38 #endif 39 40+#if __has_attribute(no_sanitize) 41+#define PROTOBUF_NO_SANITIZE(...) __attribute__((no_sanitize(__VA_ARGS__))) 42+#else 43+#define PROTOBUF_NO_SANITIZE(...) 44+#endif 45+ 46 // ThreadSafeArenaz is turned off completely in opensource builds. 47 48 // Windows declares several inconvenient macro names. We #undef them and then 49