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.

Reply via email to