Commit cecf01e6 authored by Robert Edmonds's avatar Robert Edmonds

protoc-c: c_message: Add extra braces to initialize a oneof union containing a ProtobufCBinaryData

Certain compilers (e.g. [0]) incorrectly generate warning messages
when the universal zero initializer is used by the protobuf-c generated
code to initialize a protobuf object containing a oneof that contains a
ProtobufCBinaryData field as the first member. This is now much more
likely due to the change in the previous commit ("protoc-c: c_message:
Order oneof union members from largest to smallest") which will now
always cause a ProtobufCBinaryData field to be placed as the first
member of the union, if one is present in the oneof.

In this situation, we need to add an extraneous pair of braces around
the universal zero initializer in the generated initialization code.

The former behavior of using the universal zero initializer by itself is
kept for oneof unions that do not contain a ProtobufCBinaryData member.

[0]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80454
parent 36485387
......@@ -253,6 +253,7 @@ GenerateStructDefinition(io::Printer* printer) {
printer->Print(vars, "#define $ucclassname$__INIT \\\n"
" { PROTOBUF_C_MESSAGE_INIT (&$lcclassname$__descriptor) \\\n ");
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor *field = descriptor_->field(i);
if (field->containing_oneof() == NULL) {
......@@ -260,16 +261,32 @@ GenerateStructDefinition(io::Printer* printer) {
field_generators_.get(field).GenerateStaticInit(printer);
}
}
for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
const OneofDescriptor *oneof = descriptor_->oneof_decl(i);
vars["foneofname"] = FullNameToUpper(oneof->full_name(), oneof->file());
// Initialize the case enum
printer->Print(vars, ", $foneofname$__NOT_SET");
// Initialize the union
printer->Print(", {0}");
bool want_extra_braces = false;
for (int j = 0; j < oneof->field_count(); j++) {
const FieldDescriptor *field = oneof->field(j);
if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING &&
field->type() == FieldDescriptor::TYPE_BYTES)
{
want_extra_braces = true;
}
}
if (want_extra_braces) {
printer->Print(", { {0} }");
} else {
printer->Print(", {0}");
}
}
printer->Print(" }\n\n\n");
printer->Print(" }\n\n\n");
}
void MessageGenerator::
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment