In the commit: rM3c1c98a43413: core: Use flexible array member if compiler has support.
The commit title was "Use of flexible array member", but my intention was actually use of offsetof to clarify the size of allocation.
In the commit: rM3c1c98a43413: core: Use flexible array member if compiler has support.
The commit title was "Use of flexible array member", but my intention was actually use of offsetof to clarify the size of allocation.
For the use case of struct arg_and_data_s in gpgme, which may allocate zero-sized ARG[], it seems that GCC 11 interprets it as an invalid use.
Moving ARG_LOCP field next to DATA, so that size of the structure can be smaller on 64-bit machine, we can see the warning again, even with the use of flexible array member.
For GCC 11, modified version of struct arg_and_data_s has an issue for x86_64.
struct arg_and_data_s { struct arg_and_data_s *next; gpgme_data_t data; /* If this is not NULL, use arg below. */ int *arg_locp; /* Write back the argv idx of this argument when building command line to this location. */ int inbound; /* True if this is used for reading from gpg. */ int dup_to; int print_fd; /* Print the fd number and not the special form of it. */ char arg[]; /* Used if data above is not used. */ };
That is, sizeof (struct arg_and_data_s) is 40, while offsetof(struct arg_and_data_s, arg) is 36. I'm afraid we have to call it a compiler problem.
t-fam.c: In function 'main': t-fam.c:34:14: warning: array subscript 'struct arg_and_data_s[0]' is partly outside array bounds of 'unsigned char[22]' [-Warray-bounds] 34 | aad0->next = NULL; | ^ t-fam.c:30:10: note: referencing an object of size 22 allocated by 'malloc' 30 | aad0 = malloc (offsetof (struct arg_and_data_s, arg) + 2); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ t-fam.c:35:13: warning: array subscript 'struct arg_and_data_s[0]' is partly outside array bounds of 'unsigned char[22]' [-Warray-bounds] 35 | aad0->len = 2; | ~~~~~~~~~~^~~ t-fam.c:30:10: note: referencing an object of size 22 allocated by 'malloc' 30 | aad0 = malloc (offsetof (struct arg_and_data_s, arg) + 2); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ t-fam.c:36:15: warning: array subscript 'struct arg_and_data_s[0]' is partly outside array bounds of 'unsigned char[22]' [-Warray-bounds] 36 | aad0->flags = 0; | ~~~~~~~~~~~~^~~ t-fam.c:30:10: note: referencing an object of size 22 allocated by 'malloc' 30 | aad0 = malloc (offsetof (struct arg_and_data_s, arg) + 2); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ t-fam.c:37:18: warning: array subscript 'struct arg_and_data_s[0]' is partly outside array bounds of 'unsigned char[22]' [-Warray-bounds] 37 | aad0->print_fd = fd; | ~~~~~~~~~~~~~~~^~~~ t-fam.c:30:10: note: referencing an object of size 22 allocated by 'malloc' 30 | aad0 = malloc (offsetof (struct arg_and_data_s, arg) + 2); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I filed a bug report to GCC, with modified test case.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102151