Index: third_party/protobuf/src/google/protobuf/extension_set_unittest.cc |
diff --git a/third_party/protobuf/src/google/protobuf/extension_set_unittest.cc b/third_party/protobuf/src/google/protobuf/extension_set_unittest.cc |
index f40fcbc26d9b77c222280b99b6fb129fc181f7ab..d6b823c042749de4b87f725d6e65ebc522bcf10a 100644 |
--- a/third_party/protobuf/src/google/protobuf/extension_set_unittest.cc |
+++ b/third_party/protobuf/src/google/protobuf/extension_set_unittest.cc |
@@ -205,6 +205,74 @@ TEST(ExtensionSetTest, ReleaseExtension) { |
delete released_extension; |
} |
+TEST(ExtensionSetTest, ArenaUnsafeArenaSetAllocatedAndRelease) { |
+ ::google::protobuf::Arena arena; |
+ unittest::TestAllExtensions* message = |
+ ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena); |
+ unittest::ForeignMessage extension; |
+ message->UnsafeArenaSetAllocatedExtension( |
+ unittest::optional_foreign_message_extension, |
+ &extension); |
+ // No copy when set. |
+ unittest::ForeignMessage* mutable_extension = |
+ message->MutableExtension(unittest::optional_foreign_message_extension); |
+ EXPECT_EQ(&extension, mutable_extension); |
+ // No copy when unsafe released. |
+ unittest::ForeignMessage* released_extension = |
+ message->UnsafeArenaReleaseExtension( |
+ unittest::optional_foreign_message_extension); |
+ EXPECT_EQ(&extension, released_extension); |
+ EXPECT_FALSE(message->HasExtension( |
+ unittest::optional_foreign_message_extension)); |
+ // Set the ownership back and let the destructors run. It should not take |
+ // ownership, so this should not crash. |
+ message->UnsafeArenaSetAllocatedExtension( |
+ unittest::optional_foreign_message_extension, |
+ &extension); |
+} |
+ |
+TEST(ExtensionSetTest, UnsafeArenaSetAllocatedAndRelease) { |
+ unittest::TestAllExtensions message; |
+ unittest::ForeignMessage* extension = new unittest::ForeignMessage(); |
+ message.UnsafeArenaSetAllocatedExtension( |
+ unittest::optional_foreign_message_extension, |
+ extension); |
+ // No copy when set. |
+ unittest::ForeignMessage* mutable_extension = |
+ message.MutableExtension(unittest::optional_foreign_message_extension); |
+ EXPECT_EQ(extension, mutable_extension); |
+ // No copy when unsafe released. |
+ unittest::ForeignMessage* released_extension = |
+ message.UnsafeArenaReleaseExtension( |
+ unittest::optional_foreign_message_extension); |
+ EXPECT_EQ(extension, released_extension); |
+ EXPECT_FALSE(message.HasExtension( |
+ unittest::optional_foreign_message_extension)); |
+ // Set the ownership back and let the destructors run. It should take |
+ // ownership, so this should not leak. |
+ message.UnsafeArenaSetAllocatedExtension( |
+ unittest::optional_foreign_message_extension, |
+ extension); |
+} |
+ |
+TEST(ExtensionSetTest, ArenaUnsafeArenaReleaseOfHeapAlloc) { |
+ ::google::protobuf::Arena arena; |
+ unittest::TestAllExtensions* message = |
+ ::google::protobuf::Arena::CreateMessage<unittest::TestAllExtensions>(&arena); |
+ unittest::ForeignMessage* extension = new unittest::ForeignMessage; |
+ message->SetAllocatedExtension( |
+ unittest::optional_foreign_message_extension, |
+ extension); |
+ // The arena should maintain ownership of the heap allocated proto because we |
+ // used UnsafeArenaReleaseExtension. The leak checker will ensure this. |
+ unittest::ForeignMessage* released_extension = |
+ message->UnsafeArenaReleaseExtension( |
+ unittest::optional_foreign_message_extension); |
+ EXPECT_EQ(extension, released_extension); |
+ EXPECT_FALSE(message->HasExtension( |
+ unittest::optional_foreign_message_extension)); |
+} |
+ |
TEST(ExtensionSetTest, CopyFrom) { |
unittest::TestAllExtensions message1, message2; |
@@ -263,7 +331,7 @@ TEST(ExtensionSetTest, SwapExtension) { |
unittest::TestAllExtensions message2; |
TestUtil::SetAllExtensions(&message1); |
- vector<const FieldDescriptor*> fields; |
+ std::vector<const FieldDescriptor*> fields; |
// Swap empty fields. |
const Reflection* reflection = message1.GetReflection(); |
@@ -295,7 +363,7 @@ TEST(ExtensionSetTest, SwapExtensionWithEmpty) { |
TestUtil::SetAllExtensions(&message3); |
const Reflection* reflection = message3.GetReflection(); |
- vector<const FieldDescriptor*> fields; |
+ std::vector<const FieldDescriptor*> fields; |
reflection->ListFields(message3, &fields); |
reflection->SwapFields(&message1, &message2, fields); |
@@ -312,7 +380,7 @@ TEST(ExtensionSetTest, SwapExtensionBothFull) { |
TestUtil::SetAllExtensions(&message2); |
const Reflection* reflection = message1.GetReflection(); |
- vector<const FieldDescriptor*> fields; |
+ std::vector<const FieldDescriptor*> fields; |
reflection->ListFields(message1, &fields); |
reflection->SwapFields(&message1, &message2, fields); |
@@ -422,7 +490,7 @@ TEST(ExtensionSetTest, SwapFieldsOfExtensionBothFullWithArena) { |
TestUtil::SetAllExtensions(message2); |
const Reflection* reflection = message1->GetReflection(); |
- vector<const FieldDescriptor*> fields; |
+ std::vector<const FieldDescriptor*> fields; |
reflection->ListFields(*message1, &fields); |
reflection->SwapFields(message1, message2, fields); |
TestUtil::ExpectAllExtensionsSet(*message1); |
@@ -436,7 +504,7 @@ TEST(ExtensionSetTest, SwapExtensionWithSelf) { |
TestUtil::SetAllExtensions(&message1); |
- vector<const FieldDescriptor*> fields; |
+ std::vector<const FieldDescriptor*> fields; |
const Reflection* reflection = message1.GetReflection(); |
reflection->ListFields(message1, &fields); |
reflection->SwapFields(&message1, &message1, fields); |
@@ -728,7 +796,7 @@ TEST(ExtensionSetTest, SpaceUsedExcludingSelf) { |
} \ |
int expected_size = sizeof(cpptype) * (16 - \ |
kMinRepeatedFieldAllocationSize) + empty_repeated_field_size; \ |
- EXPECT_EQ(expected_size, message.SpaceUsed()) << #type; \ |
+ EXPECT_LE(expected_size, message.SpaceUsed()) << #type; \ |
} while (0) |
TEST_REPEATED_EXTENSIONS_SPACE_USED(int32 , int32 , 101); |