https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116016
--- Comment #33 from Bill Wendling <isanbard at gmail dot com> ---
(In reply to Kees Cook from comment #31)
> (In reply to Qing Zhao from comment #25)
> > The source code need to be:
> >
> > If (__builtin_get_counted_by (P->FAM))
> > __builtin_get_counted_by (P->FAM) = COUNT;
> >
> > Yes, I agree that this is good too for the original purpose. And also even
> > simpler and more flexible.
> > Kees might have more comments here. (Not sure any other impact on handling
> > the original problem he had with the new __builtin_get_counted_by).
>
> Yeah, I like this. It gives much more obvious semantics instead of hiding a
> no-op, and this could be used for _reading_ as well as writing the value.
> This means we could also write, for example, loop constructs with only the
> FAM:
>
>
> typeof(*__builtin_get_counted_by(P->FAM)) idx;
>
> for (idx = 0; idx < *__builtin_get_counted_by(P->FAM); idx++)
> do_things(P->FAM[idx]);
I have a rough version of __builtin_set_counted_by working in Clang. I'm not
happy with it because it hides no-ops. I think the suggestions here are going
in the correct direction. I'd like to throw out some alternatives so that the
builtins could be more general.
If we had a way of testing for an attribute, we could avoid the need to return
( void *)0 when the '__builtin_get' can't find the attribute:
__builtin_has_attr (ptr, attr_name);
We could then have a builtin to get the attribute's argument:
__builtin_get_attr_arg (ptr, attr_name)
This could have an optional argument to specify which argument to get if the
attr has more than one:
__builtin_get_attr_arg (ptr, attr_name, pos)
If we do all of this, we could use it directly to set the value:
if (__builtin_has_attr (ptr->FAM, counted_by))
ptr->__builtin_get_attr_arg (ptr-FAM, counted_by, 0) = count;
If the user requires the value be set, they could do something a bit more
drastic in the 'else' case:
size_t *counted_by_field = NULL; /* size_t or whatever type */
if (__builtin_has_attr (ptr->FAM, counted_by))
counted_by = &ptr->__builtin_get_attr_arg (ptr-FAM, counted_by, 0);
if (!counted_by)
/* Do something horrible and slow */
It's more verbose, but it makes the programmer think about the case when either
the 'counted_by' attribute (or any other attribute) doesn't exist. It also
eases the burden on the compiler to look through arbitrary casts for the FAM /
count objects in a struct (this is probably more of an issue with Clang than
GCC). It's also generic which allows us to use it for any future expansions.