diff --git a/src/google/protobuf/message_lite.cc b/src/google/protobuf/message_lite.cc index 27a8b38bab56..2674b2698e1f 100644 --- a/src/google/protobuf/message_lite.cc +++ b/src/google/protobuf/message_lite.cc @@ -521,18 +521,14 @@ void GenericTypeHandler::Merge(const std::string& from, *to = from; } -// Non-inline implementations of InternalMetadata routines -#if defined(NDEBUG) || defined(_MSC_VER) -// for opt and MSVC builds, the destructor is defined in the header. -#else +// Non-inline implementations of InternalMetadata destructor // This is moved out of the header because the GOOGLE_DCHECK produces a lot of code. -InternalMetadata::~InternalMetadata() { +void InternalMetadata::CheckedDestruct() { if (HasMessageOwnedArenaTag()) { GOOGLE_DCHECK(!HasUnknownFieldsTag()); delete reinterpret_cast(ptr_ - kMessageOwnedArenaTagMask); } } -#endif // Non-inline variants of std::string specializations for // various InternalMetadata routines. diff --git a/src/google/protobuf/metadata_lite.h b/src/google/protobuf/metadata_lite.h index af840e5065c9..d015dc2f9da4 100644 --- a/src/google/protobuf/metadata_lite.h +++ b/src/google/protobuf/metadata_lite.h @@ -77,15 +77,19 @@ class PROTOBUF_EXPORT InternalMetadata { GOOGLE_DCHECK(!is_message_owned || arena != nullptr); } -#if defined(NDEBUG) || defined(_MSC_VER) + // To keep the ABI identical between debug and non-debug builds, + // the destructor is always defined here even though it may delegate + // to a non-inline private method. + // (see https://github.com/protocolbuffers/protobuf/issues/9947) ~InternalMetadata() { +#if defined(NDEBUG) || defined(_MSC_VER) if (HasMessageOwnedArenaTag()) { delete reinterpret_cast(ptr_ - kMessageOwnedArenaTagMask); } - } #else - ~InternalMetadata(); + CheckedDestruct(); #endif + } template void Delete() { @@ -264,6 +268,9 @@ class PROTOBUF_EXPORT InternalMetadata { PROTOBUF_NOINLINE void DoSwap(T* other) { mutable_unknown_fields()->Swap(other); } + + // Private helper with debug checks for ~InternalMetadata() + void CheckedDestruct(); }; // String Template specializations.