[PATCH] handle expressions in __builtin_has_attribute (PR 88383)

Martin Sebor msebor@gmail.com
Thu Dec 13 22:22:00 GMT 2018

On 12/13/18 12:56 PM, Jakub Jelinek wrote:
> On Thu, Dec 13, 2018 at 12:48:18PM -0700, Martin Sebor wrote:
>>> The support is necessary in order to determine the attributes
>>> in expressions such as:
>>>     struct S { __attribute__ ((packed)) int a[32]; };
>>>     extern struct S s;
>>>     _Static_assert (__builtin_has_attribute (s.a, packed));
>> An example involving types might be a better one:
>>    typedef __attribute__ ((may_alias)) int* BadInt;
>>    void f (BadInt *p)
>>    {
>>      _Static_assert (__builtin_has_attribute (*p, may_alias));
>>    }
> So how is the builtin defined then?  Is the argument always an expression
> and you only return whether its type has the attribute, or do something
> different if the expression is of certain kind?

For a DECL the built-in looks at both the DECL_ATTRIBUTES and
the DECL's type's TYPE_ATTRIBUTES.  For expressions, it just
looks at TYPE_ATTRIBUTES of the expression's type.  I'm not
sure that this is necessarily the cleanest design but it's
meant to follow how attributes are applied to DECLs.  Sometimes
they get applied to the DECL itself and other times to its type.
This has been causing confusion to both users and GCC devs such
as myself so at some point I'd like to make this clearer somehow.
Not sure exactly how yet.

> Perhaps it would be better have two builtins, one would always take
> type from the expression, the other would only accept decls (or perhaps
> some syntax for the FIELD_DECLs).

I'm not sure I see a need for two built-ins here.

There is another way to handle the may_alias example: by using
typeof first and then the built-in on the result:

   _Static_assert (__builtin_has_attribute (__typeof__ (*p), may_alias));

so it seems that it would be possible to do what Jeff suggests
and only accept DECLs and TYPEs.  But I'm also not sure I see
an advantage of restricting the built-in like that.

FWIW, I had in mind two uses when I introduced the built-in:
1) a conditional attribute copy (where the condition would be
whether or not the source DECL or TYPE has some attribute), and
2) detecting that attributes have been successfully applied as
expected in tests.  I haven't implemented (1) yet but I'd like
to at some point (if only to avoid hardcoding into GCC the set
of attributes that are excluded from copying).  I have added
a handful of tests that make use of the built-in.  So if changes
should be made to the built-in, I will want to make sure they
don't make these use cases difficult.


More information about the Gcc-patches mailing list