Fix a bug where we did not return a mutable message for _mut() accessors

This bug has been found by the TSAN sanitizer as part of cl/582814210. Before this change we were incorrectly returning an immutable Message instance for mutable accessors. This bug has been detected by TSAN because for embedded message fields the C++ runtime returns a static message instance if a field has not been set. In cl/582814210 this bug led to two separate unit tests read and write from/to the same object without any synchronization. Thus TSAN found a data race.

Tests for this change will be added as part of cl/582814210. At this state of the source we don't have any mutation functions available to trigger the TSAN error.

PiperOrigin-RevId: 582978261
pull/14773/head
Jakob Buchgraber 1 year ago committed by Copybara-Service
parent 245a6e692a
commit ba7067c9fa
  1. 9
      src/google/protobuf/compiler/rust/accessors/singular_message.cc

@ -27,6 +27,7 @@ void SingularMessage::InMsgImpl(Context<FieldDescriptor> field) const {
{"prefix", prefix},
{"field", field.desc().name()},
{"getter_thunk", Thunk(field, "get")},
{"getter_mut_thunk", Thunk(field, "get_mut")},
{"clearer_thunk", Thunk(field, "clear")},
{
"view_body",
@ -72,7 +73,7 @@ void SingularMessage::InMsgImpl(Context<FieldDescriptor> field) const {
)rs");
} else {
field.Emit({}, R"rs(
let submsg = unsafe { $getter_thunk$(self.inner.msg) };
let submsg = unsafe { $getter_mut_thunk$(self.inner.msg) };
$prefix$Mut::new($pbi$::Private, &mut self.inner, submsg)
)rs");
}
@ -97,6 +98,7 @@ void SingularMessage::InExternC(Context<FieldDescriptor> field) const {
field.Emit(
{
{"getter_thunk", Thunk(field, "get")},
{"getter_mut_thunk", Thunk(field, "get_mut")},
{"clearer_thunk", Thunk(field, "clear")},
{"ReturnType",
[&] {
@ -112,6 +114,7 @@ void SingularMessage::InExternC(Context<FieldDescriptor> field) const {
},
R"rs(
fn $getter_thunk$(raw_msg: $pbi$::RawMessage) -> $ReturnType$;
fn $getter_mut_thunk$(raw_msg: $pbi$::RawMessage) -> $ReturnType$;
fn $clearer_thunk$(raw_msg: $pbi$::RawMessage);
)rs");
}
@ -120,12 +123,16 @@ void SingularMessage::InThunkCc(Context<FieldDescriptor> field) const {
field.Emit({{"QualifiedMsg",
cpp::QualifiedClassName(field.desc().containing_type())},
{"getter_thunk", Thunk(field, "get")},
{"getter_mut_thunk", Thunk(field, "get_mut")},
{"clearer_thunk", Thunk(field, "clear")},
{"field", cpp::FieldName(&field.desc())}},
R"cc(
const void* $getter_thunk$($QualifiedMsg$* msg) {
return static_cast<const void*>(&msg->$field$());
}
void* $getter_mut_thunk$($QualifiedMsg$* msg) {
return static_cast<void*>(msg->mutable_$field$());
}
void $clearer_thunk$($QualifiedMsg$* msg) { msg->clear_$field$(); }
)cc");
}

Loading…
Cancel
Save