|
| 1 | +diff --git a/src/google/protobuf/port.cc b/src/google/protobuf/port.cc |
| 2 | +index af668e9e2..d60c2b89f 100644 |
| 3 | +--- a/src/google/protobuf/port.cc |
| 4 | ++++ b/src/google/protobuf/port.cc |
| 5 | +@@ -97,14 +97,9 @@ void RealDebugCounter::Register(absl::string_view name) { |
| 6 | + } |
| 7 | + } |
| 8 | + |
| 9 | +-#if defined(__cpp_lib_constexpr_string) && __cpp_lib_constexpr_string >= 201907L |
| 10 | +-PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT const GlobalEmptyString |
| 11 | +- fixed_address_empty_string{}; |
| 12 | +-#else |
| 13 | + PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT |
| 14 | + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 GlobalEmptyString |
| 15 | + fixed_address_empty_string{}; |
| 16 | +-#endif |
| 17 | + |
| 18 | + } // namespace internal |
| 19 | + } // namespace protobuf |
| 20 | +diff --git a/src/google/protobuf/port.h b/src/google/protobuf/port.h |
| 21 | +index 5f9e909a0..386ecc02a 100644 |
| 22 | +--- a/src/google/protobuf/port.h |
| 23 | ++++ b/src/google/protobuf/port.h |
| 24 | +@@ -494,20 +494,27 @@ class NoopDebugCounter { |
| 25 | + // Default empty string object. Don't use this directly. Instead, call |
| 26 | + // GetEmptyString() to get the reference. This empty string is aligned with a |
| 27 | + // minimum alignment of 8 bytes to match the requirement of ArenaStringPtr. |
| 28 | +-#if defined(__cpp_lib_constexpr_string) && __cpp_lib_constexpr_string >= 201907L |
| 29 | ++ |
| 30 | + // Take advantage of C++20 constexpr support in std::string. |
| 31 | +-class alignas(8) GlobalEmptyString { |
| 32 | ++class alignas(8) GlobalEmptyStringConstexpr { |
| 33 | + public: |
| 34 | + const std::string& get() const { return value_; } |
| 35 | + // Nothing to init, or destroy. |
| 36 | + std::string* Init() const { return nullptr; } |
| 37 | + |
| 38 | ++ template <typename T = std::string, bool = (T(), true)> |
| 39 | ++ static constexpr std::true_type HasConstexprDefaultConstructor(int) { |
| 40 | ++ return {}; |
| 41 | ++ } |
| 42 | ++ static constexpr std::false_type HasConstexprDefaultConstructor(char) { |
| 43 | ++ return {}; |
| 44 | ++ } |
| 45 | ++ |
| 46 | + private: |
| 47 | + std::string value_; |
| 48 | + }; |
| 49 | +-PROTOBUF_EXPORT extern const GlobalEmptyString fixed_address_empty_string; |
| 50 | +-#else |
| 51 | +-class alignas(8) GlobalEmptyString { |
| 52 | ++ |
| 53 | ++class alignas(8) GlobalEmptyStringDynamicInit { |
| 54 | + public: |
| 55 | + const std::string& get() const { |
| 56 | + return *reinterpret_cast<const std::string*>(internal::Launder(buffer_)); |
| 57 | +@@ -519,8 +526,12 @@ class alignas(8) GlobalEmptyString { |
| 58 | + private: |
| 59 | + alignas(std::string) char buffer_[sizeof(std::string)]; |
| 60 | + }; |
| 61 | ++ |
| 62 | ++using GlobalEmptyString = std::conditional_t< |
| 63 | ++ GlobalEmptyStringConstexpr::HasConstexprDefaultConstructor(0), |
| 64 | ++ const GlobalEmptyStringConstexpr, GlobalEmptyStringDynamicInit>; |
| 65 | ++ |
| 66 | + PROTOBUF_EXPORT extern GlobalEmptyString fixed_address_empty_string; |
| 67 | +-#endif |
| 68 | + |
| 69 | + } // namespace internal |
| 70 | + } // namespace protobuf |
0 commit comments