Skip to content

Commit 33bbbeb

Browse files
Change DynamicCastMessage to throw a std::bad_cast exception when exceptions
are enabled. This makes the function a drop-in replacement for `dynamic_cast` when the user is expecting exceptions to be thrown. PiperOrigin-RevId: 689419852
1 parent 350e24e commit 33bbbeb

File tree

4 files changed

+24
-2
lines changed

4 files changed

+24
-2
lines changed

src/google/protobuf/BUILD.bazel

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,6 +1268,7 @@ cc_library(
12681268
":protobuf",
12691269
"//src/google/protobuf/testing",
12701270
"//src/google/protobuf/testing:file",
1271+
"@com_google_absl//absl/base:config",
12711272
"@com_google_absl//absl/container:flat_hash_map",
12721273
"@com_google_absl//absl/log:absl_check",
12731274
"@com_google_absl//absl/strings",
@@ -1735,6 +1736,7 @@ cc_test(
17351736
"//src/google/protobuf/testing",
17361737
"//src/google/protobuf/testing:file",
17371738
"//src/google/protobuf/util:differencer",
1739+
"@com_google_absl//absl/base:config",
17381740
"@com_google_absl//absl/hash:hash_testing",
17391741
"@com_google_absl//absl/log:absl_check",
17401742
"@com_google_absl//absl/log:scoped_mock_log",
@@ -1766,6 +1768,7 @@ cc_test(
17661768
"//src/google/protobuf/testing",
17671769
"//src/google/protobuf/testing:file",
17681770
"//src/google/protobuf/util:differencer",
1771+
"@com_google_absl//absl/base:config",
17691772
"@com_google_absl//absl/log:absl_check",
17701773
"@com_google_absl//absl/log:scoped_mock_log",
17711774
"@com_google_absl//absl/strings",

src/google/protobuf/lite_unittest.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,16 +1395,23 @@ TEST(LiteTest, DynamicCastMessage) {
13951395
EXPECT_EQ(shared_2, nullptr);
13961396
}
13971397

1398-
#if GTEST_HAS_DEATH_TEST
13991398
TEST(LiteTest, DynamicCastMessageInvalidReferenceType) {
14001399
CastType1 test_type_1;
14011400
const MessageLite& test_type_1_pointer_const_ref = test_type_1;
1401+
#if defined(ABSL_HAVE_EXCEPTIONS)
1402+
EXPECT_THROW(DynamicCastMessage<CastType2>(test_type_1_pointer_const_ref),
1403+
std::bad_cast);
1404+
#elif defined(GTEST_HAS_DEATH_TEST)
14021405
ASSERT_DEATH(
14031406
DynamicCastMessage<CastType2>(test_type_1_pointer_const_ref),
14041407
absl::StrCat("Cannot downcast ", test_type_1.GetTypeName(), " to ",
14051408
CastType2::default_instance().GetTypeName()));
1409+
#else
1410+
(void)test_type_1;
1411+
(void)test_type_1_pointer_const_ref;
1412+
GTEST_SKIP() << "Can't test the failure.";
1413+
#endif
14061414
}
1407-
#endif // GTEST_HAS_DEATH_TEST
14081415

14091416
TEST(LiteTest, DownCastMessageValidType) {
14101417
CastType1 test_type_1;

src/google/protobuf/message_lite.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@
1919
#include <istream>
2020
#include <ostream>
2121
#include <string>
22+
#include <typeinfo>
2223
#include <utility>
2324

25+
#include "absl/base/config.h"
2426
#include "absl/log/absl_check.h"
2527
#include "absl/log/absl_log.h"
2628
#include "absl/strings/cord.h"
@@ -198,6 +200,9 @@ void MessageLite::LogInitializationErrorMessage() const {
198200
namespace internal {
199201

200202
void FailDynamicCast(const MessageLite& from, const MessageLite& to) {
203+
#if defined(ABSL_HAVE_EXCEPTIONS)
204+
throw std::bad_cast();
205+
#endif
201206
const auto to_name = to.GetTypeName();
202207
if (internal::GetClassData(from)->is_dynamic) {
203208
ABSL_LOG(FATAL)

src/google/protobuf/message_unittest.inc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <gmock/gmock.h>
3636
#include "google/protobuf/testing/googletest.h"
3737
#include <gtest/gtest.h>
38+
#include "absl/base/config.h"
3839
#include "absl/log/absl_check.h"
3940
#include "absl/log/scoped_mock_log.h"
4041
#include "absl/strings/cord.h"
@@ -816,11 +817,17 @@ TEST(MESSAGE_TEST_NAME, DynamicCastMessage) {
816817
TEST(MESSAGE_TEST_NAME, DynamicCastMessageInvalidReferenceType) {
817818
UNITTEST::TestAllTypes test_all_types;
818819
const MessageLite& test_all_types_pointer_const_ref = test_all_types;
820+
#if defined(ABSL_HAVE_EXCEPTIONS)
821+
EXPECT_THROW(DynamicCastMessage<UNITTEST::TestRequired>(
822+
test_all_types_pointer_const_ref),
823+
std::bad_cast);
824+
#else
819825
ASSERT_DEATH(
820826
DynamicCastMessage<UNITTEST::TestRequired>(
821827
test_all_types_pointer_const_ref),
822828
absl::StrCat("Cannot downcast ", test_all_types.GetTypeName(), " to ",
823829
UNITTEST::TestRequired::default_instance().GetTypeName()));
830+
#endif
824831
}
825832

826833
TEST(MESSAGE_TEST_NAME, DownCastMessageValidType) {

0 commit comments

Comments
 (0)