Page MenuHome GnuPG

Use of offsetof is better for allocation of flexible array
Open, NormalPublic

Description

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.

Event Timeline

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);
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
werner triaged this task as Normal priority.Aug 25 2021, 4:27 PM
gniibe set External Link to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102151.Sep 1 2021, 3:44 AM