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