On 09/16/2014 08:27 AM, Jason Merrill wrote:
On 09/16/2014 06:23 AM, Ulrich Weigand wrote:
Note that with a somewhat equivalent C construct:

struct pollfd
   {
     int fd;
     short int events;
     short int revents;
   };

struct Pollfd
   {
     struct pollfd x;
   };

struct Pollfd myfd[10];

we still get an object size of 80 for either:

   __builtin_object_size ((struct pollfd *)myfd, 1);

or even

   __builtin_object_size (&myfd->x, 1);

That strikes me as a bug, especially the second one.

This seems to be happening because of the STRIP_USELESS_TYPE_CONVERSION in gimplify_expr dropping the NOP_EXPR from the argument, otherwise the NOP_EXPR would cause __builtin_object_size to give up. I don't think this behavior is intentional...

I don't know why the C frontend is folding &myfd->x to (struct pollfd *)myfd, though.

Is this "wrapping" of system types in a derived calls supposed to work?
If there is a better way to express this without breaking glibc headers,
I'd be happy to let the authors know ...

Well, __builtin_object_size seems to be pretty fragile magic. To make it work I guess you could add a wrapper for poll that takes a Pollfd and does a reinterpret_cast, i.e.

inline int poll(Pollfd* p, nfds_t n, int t)
{
  return poll(reinterpret_cast<pollfd*>(p), n, t);
}

so that you force the conversion to ignore the inheritance relationship and thereby avoid the COMPONENT_REF.

Jason

Reply via email to