t/issue745/: Add test case for #745

This currently fails on gcc 15 but succeeds on gcc 14, as expected.
This commit is contained in:
Robert Edmonds
2025-01-20 19:18:26 -05:00
parent 67eef00207
commit 040e9eb0c5
4 changed files with 91 additions and 0 deletions

View File

@@ -329,6 +329,23 @@ BUILT_SOURCES += \
EXTRA_DIST += \
t/issue440/issue440.proto
# Issue #745
check_PROGRAMS += \
t/issue745/issue745
TESTS += \
t/issue745/issue745
t_issue745_issue745_SOURCES = \
t/issue745/issue745.c \
t/issue745/issue745.pb-c.c
t_issue745_issue745_LDADD = \
protobuf-c/libprotobuf-c.la
t/issue745/issue745.pb-c.c t/issue745/issue745.pb-c.h: $(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) $(top_srcdir)/t/issue745/issue745.proto
$(AM_V_GEN)@PROTOC@ --plugin=protoc-gen-c=$(top_builddir)/protoc-c/protoc-gen-c$(EXEEXT) -I$(top_srcdir) --c_out=$(top_builddir) $(top_srcdir)/t/issue745/issue745.proto
BUILT_SOURCES += \
t/issue745/issue745.pb-c.c t/issue745/issue745.pb-c.h
EXTRA_DIST += \
t/issue745/issue745.proto
endif # CROSS_COMPILING
endif # BUILD_COMPILER

1
t/issue745/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/issue745

41
t/issue745/issue745.c Normal file
View File

@@ -0,0 +1,41 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include "t/issue745/issue745.pb-c.h"
int main(void)
{
T t = T__INIT;
size_t offset_to_union = offsetof(T, test_bool);
size_t size_of_union = sizeof(T) - offset_to_union;
unsigned char *ptr_to_union = ((unsigned char *)&t) + offset_to_union;
assert(offsetof(T, test_bool) == offsetof(T, test_enum));
assert(offsetof(T, test_enum) == offsetof(T, test_float));
assert(offsetof(T, test_float) == offsetof(T, test_uint32));
assert(offsetof(T, test_uint32) == offsetof(T, test_message));
assert(offsetof(T, test_message) == offsetof(T, test_string));
assert(offsetof(T, test_string) == offsetof(T, test_double));
assert(offsetof(T, test_double) == offsetof(T, test_uint64));
assert(offsetof(T, test_uint64) == offsetof(T, test_bytes));
for (size_t i = 0; i < size_of_union; i++) {
fprintf(stderr, "ptr_to_union[%zd] = %02x\n", i, ptr_to_union[i]);
}
// The following will probably crash on gcc >= 15 under its default
// `-fzero-init-padding-bits=standard` behavior, if the ordering of oneof union
// members in T are as performed by protobuf-c <= 1.5.0.
//
// The code generator in protobuf-c >= 1.5.1 should order union members from
// largest to smallest, which should correctly zero all the bits used by the
// object representations of the members of the oneof union even on gcc >= 15.
for (size_t i = 0; i < size_of_union; i++) {
assert(ptr_to_union[i] == 0);
}
return EXIT_SUCCESS;
}

32
t/issue745/issue745.proto Normal file
View File

@@ -0,0 +1,32 @@
syntax = "proto3";
enum E {
FIRST_VALUE = 0;
SECOND_VALUE = 1;
}
message M {
int32 test = 1;
}
message T {
oneof test_oneof {
bool test_bool = 1;
E test_enum = 2;
float test_float = 3;
fixed32 test_fixed32 = 4;
int32 test_int32 = 5;
sfixed32 test_sfixed32 = 6;
sint32 test_sint32 = 7;
uint32 test_uint32 = 8;
M test_message = 9;
string test_string = 10;
double test_double = 11;
fixed64 test_fixed64 = 12;
int64 test_int64 = 13;
sfixed64 test_sfixed64 = 14;
sint64 test_sint64 = 15;
uint64 test_uint64 = 16;
bytes test_bytes = 17;
}
}