Fix #9947: make the ABI identical between debug and non-debug builds

pull/10273/head
Antoine Pitrou 3 years ago committed by Adam Cozzette
parent 2404ea48a0
commit 101b6199f3
  1. 8
      src/google/protobuf/message_lite.cc
  2. 13
      src/google/protobuf/metadata_lite.h

@ -520,18 +520,14 @@ void GenericTypeHandler<std::string>::Merge(const std::string& from,
*to = from; *to = from;
} }
// Non-inline implementations of InternalMetadata routines // Non-inline implementations of InternalMetadata destructor
#if defined(NDEBUG) || defined(_MSC_VER)
// for opt and MSVC builds, the destructor is defined in the header.
#else
// This is moved out of the header because the GOOGLE_DCHECK produces a lot of code. // This is moved out of the header because the GOOGLE_DCHECK produces a lot of code.
InternalMetadata::~InternalMetadata() { void InternalMetadata::CheckedDestruct() {
if (HasMessageOwnedArenaTag()) { if (HasMessageOwnedArenaTag()) {
GOOGLE_DCHECK(!HasUnknownFieldsTag()); GOOGLE_DCHECK(!HasUnknownFieldsTag());
delete reinterpret_cast<Arena*>(ptr_ - kMessageOwnedArenaTagMask); delete reinterpret_cast<Arena*>(ptr_ - kMessageOwnedArenaTagMask);
} }
} }
#endif
// Non-inline variants of std::string specializations for // Non-inline variants of std::string specializations for
// various InternalMetadata routines. // various InternalMetadata routines.

@ -74,15 +74,19 @@ class PROTOBUF_EXPORT InternalMetadata {
GOOGLE_DCHECK(!is_message_owned || arena != nullptr); 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() { ~InternalMetadata() {
#if defined(NDEBUG) || defined(_MSC_VER)
if (HasMessageOwnedArenaTag()) { if (HasMessageOwnedArenaTag()) {
delete reinterpret_cast<Arena*>(ptr_ - kMessageOwnedArenaTagMask); delete reinterpret_cast<Arena*>(ptr_ - kMessageOwnedArenaTagMask);
} }
}
#else #else
~InternalMetadata(); CheckedDestruct();
#endif #endif
}
template <typename T> template <typename T>
void Delete() { void Delete() {
@ -261,6 +265,9 @@ class PROTOBUF_EXPORT InternalMetadata {
PROTOBUF_NOINLINE void DoSwap(T* other) { PROTOBUF_NOINLINE void DoSwap(T* other) {
mutable_unknown_fields<T>()->Swap(other); mutable_unknown_fields<T>()->Swap(other);
} }
// Private helper with debug checks for ~InternalMetadata()
void CheckedDestruct();
}; };
// String Template specializations. // String Template specializations.

Loading…
Cancel
Save