diff --git a/src/google/protobuf/compiler/cpp/file.cc b/src/google/protobuf/compiler/cpp/file.cc index e3e0130e93..4b77480997 100644 --- a/src/google/protobuf/compiler/cpp/file.cc +++ b/src/google/protobuf/compiler/cpp/file.cc @@ -529,6 +529,17 @@ void FileGenerator::GenerateSourcePrelude(io::Printer* p) { } } +bool FileGenerator::IsFileDescriptorProto() const { + if (Namespace(file_, options_) != + absl::StrCat("::", ProtobufNamespace(options_))) { + return false; + } + for (int i = 0; i < file_->message_type_count(); ++i) { + if (file_->message_type(i)->name() == "FileDescriptorProto") return true; + } + return false; +} + void FileGenerator::GenerateSourceDefaultInstance(int idx, io::Printer* p) { MessageGenerator* generator = message_generators_[idx].get(); @@ -569,24 +580,50 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx, io::Printer* p) { generator->GenerateConstexprConstructor(p); - p->Emit( - { - {"type", DefaultInstanceType(generator->descriptor(), options_)}, - {"name", DefaultInstanceName(generator->descriptor(), options_)}, - {"class", ClassName(generator->descriptor())}, - }, - R"cc( - struct $type$ { - PROTOBUF_CONSTEXPR $type$() : _instance(::_pbi::ConstantInitialized{}) {} - ~$type$() {} - union { - $class$ _instance; + if (IsFileDescriptorProto()) { + p->Emit( + { + {"type", DefaultInstanceType(generator->descriptor(), options_)}, + {"name", DefaultInstanceName(generator->descriptor(), options_)}, + {"class", ClassName(generator->descriptor())}, + }, + R"cc( + struct $type$ { +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr $type$() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + $type$() {} + void Init() { ::new (&_instance) $class$(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + ~$type$() {} + union { + $class$ _instance; + }; }; - }; - PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT - PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 $type$ $name$; - )cc"); + PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 $type$ $name$; + )cc"); + } else { + p->Emit( + { + {"type", DefaultInstanceType(generator->descriptor(), options_)}, + {"name", DefaultInstanceName(generator->descriptor(), options_)}, + {"class", ClassName(generator->descriptor())}, + }, + R"cc( + struct $type$ { + PROTOBUF_CONSTEXPR $type$() : _instance(::_pbi::ConstantInitialized{}) {} + ~$type$() {} + union { + $class$ _instance; + }; + }; + + PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 $type$ $name$; + )cc"); + } for (int i = 0; i < generator->descriptor()->field_count(); ++i) { const FieldDescriptor* field = generator->descriptor()->field(i); @@ -1109,15 +1146,43 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* p) { // because in some situations that would otherwise pull in a lot of // unnecessary code that can't be stripped by --gc-sections. Descriptor // initialization will still be performed lazily when it's needed. - if (file_->name() == "net/proto2/proto/descriptor.proto") { - return; + if (file_->name() != "net/proto2/proto/descriptor.proto") { + p->Emit({{"dummy", UniqueName("dynamic_init_dummy", file_, options_)}}, + R"cc( + // Force running AddDescriptors() at dynamic initialization time. + PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 + static ::_pbi::AddDescriptorsRunner $dummy$(&$desc_table$); + )cc"); } - p->Emit({{"dummy", UniqueName("dynamic_init_dummy", file_, options_)}}, R"cc( - // Force running AddDescriptors() at dynamic initialization time. - PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 - static ::_pbi::AddDescriptorsRunner $dummy$(&$desc_table$); - )cc"); + // However, we must provide a way to force initialize the default instances + // of FileDescriptorProto which will be used during registration of other + // files. + if (IsFileDescriptorProto()) { + NamespaceOpener ns(p); + ns.ChangeTo(absl::StrCat(ProtobufNamespace(options_), "::internal")); + p->Emit( + {{"dummy", UniqueName("dynamic_init_dummy", file_, options_)}, + {"initializers", absl::StrJoin(message_generators_, "\n", + [&](std::string* out, const auto& gen) { + absl::StrAppend( + out, + DefaultInstanceName( + gen->descriptor(), options_), + ".Init();"); + })}}, + R"cc( + //~ Emit wants an indented line, so give it a comment to strip. +#if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + PROTOBUF_EXPORT void InitializeFileDescriptorDefaultInstancesSlow() { + $initializers$; + } + PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 + static std::true_type $dummy${ + (InitializeFileDescriptorDefaultInstances(), std::true_type{})}; +#endif // !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + )cc"); + } } class FileGenerator::ForwardDeclarations { @@ -1240,6 +1305,16 @@ void FileGenerator::GenerateForwardDeclarations(io::Printer* p) { for (const auto& decl : decls) { decl.second.PrintTopLevelDecl(p, options_); } + + if (IsFileDescriptorProto()) { + ns.ChangeTo(absl::StrCat(ProtobufNamespace(options_), "::internal")); + p->Emit(R"cc( + //~ Emit wants an indented line, so give it a comment to strip. +#if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + PROTOBUF_EXPORT void InitializeFileDescriptorDefaultInstancesSlow(); +#endif // !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + )cc"); + } } void FileGenerator::GenerateLibraryIncludes(io::Printer* p) { diff --git a/src/google/protobuf/compiler/cpp/file.h b/src/google/protobuf/compiler/cpp/file.h index 6514df048f..96cecd77d4 100644 --- a/src/google/protobuf/compiler/cpp/file.h +++ b/src/google/protobuf/compiler/cpp/file.h @@ -168,6 +168,8 @@ class FileGenerator { void GenerateProto2NamespaceEnumSpecializations(io::Printer* p); + bool IsFileDescriptorProto() const; + // Sometimes the names we use in a .proto file happen to be defined as // macros on some platforms (e.g., macro/minor used in plugin.proto are // defined as macros in sys/types.h on FreeBSD and a few other platforms). diff --git a/src/google/protobuf/descriptor.pb.cc b/src/google/protobuf/descriptor.pb.cc index a67c00aa7a..a3c7065995 100644 --- a/src/google/protobuf/descriptor.pb.cc +++ b/src/google/protobuf/descriptor.pb.cc @@ -25,7 +25,12 @@ PROTOBUF_CONSTEXPR FileDescriptorSet::FileDescriptorSet( /*decltype(_impl_.file_)*/{} , /*decltype(_impl_._cached_size_)*/{}} {} struct FileDescriptorSetDefaultTypeInternal { - PROTOBUF_CONSTEXPR FileDescriptorSetDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr FileDescriptorSetDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + FileDescriptorSetDefaultTypeInternal() {} + void Init() { ::new (&_instance) FileDescriptorSet(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~FileDescriptorSetDefaultTypeInternal() {} union { FileDescriptorSet _instance; @@ -66,7 +71,12 @@ PROTOBUF_CONSTEXPR FileDescriptorProto::FileDescriptorProto( , /*decltype(_impl_.options_)*/nullptr , /*decltype(_impl_.source_code_info_)*/nullptr} {} struct FileDescriptorProtoDefaultTypeInternal { - PROTOBUF_CONSTEXPR FileDescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr FileDescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + FileDescriptorProtoDefaultTypeInternal() {} + void Init() { ::new (&_instance) FileDescriptorProto(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~FileDescriptorProtoDefaultTypeInternal() {} union { FileDescriptorProto _instance; @@ -85,7 +95,12 @@ PROTOBUF_CONSTEXPR DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRang , /*decltype(_impl_.end_)*/ 0 } {} struct DescriptorProto_ExtensionRangeDefaultTypeInternal { - PROTOBUF_CONSTEXPR DescriptorProto_ExtensionRangeDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr DescriptorProto_ExtensionRangeDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + DescriptorProto_ExtensionRangeDefaultTypeInternal() {} + void Init() { ::new (&_instance) DescriptorProto_ExtensionRange(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~DescriptorProto_ExtensionRangeDefaultTypeInternal() {} union { DescriptorProto_ExtensionRange _instance; @@ -103,7 +118,12 @@ PROTOBUF_CONSTEXPR DescriptorProto_ReservedRange::DescriptorProto_ReservedRange( , /*decltype(_impl_.end_)*/ 0 } {} struct DescriptorProto_ReservedRangeDefaultTypeInternal { - PROTOBUF_CONSTEXPR DescriptorProto_ReservedRangeDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr DescriptorProto_ReservedRangeDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + DescriptorProto_ReservedRangeDefaultTypeInternal() {} + void Init() { ::new (&_instance) DescriptorProto_ReservedRange(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~DescriptorProto_ReservedRangeDefaultTypeInternal() {} union { DescriptorProto_ReservedRange _instance; @@ -130,7 +150,12 @@ PROTOBUF_CONSTEXPR DescriptorProto::DescriptorProto( , /*decltype(_impl_.options_)*/nullptr} {} struct DescriptorProtoDefaultTypeInternal { - PROTOBUF_CONSTEXPR DescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr DescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + DescriptorProtoDefaultTypeInternal() {} + void Init() { ::new (&_instance) DescriptorProto(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~DescriptorProtoDefaultTypeInternal() {} union { DescriptorProto _instance; @@ -160,7 +185,12 @@ PROTOBUF_CONSTEXPR ExtensionRangeOptions_Declaration::ExtensionRangeOptions_Decl , /*decltype(_impl_.repeated_)*/ false } {} struct ExtensionRangeOptions_DeclarationDefaultTypeInternal { - PROTOBUF_CONSTEXPR ExtensionRangeOptions_DeclarationDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr ExtensionRangeOptions_DeclarationDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + ExtensionRangeOptions_DeclarationDefaultTypeInternal() {} + void Init() { ::new (&_instance) ExtensionRangeOptions_Declaration(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~ExtensionRangeOptions_DeclarationDefaultTypeInternal() {} union { ExtensionRangeOptions_Declaration _instance; @@ -179,7 +209,12 @@ PROTOBUF_CONSTEXPR ExtensionRangeOptions::ExtensionRangeOptions( , /*decltype(_impl_.verification_)*/ 1 } {} struct ExtensionRangeOptionsDefaultTypeInternal { - PROTOBUF_CONSTEXPR ExtensionRangeOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr ExtensionRangeOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + ExtensionRangeOptionsDefaultTypeInternal() {} + void Init() { ::new (&_instance) ExtensionRangeOptions(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~ExtensionRangeOptionsDefaultTypeInternal() {} union { ExtensionRangeOptions _instance; @@ -224,7 +259,12 @@ PROTOBUF_CONSTEXPR FieldDescriptorProto::FieldDescriptorProto( , /*decltype(_impl_.type_)*/ 1 } {} struct FieldDescriptorProtoDefaultTypeInternal { - PROTOBUF_CONSTEXPR FieldDescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr FieldDescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + FieldDescriptorProtoDefaultTypeInternal() {} + void Init() { ::new (&_instance) FieldDescriptorProto(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~FieldDescriptorProtoDefaultTypeInternal() {} union { FieldDescriptorProto _instance; @@ -243,7 +283,12 @@ PROTOBUF_CONSTEXPR OneofDescriptorProto::OneofDescriptorProto( , /*decltype(_impl_.options_)*/nullptr} {} struct OneofDescriptorProtoDefaultTypeInternal { - PROTOBUF_CONSTEXPR OneofDescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr OneofDescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + OneofDescriptorProtoDefaultTypeInternal() {} + void Init() { ::new (&_instance) OneofDescriptorProto(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~OneofDescriptorProtoDefaultTypeInternal() {} union { OneofDescriptorProto _instance; @@ -261,7 +306,12 @@ PROTOBUF_CONSTEXPR EnumDescriptorProto_EnumReservedRange::EnumDescriptorProto_En , /*decltype(_impl_.end_)*/ 0 } {} struct EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal { - PROTOBUF_CONSTEXPR EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal() {} + void Init() { ::new (&_instance) EnumDescriptorProto_EnumReservedRange(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~EnumDescriptorProto_EnumReservedRangeDefaultTypeInternal() {} union { EnumDescriptorProto_EnumReservedRange _instance; @@ -283,7 +333,12 @@ PROTOBUF_CONSTEXPR EnumDescriptorProto::EnumDescriptorProto( , /*decltype(_impl_.options_)*/nullptr} {} struct EnumDescriptorProtoDefaultTypeInternal { - PROTOBUF_CONSTEXPR EnumDescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr EnumDescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + EnumDescriptorProtoDefaultTypeInternal() {} + void Init() { ::new (&_instance) EnumDescriptorProto(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~EnumDescriptorProtoDefaultTypeInternal() {} union { EnumDescriptorProto _instance; @@ -304,7 +359,12 @@ PROTOBUF_CONSTEXPR EnumValueDescriptorProto::EnumValueDescriptorProto( , /*decltype(_impl_.number_)*/ 0 } {} struct EnumValueDescriptorProtoDefaultTypeInternal { - PROTOBUF_CONSTEXPR EnumValueDescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr EnumValueDescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + EnumValueDescriptorProtoDefaultTypeInternal() {} + void Init() { ::new (&_instance) EnumValueDescriptorProto(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~EnumValueDescriptorProtoDefaultTypeInternal() {} union { EnumValueDescriptorProto _instance; @@ -324,7 +384,12 @@ PROTOBUF_CONSTEXPR ServiceDescriptorProto::ServiceDescriptorProto( , /*decltype(_impl_.options_)*/nullptr} {} struct ServiceDescriptorProtoDefaultTypeInternal { - PROTOBUF_CONSTEXPR ServiceDescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr ServiceDescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + ServiceDescriptorProtoDefaultTypeInternal() {} + void Init() { ::new (&_instance) ServiceDescriptorProto(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~ServiceDescriptorProtoDefaultTypeInternal() {} union { ServiceDescriptorProto _instance; @@ -355,7 +420,12 @@ PROTOBUF_CONSTEXPR MethodDescriptorProto::MethodDescriptorProto( , /*decltype(_impl_.server_streaming_)*/ false } {} struct MethodDescriptorProtoDefaultTypeInternal { - PROTOBUF_CONSTEXPR MethodDescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr MethodDescriptorProtoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + MethodDescriptorProtoDefaultTypeInternal() {} + void Init() { ::new (&_instance) MethodDescriptorProto(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~MethodDescriptorProtoDefaultTypeInternal() {} union { MethodDescriptorProto _instance; @@ -431,7 +501,12 @@ PROTOBUF_CONSTEXPR FileOptions::FileOptions( , /*decltype(_impl_.cc_enable_arenas_)*/ true } {} struct FileOptionsDefaultTypeInternal { - PROTOBUF_CONSTEXPR FileOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr FileOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + FileOptionsDefaultTypeInternal() {} + void Init() { ::new (&_instance) FileOptions(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~FileOptionsDefaultTypeInternal() {} union { FileOptions _instance; @@ -457,7 +532,12 @@ PROTOBUF_CONSTEXPR MessageOptions::MessageOptions( , /*decltype(_impl_.deprecated_legacy_json_field_conflicts_)*/ false } {} struct MessageOptionsDefaultTypeInternal { - PROTOBUF_CONSTEXPR MessageOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr MessageOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + MessageOptionsDefaultTypeInternal() {} + void Init() { ::new (&_instance) MessageOptions(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~MessageOptionsDefaultTypeInternal() {} union { MessageOptions _instance; @@ -495,7 +575,12 @@ PROTOBUF_CONSTEXPR FieldOptions::FieldOptions( , /*decltype(_impl_.target_obsolete_do_not_use_)*/ 0 } {} struct FieldOptionsDefaultTypeInternal { - PROTOBUF_CONSTEXPR FieldOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr FieldOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + FieldOptionsDefaultTypeInternal() {} + void Init() { ::new (&_instance) FieldOptions(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~FieldOptionsDefaultTypeInternal() {} union { FieldOptions _instance; @@ -510,7 +595,12 @@ PROTOBUF_CONSTEXPR OneofOptions::OneofOptions( , /*decltype(_impl_.uninterpreted_option_)*/{} , /*decltype(_impl_._cached_size_)*/{}} {} struct OneofOptionsDefaultTypeInternal { - PROTOBUF_CONSTEXPR OneofOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr OneofOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + OneofOptionsDefaultTypeInternal() {} + void Init() { ::new (&_instance) OneofOptions(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~OneofOptionsDefaultTypeInternal() {} union { OneofOptions _instance; @@ -532,7 +622,12 @@ PROTOBUF_CONSTEXPR EnumOptions::EnumOptions( , /*decltype(_impl_.deprecated_legacy_json_field_conflicts_)*/ false } {} struct EnumOptionsDefaultTypeInternal { - PROTOBUF_CONSTEXPR EnumOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr EnumOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + EnumOptionsDefaultTypeInternal() {} + void Init() { ::new (&_instance) EnumOptions(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~EnumOptionsDefaultTypeInternal() {} union { EnumOptions _instance; @@ -550,7 +645,12 @@ PROTOBUF_CONSTEXPR EnumValueOptions::EnumValueOptions( , /*decltype(_impl_.deprecated_)*/ false } {} struct EnumValueOptionsDefaultTypeInternal { - PROTOBUF_CONSTEXPR EnumValueOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr EnumValueOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + EnumValueOptionsDefaultTypeInternal() {} + void Init() { ::new (&_instance) EnumValueOptions(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~EnumValueOptionsDefaultTypeInternal() {} union { EnumValueOptions _instance; @@ -568,7 +668,12 @@ PROTOBUF_CONSTEXPR ServiceOptions::ServiceOptions( , /*decltype(_impl_.deprecated_)*/ false } {} struct ServiceOptionsDefaultTypeInternal { - PROTOBUF_CONSTEXPR ServiceOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr ServiceOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + ServiceOptionsDefaultTypeInternal() {} + void Init() { ::new (&_instance) ServiceOptions(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~ServiceOptionsDefaultTypeInternal() {} union { ServiceOptions _instance; @@ -588,7 +693,12 @@ PROTOBUF_CONSTEXPR MethodOptions::MethodOptions( , /*decltype(_impl_.idempotency_level_)*/ 0 } {} struct MethodOptionsDefaultTypeInternal { - PROTOBUF_CONSTEXPR MethodOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr MethodOptionsDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + MethodOptionsDefaultTypeInternal() {} + void Init() { ::new (&_instance) MethodOptions(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~MethodOptionsDefaultTypeInternal() {} union { MethodOptions _instance; @@ -608,7 +718,12 @@ PROTOBUF_CONSTEXPR UninterpretedOption_NamePart::UninterpretedOption_NamePart( , /*decltype(_impl_.is_extension_)*/ false } {} struct UninterpretedOption_NamePartDefaultTypeInternal { - PROTOBUF_CONSTEXPR UninterpretedOption_NamePartDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr UninterpretedOption_NamePartDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + UninterpretedOption_NamePartDefaultTypeInternal() {} + void Init() { ::new (&_instance) UninterpretedOption_NamePart(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~UninterpretedOption_NamePartDefaultTypeInternal() {} union { UninterpretedOption_NamePart _instance; @@ -641,7 +756,12 @@ PROTOBUF_CONSTEXPR UninterpretedOption::UninterpretedOption( , /*decltype(_impl_.double_value_)*/ 0 } {} struct UninterpretedOptionDefaultTypeInternal { - PROTOBUF_CONSTEXPR UninterpretedOptionDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr UninterpretedOptionDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + UninterpretedOptionDefaultTypeInternal() {} + void Init() { ::new (&_instance) UninterpretedOption(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~UninterpretedOptionDefaultTypeInternal() {} union { UninterpretedOption _instance; @@ -670,7 +790,12 @@ PROTOBUF_CONSTEXPR SourceCodeInfo_Location::SourceCodeInfo_Location( } } {} struct SourceCodeInfo_LocationDefaultTypeInternal { - PROTOBUF_CONSTEXPR SourceCodeInfo_LocationDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr SourceCodeInfo_LocationDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + SourceCodeInfo_LocationDefaultTypeInternal() {} + void Init() { ::new (&_instance) SourceCodeInfo_Location(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~SourceCodeInfo_LocationDefaultTypeInternal() {} union { SourceCodeInfo_Location _instance; @@ -684,7 +809,12 @@ PROTOBUF_CONSTEXPR SourceCodeInfo::SourceCodeInfo( /*decltype(_impl_.location_)*/{} , /*decltype(_impl_._cached_size_)*/{}} {} struct SourceCodeInfoDefaultTypeInternal { - PROTOBUF_CONSTEXPR SourceCodeInfoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr SourceCodeInfoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + SourceCodeInfoDefaultTypeInternal() {} + void Init() { ::new (&_instance) SourceCodeInfo(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~SourceCodeInfoDefaultTypeInternal() {} union { SourceCodeInfo _instance; @@ -711,7 +841,12 @@ PROTOBUF_CONSTEXPR GeneratedCodeInfo_Annotation::GeneratedCodeInfo_Annotation( , /*decltype(_impl_.semantic_)*/ 0 } {} struct GeneratedCodeInfo_AnnotationDefaultTypeInternal { - PROTOBUF_CONSTEXPR GeneratedCodeInfo_AnnotationDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr GeneratedCodeInfo_AnnotationDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + GeneratedCodeInfo_AnnotationDefaultTypeInternal() {} + void Init() { ::new (&_instance) GeneratedCodeInfo_Annotation(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~GeneratedCodeInfo_AnnotationDefaultTypeInternal() {} union { GeneratedCodeInfo_Annotation _instance; @@ -725,7 +860,12 @@ PROTOBUF_CONSTEXPR GeneratedCodeInfo::GeneratedCodeInfo( /*decltype(_impl_.annotation_)*/{} , /*decltype(_impl_._cached_size_)*/{}} {} struct GeneratedCodeInfoDefaultTypeInternal { - PROTOBUF_CONSTEXPR GeneratedCodeInfoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#if defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + constexpr GeneratedCodeInfoDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} +#else // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + GeneratedCodeInfoDefaultTypeInternal() {} + void Init() { ::new (&_instance) GeneratedCodeInfo(); }; +#endif // defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) ~GeneratedCodeInfoDefaultTypeInternal() {} union { GeneratedCodeInfo _instance; @@ -1532,6 +1672,47 @@ PROTOBUF_ATTRIBUTE_INIT_PRIORITY2 static ::_pbi::AddDescriptorsRunner dynamic_init_dummy_google_2fprotobuf_2fdescriptor_2eproto(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto); namespace google { namespace protobuf { +namespace internal { +#if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) +PROTOBUF_EXPORT void InitializeFileDescriptorDefaultInstancesSlow() { + _FileDescriptorSet_default_instance_.Init(); +_FileDescriptorProto_default_instance_.Init(); +_DescriptorProto_ExtensionRange_default_instance_.Init(); +_DescriptorProto_ReservedRange_default_instance_.Init(); +_DescriptorProto_default_instance_.Init(); +_ExtensionRangeOptions_Declaration_default_instance_.Init(); +_ExtensionRangeOptions_default_instance_.Init(); +_FieldDescriptorProto_default_instance_.Init(); +_OneofDescriptorProto_default_instance_.Init(); +_EnumDescriptorProto_EnumReservedRange_default_instance_.Init(); +_EnumDescriptorProto_default_instance_.Init(); +_EnumValueDescriptorProto_default_instance_.Init(); +_ServiceDescriptorProto_default_instance_.Init(); +_MethodDescriptorProto_default_instance_.Init(); +_FileOptions_default_instance_.Init(); +_MessageOptions_default_instance_.Init(); +_FieldOptions_default_instance_.Init(); +_OneofOptions_default_instance_.Init(); +_EnumOptions_default_instance_.Init(); +_EnumValueOptions_default_instance_.Init(); +_ServiceOptions_default_instance_.Init(); +_MethodOptions_default_instance_.Init(); +_UninterpretedOption_NamePart_default_instance_.Init(); +_UninterpretedOption_default_instance_.Init(); +_SourceCodeInfo_Location_default_instance_.Init(); +_SourceCodeInfo_default_instance_.Init(); +_GeneratedCodeInfo_Annotation_default_instance_.Init(); +_GeneratedCodeInfo_default_instance_.Init();; +} +PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 +static std::true_type dynamic_init_dummy_google_2fprotobuf_2fdescriptor_2eproto{ + (InitializeFileDescriptorDefaultInstances(), std::true_type{})}; +#endif // !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) +} // namespace internal +} // namespace protobuf +} // namespace google +namespace google { +namespace protobuf { const ::google::protobuf::EnumDescriptor* ExtensionRangeOptions_VerificationState_descriptor() { ::google::protobuf::internal::AssignDescriptors(&descriptor_table_google_2fprotobuf_2fdescriptor_2eproto); return file_level_enum_descriptors_google_2fprotobuf_2fdescriptor_2eproto[0]; diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index 9d5ef15803..56a8c99b0f 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -195,6 +195,11 @@ template <> PROTOBUF_EXPORT ::google::protobuf::UninterpretedOption* Arena::CreateMaybeMessage<::google::protobuf::UninterpretedOption>(Arena*); template <> PROTOBUF_EXPORT ::google::protobuf::UninterpretedOption_NamePart* Arena::CreateMaybeMessage<::google::protobuf::UninterpretedOption_NamePart>(Arena*); +namespace internal { +#if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) +PROTOBUF_EXPORT void InitializeFileDescriptorDefaultInstancesSlow(); +#endif // !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) +} // namespace internal } // namespace protobuf } // namespace google diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 626672b515..bd3b4e07ce 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -103,6 +103,14 @@ Message* MaybeForceCopy(Arena* arena, Message* msg) { namespace internal { +void InitializeFileDescriptorDefaultInstances() { +#if !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) + static std::true_type init = + (InitializeFileDescriptorDefaultInstancesSlow(), std::true_type{}); + (void)init; +#endif // !defined(PROTOBUF_CONSTINIT_DEFAULT_INSTANCES) +} + bool ParseNamedEnum(const EnumDescriptor* descriptor, absl::string_view name, int* value) { const EnumValueDescriptor* d = descriptor->FindValueByName(name); @@ -3570,6 +3578,7 @@ void AssignDescriptorsImpl(const DescriptorTable* table, bool eager) { void AddDescriptorsImpl(const DescriptorTable* table) { // Reflection refers to the default fields so make sure they are initialized. internal::InitProtobufDefaults(); + internal::InitializeFileDescriptorDefaultInstances(); // Ensure all dependent descriptors are registered to the generated descriptor // pool and message factory. diff --git a/src/google/protobuf/generated_message_reflection.h b/src/google/protobuf/generated_message_reflection.h index e0d87b33aa..61851566c1 100644 --- a/src/google/protobuf/generated_message_reflection.h +++ b/src/google/protobuf/generated_message_reflection.h @@ -355,6 +355,8 @@ PROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8_t* base, uint32_t has_offset, io::CodedOutputStream* output); +PROTOBUF_EXPORT void InitializeFileDescriptorDefaultInstances(); + struct PROTOBUF_EXPORT AddDescriptorsRunner { explicit AddDescriptorsRunner(const DescriptorTable* table); }; diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index f4c0bc59dc..082e012c1c 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -676,6 +676,7 @@ static_assert(PROTOBUF_CPLUSPLUS_MIN(201402L), "Protobuf only supports C++14 and # if defined(__cpp_constinit) && !defined(__CYGWIN__) # define PROTOBUF_CONSTINIT constinit # define PROTOBUF_CONSTEXPR constexpr +# define PROTOBUF_CONSTINIT_DEFAULT_INSTANCES // Some older Clang versions incorrectly raise an error about // constant-initializing weak default instance pointers. Versions 12.0 and // higher seem to work, except that XCode 12.5.1 shows the error even though it @@ -686,9 +687,11 @@ static_assert(PROTOBUF_CPLUSPLUS_MIN(201402L), "Protobuf only supports C++14 and (!defined(__APPLE__) && PROTOBUF_CLANG_MIN(12, 0))) # define PROTOBUF_CONSTINIT [[clang::require_constant_initialization]] # define PROTOBUF_CONSTEXPR constexpr +# define PROTOBUF_CONSTINIT_DEFAULT_INSTANCES # elif PROTOBUF_GNUC_MIN(12, 2) # define PROTOBUF_CONSTINIT __constinit # define PROTOBUF_CONSTEXPR constexpr +# define PROTOBUF_CONSTINIT_DEFAULT_INSTANCES # endif #endif diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc index c8aaabca26..89bf2f2034 100644 --- a/src/google/protobuf/port_undef.inc +++ b/src/google/protobuf/port_undef.inc @@ -91,6 +91,7 @@ #undef PROTOBUF_BIG_ENDIAN #undef PROTOBUF_CONSTINIT #undef PROTOBUF_CONSTEXPR +#undef PROTOBUF_CONSTINIT_DEFAULT_INSTANCES #undef PROTOBUF_ATTRIBUTE_WEAK #undef PROTOBUF_HAVE_ATTRIBUTE_WEAK #undef PROTOBUF_ATTRIBUTE_NO_DESTROY