diff --git a/src/google/protobuf/compiler/cpp/field.cc b/src/google/protobuf/compiler/cpp/field.cc index 47ae1ed27e59..e5d37f849a5d 100644 --- a/src/google/protobuf/compiler/cpp/field.cc +++ b/src/google/protobuf/compiler/cpp/field.cc @@ -85,6 +85,11 @@ std::vector FieldVars(const FieldDescriptor* field, const Options& opts) { {"{", ""}, {"}", ""}, + // For TSan validation. + {"TsanDetectConcurrentMutation", + "PROTOBUF_TSAN_WRITE(&_internal_metadata_)"}, + {"TsanDetectConcurrentRead", "PROTOBUF_TSAN_READ(&_internal_metadata_)"}, + // Old-style names. {"field", FieldMemberName(field, split)}, {"declared_type", DeclaredTypeMethodName(field->type())}, diff --git a/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc b/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc index d88f2d08b629..6c566c472fd1 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/enum_field.cc @@ -388,9 +388,11 @@ void RepeatedEnum::GenerateInlineAccessorDefinitions(io::Printer* p) const { return _internal_mutable_$name$(); } inline const $pb$::RepeatedField& $Msg$::_internal_$name$() const { + $TsanDetectConcurrentRead$; return $field_$; } inline $pb$::RepeatedField* $Msg$::_internal_mutable_$name$() { + $TsanDetectConcurrentMutation$; return &$field_$; } )cc"); diff --git a/src/google/protobuf/compiler/cpp/field_generators/map_field.cc b/src/google/protobuf/compiler/cpp/field_generators/map_field.cc index 26b3d9bdab38..c11fb4e5c99e 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/map_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/map_field.cc @@ -218,6 +218,7 @@ void Map::GenerateAccessorDeclarations(io::Printer* p) const { void Map::GenerateInlineAccessorDefinitions(io::Printer* p) const { p->Emit(R"cc( inline const $Map$& $Msg$::_internal_$name$() const { + $TsanDetectConcurrentRead$; return $field_$.GetMap(); } inline const $Map$& $Msg$::$name$() const { @@ -227,6 +228,7 @@ void Map::GenerateInlineAccessorDefinitions(io::Printer* p) const { } inline $Map$* $Msg$::_internal_mutable_$name$() { $PrepareSplitMessageForWrite$; + $TsanDetectConcurrentMutation$; return $field_$.MutableMap(); } inline $Map$* $Msg$::mutable_$name$() { diff --git a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc index e0965d9e5d8f..3c3798ea966c 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/message_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/message_field.cc @@ -826,10 +826,12 @@ void RepeatedMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const { p->Emit(R"cc( inline const $pb$::RepeatedPtrField<$Submsg$>& $classname$::_internal_$name$() const { + $TsanDetectConcurrentRead$; return $field$$.weak$; } inline $pb$::RepeatedPtrField<$Submsg$>* $classname$::_internal_mutable_$name$() { + $TsanDetectConcurrentMutation$; return &$field$$.weak$; } )cc"); @@ -837,10 +839,12 @@ void RepeatedMessage::GenerateInlineAccessorDefinitions(io::Printer* p) const { p->Emit(R"cc( inline const $pb$::WeakRepeatedPtrField<$Submsg$>& $Msg$::_internal_weak_$name$() const { + $TsanDetectConcurrentRead$; return $field$; } inline $pb$::WeakRepeatedPtrField<$Submsg$>* $Msg$::_internal_mutable_weak_$name$() { + $TsanDetectConcurrentMutation$; return &$field$; } )cc"); diff --git a/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc b/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc index 66d138b05923..64918b62ab7f 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/primitive_field.cc @@ -455,9 +455,11 @@ void RepeatedPrimitive::GenerateInlineAccessorDefinitions( } inline const $pb$::RepeatedField<$Type$>& $Msg$::_internal_$name$() const { + $TsanDetectConcurrentRead$; return $field_$; } inline $pb$::RepeatedField<$Type$>* $Msg$::_internal_mutable_$name$() { + $TsanDetectConcurrentMutation$; return &$field_$; } )cc"); diff --git a/src/google/protobuf/compiler/cpp/field_generators/string_field.cc b/src/google/protobuf/compiler/cpp/field_generators/string_field.cc index 7beea973dc0b..e92f20c00caa 100644 --- a/src/google/protobuf/compiler/cpp/field_generators/string_field.cc +++ b/src/google/protobuf/compiler/cpp/field_generators/string_field.cc @@ -893,10 +893,12 @@ void RepeatedString::GenerateInlineAccessorDefinitions(io::Printer* p) const { } inline const ::$proto_ns$::RepeatedPtrField& $Msg$::_internal_$name$() const { + $TsanDetectConcurrentRead$; return $field_$; } inline ::$proto_ns$::RepeatedPtrField* $Msg$::_internal_mutable_$name$() { + $TsanDetectConcurrentMutation$; return &$field_$; } )cc"); diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 153feda757bb..a20b8b84fc09 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -1239,10 +1239,12 @@ inline ::google::protobuf::RepeatedPtrField* CodeGeneratorRequest:: } inline const ::google::protobuf::RepeatedPtrField& CodeGeneratorRequest::_internal_file_to_generate() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.file_to_generate_; } inline ::google::protobuf::RepeatedPtrField* CodeGeneratorRequest::_internal_mutable_file_to_generate() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.file_to_generate_; } @@ -1341,10 +1343,12 @@ CodeGeneratorRequest::proto_file() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& CodeGeneratorRequest::_internal_proto_file() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.proto_file_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* CodeGeneratorRequest::_internal_mutable_proto_file() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.proto_file_; } @@ -1844,10 +1848,12 @@ CodeGeneratorResponse::file() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::compiler::CodeGeneratorResponse_File>& CodeGeneratorResponse::_internal_file() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.file_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::compiler::CodeGeneratorResponse_File>* CodeGeneratorResponse::_internal_mutable_file() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.file_; } diff --git a/src/google/protobuf/descriptor.pb.h b/src/google/protobuf/descriptor.pb.h index 86382f6ee1e7..2ddcf553adfc 100644 --- a/src/google/protobuf/descriptor.pb.h +++ b/src/google/protobuf/descriptor.pb.h @@ -8704,10 +8704,12 @@ FileDescriptorSet::file() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>& FileDescriptorSet::_internal_file() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.file_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FileDescriptorProto>* FileDescriptorSet::_internal_mutable_file() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.file_; } @@ -8921,10 +8923,12 @@ inline ::google::protobuf::RepeatedPtrField* FileDescriptorProto::m } inline const ::google::protobuf::RepeatedPtrField& FileDescriptorProto::_internal_dependency() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.dependency_; } inline ::google::protobuf::RepeatedPtrField* FileDescriptorProto::_internal_mutable_dependency() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.dependency_; } @@ -8960,9 +8964,11 @@ inline ::google::protobuf::RepeatedField<::int32_t>* FileDescriptorProto::mutabl } inline const ::google::protobuf::RepeatedField<::int32_t>& FileDescriptorProto::_internal_public_dependency() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.public_dependency_; } inline ::google::protobuf::RepeatedField<::int32_t>* FileDescriptorProto::_internal_mutable_public_dependency() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.public_dependency_; } @@ -8998,9 +9004,11 @@ inline ::google::protobuf::RepeatedField<::int32_t>* FileDescriptorProto::mutabl } inline const ::google::protobuf::RepeatedField<::int32_t>& FileDescriptorProto::_internal_weak_dependency() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.weak_dependency_; } inline ::google::protobuf::RepeatedField<::int32_t>* FileDescriptorProto::_internal_mutable_weak_dependency() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.weak_dependency_; } @@ -9039,10 +9047,12 @@ FileDescriptorProto::message_type() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>& FileDescriptorProto::_internal_message_type() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.message_type_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>* FileDescriptorProto::_internal_mutable_message_type() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.message_type_; } @@ -9081,10 +9091,12 @@ FileDescriptorProto::enum_type() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>& FileDescriptorProto::_internal_enum_type() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.enum_type_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>* FileDescriptorProto::_internal_mutable_enum_type() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.enum_type_; } @@ -9123,10 +9135,12 @@ FileDescriptorProto::service() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::ServiceDescriptorProto>& FileDescriptorProto::_internal_service() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.service_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::ServiceDescriptorProto>* FileDescriptorProto::_internal_mutable_service() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.service_; } @@ -9165,10 +9179,12 @@ FileDescriptorProto::extension() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>& FileDescriptorProto::_internal_extension() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.extension_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* FileDescriptorProto::_internal_mutable_extension() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.extension_; } @@ -9778,10 +9794,12 @@ DescriptorProto::field() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>& DescriptorProto::_internal_field() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.field_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* DescriptorProto::_internal_mutable_field() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.field_; } @@ -9820,10 +9838,12 @@ DescriptorProto::extension() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>& DescriptorProto::_internal_extension() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.extension_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::FieldDescriptorProto>* DescriptorProto::_internal_mutable_extension() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.extension_; } @@ -9862,10 +9882,12 @@ DescriptorProto::nested_type() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>& DescriptorProto::_internal_nested_type() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.nested_type_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto>* DescriptorProto::_internal_mutable_nested_type() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.nested_type_; } @@ -9904,10 +9926,12 @@ DescriptorProto::enum_type() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>& DescriptorProto::_internal_enum_type() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.enum_type_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto>* DescriptorProto::_internal_mutable_enum_type() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.enum_type_; } @@ -9946,10 +9970,12 @@ DescriptorProto::extension_range() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ExtensionRange>& DescriptorProto::_internal_extension_range() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.extension_range_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ExtensionRange>* DescriptorProto::_internal_mutable_extension_range() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.extension_range_; } @@ -9988,10 +10014,12 @@ DescriptorProto::oneof_decl() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::OneofDescriptorProto>& DescriptorProto::_internal_oneof_decl() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.oneof_decl_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::OneofDescriptorProto>* DescriptorProto::_internal_mutable_oneof_decl() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.oneof_decl_; } @@ -10120,10 +10148,12 @@ DescriptorProto::reserved_range() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ReservedRange>& DescriptorProto::_internal_reserved_range() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.reserved_range_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::DescriptorProto_ReservedRange>* DescriptorProto::_internal_mutable_reserved_range() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.reserved_range_; } @@ -10207,10 +10237,12 @@ inline ::google::protobuf::RepeatedPtrField* DescriptorProto::mutab } inline const ::google::protobuf::RepeatedPtrField& DescriptorProto::_internal_reserved_name() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.reserved_name_; } inline ::google::protobuf::RepeatedPtrField* DescriptorProto::_internal_mutable_reserved_name() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.reserved_name_; } @@ -10483,10 +10515,12 @@ ExtensionRangeOptions::uninterpreted_option() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& ExtensionRangeOptions::_internal_uninterpreted_option() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.uninterpreted_option_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* ExtensionRangeOptions::_internal_mutable_uninterpreted_option() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.uninterpreted_option_; } @@ -10525,10 +10559,12 @@ ExtensionRangeOptions::declaration() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::ExtensionRangeOptions_Declaration>& ExtensionRangeOptions::_internal_declaration() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.declaration_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::ExtensionRangeOptions_Declaration>* ExtensionRangeOptions::_internal_mutable_declaration() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.declaration_; } @@ -11407,10 +11443,12 @@ EnumDescriptorProto::value() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumValueDescriptorProto>& EnumDescriptorProto::_internal_value() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.value_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumValueDescriptorProto>* EnumDescriptorProto::_internal_mutable_value() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.value_; } @@ -11539,10 +11577,12 @@ EnumDescriptorProto::reserved_range() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto_EnumReservedRange>& EnumDescriptorProto::_internal_reserved_range() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.reserved_range_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::EnumDescriptorProto_EnumReservedRange>* EnumDescriptorProto::_internal_mutable_reserved_range() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.reserved_range_; } @@ -11626,10 +11666,12 @@ inline ::google::protobuf::RepeatedPtrField* EnumDescriptorProto::m } inline const ::google::protobuf::RepeatedPtrField& EnumDescriptorProto::_internal_reserved_name() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.reserved_name_; } inline ::google::protobuf::RepeatedPtrField* EnumDescriptorProto::_internal_mutable_reserved_name() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.reserved_name_; } @@ -11917,10 +11959,12 @@ ServiceDescriptorProto::method() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::MethodDescriptorProto>& ServiceDescriptorProto::_internal_method() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.method_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::MethodDescriptorProto>* ServiceDescriptorProto::_internal_mutable_method() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.method_; } @@ -13267,10 +13311,12 @@ FileOptions::uninterpreted_option() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& FileOptions::_internal_uninterpreted_option() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.uninterpreted_option_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* FileOptions::_internal_mutable_uninterpreted_option() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.uninterpreted_option_; } @@ -13438,10 +13484,12 @@ MessageOptions::uninterpreted_option() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& MessageOptions::_internal_uninterpreted_option() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.uninterpreted_option_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* MessageOptions::_internal_mutable_uninterpreted_option() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.uninterpreted_option_; } @@ -13710,9 +13758,11 @@ inline ::google::protobuf::RepeatedField* FieldOptions::mutable_targets() { return _internal_mutable_targets(); } inline const ::google::protobuf::RepeatedField& FieldOptions::_internal_targets() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.targets_; } inline ::google::protobuf::RepeatedField* FieldOptions::_internal_mutable_targets() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.targets_; } @@ -13751,10 +13801,12 @@ FieldOptions::uninterpreted_option() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& FieldOptions::_internal_uninterpreted_option() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.uninterpreted_option_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* FieldOptions::_internal_mutable_uninterpreted_option() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.uninterpreted_option_; } @@ -13823,10 +13875,12 @@ OneofOptions::uninterpreted_option() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& OneofOptions::_internal_uninterpreted_option() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.uninterpreted_option_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* OneofOptions::_internal_mutable_uninterpreted_option() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.uninterpreted_option_; } @@ -13944,10 +13998,12 @@ EnumOptions::uninterpreted_option() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& EnumOptions::_internal_uninterpreted_option() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.uninterpreted_option_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* EnumOptions::_internal_mutable_uninterpreted_option() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.uninterpreted_option_; } @@ -14040,10 +14096,12 @@ EnumValueOptions::uninterpreted_option() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& EnumValueOptions::_internal_uninterpreted_option() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.uninterpreted_option_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* EnumValueOptions::_internal_mutable_uninterpreted_option() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.uninterpreted_option_; } @@ -14111,10 +14169,12 @@ ServiceOptions::uninterpreted_option() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& ServiceOptions::_internal_uninterpreted_option() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.uninterpreted_option_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* ServiceOptions::_internal_mutable_uninterpreted_option() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.uninterpreted_option_; } @@ -14208,10 +14268,12 @@ MethodOptions::uninterpreted_option() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>& MethodOptions::_internal_uninterpreted_option() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.uninterpreted_option_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption>* MethodOptions::_internal_mutable_uninterpreted_option() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.uninterpreted_option_; } @@ -14346,10 +14408,12 @@ UninterpretedOption::name() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption_NamePart>& UninterpretedOption::_internal_name() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.name_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::UninterpretedOption_NamePart>* UninterpretedOption::_internal_mutable_name() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.name_; } @@ -14653,9 +14717,11 @@ inline ::google::protobuf::RepeatedField<::int32_t>* SourceCodeInfo_Location::mu } inline const ::google::protobuf::RepeatedField<::int32_t>& SourceCodeInfo_Location::_internal_path() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.path_; } inline ::google::protobuf::RepeatedField<::int32_t>* SourceCodeInfo_Location::_internal_mutable_path() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.path_; } @@ -14691,9 +14757,11 @@ inline ::google::protobuf::RepeatedField<::int32_t>* SourceCodeInfo_Location::mu } inline const ::google::protobuf::RepeatedField<::int32_t>& SourceCodeInfo_Location::_internal_span() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.span_; } inline ::google::protobuf::RepeatedField<::int32_t>* SourceCodeInfo_Location::_internal_mutable_span() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.span_; } @@ -14903,10 +14971,12 @@ inline ::google::protobuf::RepeatedPtrField* SourceCodeInfo_Locatio } inline const ::google::protobuf::RepeatedPtrField& SourceCodeInfo_Location::_internal_leading_detached_comments() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.leading_detached_comments_; } inline ::google::protobuf::RepeatedPtrField* SourceCodeInfo_Location::_internal_mutable_leading_detached_comments() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.leading_detached_comments_; } @@ -14949,10 +15019,12 @@ SourceCodeInfo::location() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::SourceCodeInfo_Location>& SourceCodeInfo::_internal_location() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.location_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::SourceCodeInfo_Location>* SourceCodeInfo::_internal_mutable_location() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.location_; } @@ -14992,9 +15064,11 @@ inline ::google::protobuf::RepeatedField<::int32_t>* GeneratedCodeInfo_Annotatio } inline const ::google::protobuf::RepeatedField<::int32_t>& GeneratedCodeInfo_Annotation::_internal_path() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.path_; } inline ::google::protobuf::RepeatedField<::int32_t>* GeneratedCodeInfo_Annotation::_internal_mutable_path() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.path_; } @@ -15176,10 +15250,12 @@ GeneratedCodeInfo::annotation() const { } inline const ::google::protobuf::RepeatedPtrField<::google::protobuf::GeneratedCodeInfo_Annotation>& GeneratedCodeInfo::_internal_annotation() const { + PROTOBUF_TSAN_READ(&_internal_metadata_); return _impl_.annotation_; } inline ::google::protobuf::RepeatedPtrField<::google::protobuf::GeneratedCodeInfo_Annotation>* GeneratedCodeInfo::_internal_mutable_annotation() { + PROTOBUF_TSAN_WRITE(&_internal_metadata_); return &_impl_.annotation_; } diff --git a/src/google/protobuf/port_def.inc b/src/google/protobuf/port_def.inc index fd387bad9820..3ad04e6f6eca 100644 --- a/src/google/protobuf/port_def.inc +++ b/src/google/protobuf/port_def.inc @@ -829,6 +829,31 @@ static_assert(PROTOBUF_ABSL_MIN(20230125, 3), # endif #endif +#ifdef PROTOBUF_TSAN_READ +#error PROTOBUF_TSAN_READ was previously defined +#endif +#ifdef PROTOBUF_TSAN_WRITE +#error PROTOBUF_TSAN_WRITE was previously defined +#endif +#ifdef PROTOBUF_TSAN +// TODO(b/285620714): it would be preferable to use __tsan_external_read/ +// __tsan_external_write, but they can cause dlopen issues. +#define PROTOBUF_TSAN_READ(addr) \ + do { \ + volatile char protobuf_tsan_dummy = *reinterpret_cast(addr); \ + (void)protobuf_tsan_dummy; \ + } while (0) +#define PROTOBUF_TSAN_WRITE(addr) \ + do { \ + char protobuf_tsan_zero = 0; \ + asm volatile("" : "+m"(protobuf_tsan_zero)); \ + *reinterpret_cast(addr) += protobuf_tsan_zero; \ + } while (0) +#else // PROTOBUF_TSAN +#define PROTOBUF_TSAN_READ(addr) +#define PROTOBUF_TSAN_WRITE(addr) +#endif // PROTOBUF_TSAN + #ifdef PROTOBUF_USE_TABLE_PARSER_ON_REFLECTION #error PROTOBUF_USE_TABLE_PARSER_ON_REFLECTION was previously defined #endif diff --git a/src/google/protobuf/port_undef.inc b/src/google/protobuf/port_undef.inc index 7ac2b03ea434..7170406c9c33 100644 --- a/src/google/protobuf/port_undef.inc +++ b/src/google/protobuf/port_undef.inc @@ -103,6 +103,8 @@ #undef PROTOBUF_ASAN #undef PROTOBUF_MSAN #undef PROTOBUF_TSAN +#undef PROTOBUF_TSAN_READ +#undef PROTOBUF_TSAN_WRITE #undef PROTOBUF_USE_TABLE_PARSER_ON_REFLECTION #undef PROTOBUF_TC_PARAM_DECL #undef PROTOBUF_EXCLUSIVE_LOCKS_REQUIRED diff --git a/src/google/protobuf/repeated_field_unittest.cc b/src/google/protobuf/repeated_field_unittest.cc index bcac69ab9c6d..5507b2475d16 100644 --- a/src/google/protobuf/repeated_field_unittest.cc +++ b/src/google/protobuf/repeated_field_unittest.cc @@ -2029,6 +2029,7 @@ TEST(RepeatedPtrField, Cleanups) { EXPECT_THAT(growth.cleanups, testing::IsEmpty()); } + // =================================================================== // Iterator tests stolen from net/proto/proto-array_unittest.