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