diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index ac5d28d12a..a26cb5c686 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -200,9 +200,6 @@ void MessageLite::LogInitializationErrorMessage() const { namespace internal { void FailDynamicCast(const MessageLite& from, const MessageLite& to) { -#if defined(ABSL_HAVE_EXCEPTIONS) - throw std::bad_cast(); -#endif const auto to_name = to.GetTypeName(); if (internal::GetClassData(from)->is_dynamic) { ABSL_LOG(FATAL) diff --git a/src/google/protobuf/message_lite.h b/src/google/protobuf/message_lite.h index 9016c8478a..41a7789142 100644 --- a/src/google/protobuf/message_lite.h +++ b/src/google/protobuf/message_lite.h @@ -1330,7 +1330,7 @@ std::string Utf8Format(const MessageLite& message_lite); // // `DynamicCastMessage` is similar to `dynamic_cast`, returns `nullptr` when the // input is not an instance of `T`. The overloads that take a reference will -// terminate on mismatch. +// throw std::bad_cast on mismatch, or terminate if compiled without exceptions. // // `DownCastMessage` is a lightweight function for downcasting base // `MessageLite` pointer to derived type, where it only does type checking if @@ -1364,6 +1364,11 @@ template const T& DynamicCastMessage(const MessageLite& from) { const T* destination_message = DynamicCastMessage(&from); if (ABSL_PREDICT_FALSE(destination_message == nullptr)) { + // If exceptions are enabled, throw. + // Otherwise, log a fatal error. +#if defined(ABSL_HAVE_EXCEPTIONS) + throw std::bad_cast(); +#endif // Move the logging into an out-of-line function to reduce bloat in the // caller. internal::FailDynamicCast(from, T::default_instance());