Add an `Unreachable()` function to replace `PROTOBUF_ASSUME(false);` uses.
It shows intent more clearly.
PiperOrigin-RevId: 582822804
diff --git a/src/google/protobuf/BUILD.bazel b/src/google/protobuf/BUILD.bazel
index d770517..44f33f3 100644
--- a/src/google/protobuf/BUILD.bazel
+++ b/src/google/protobuf/BUILD.bazel
@@ -239,6 +239,7 @@
deps = [
":port_def",
":varint_shuffle",
+ "@com_google_absl//absl/base:config",
"@com_google_absl//absl/log:absl_check",
"@com_google_googletest//:gtest",
"@com_google_googletest//:gtest_main",
@@ -439,6 +440,7 @@
"//src/google/protobuf/stubs:lite",
"//third_party/utf8_range:utf8_validity",
"@com_google_absl//absl/base",
+ "@com_google_absl//absl/base:config",
"@com_google_absl//absl/container:btree",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/hash",
diff --git a/src/google/protobuf/port.h b/src/google/protobuf/port.h
index 51e63e3..6d7bd4b 100644
--- a/src/google/protobuf/port.h
+++ b/src/google/protobuf/port.h
@@ -22,6 +22,7 @@
#include <typeinfo>
+#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
@@ -201,6 +202,18 @@
#endif
}
+#if ABSL_HAVE_BUILTIN(__builtin_FILE) && ABSL_HAVE_BUILTIN(__builtin_LINE)
+[[noreturn]] inline void Unreachable(const char* file = __builtin_FILE(),
+ int line = __builtin_LINE()) {
+#else
+[[noreturn]] inline void Unreachable(const char* file = "", int line = 0) {
+#endif
+#if defined(NDEBUG) && ABSL_HAVE_BUILTIN(__builtin_unreachable)
+ __builtin_unreachable();
+#endif
+ protobuf_assumption_failed("Unreachable", file, line);
+}
+
} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc
index d1bf975..42ffca6 100644
--- a/src/google/protobuf/port_def.inc
+++ b/src/google/protobuf/port_def.inc
@@ -1030,8 +1030,9 @@
namespace google {
namespace protobuf {
namespace internal {
-PROTOBUF_EXPORT void protobuf_assumption_failed(const char *pred,
- const char *file, int line);
+[[noreturn]] PROTOBUF_EXPORT void protobuf_assumption_failed(const char *pred,
+ const char *file,
+ int line);
} // namespace internal
} // namespace protobuf
} // namespace google
diff --git a/src/google/protobuf/port_test.cc b/src/google/protobuf/port_test.cc
index d1174c3..5fbd55b 100644
--- a/src/google/protobuf/port_test.cc
+++ b/src/google/protobuf/port_test.cc
@@ -5,10 +5,13 @@
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
//
+#include "google/protobuf/port.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <gtest/gtest.h>
+#include "absl/base/config.h"
// Must be included last
#include "google/protobuf/port_def.inc"
@@ -28,6 +31,16 @@
#endif
}
+TEST(PortTest, UnreachableTrapsOnDebugMode) {
+#ifdef GTEST_HAS_DEATH_TEST
+ EXPECT_DEBUG_DEATH(Unreachable(), "Assumption failed: 'Unreachable'");
+#if ABSL_HAVE_BUILTIN(__builtin_FILE)
+ EXPECT_DEBUG_DEATH(Unreachable(),
+ "port_test\\.cc:.*Assumption failed: 'Unreachable'");
+#endif
+#endif
+}
+
} // namespace internal
} // namespace protobuf
} // namespace google