On 3/21/19 5:05 PM, Martin Sebor wrote:
On 3/21/19 4:25 PM, Jakub Jelinek wrote:
On Thu, Mar 21, 2019 at 04:19:37PM -0600, Martin Sebor wrote:
Say that the argument is either a type or an expression that is
either an identifier (for C++ id-expression) to cover 1) and
a postfix expression with . or -> operator (to cover COMPONENT_REF)?

That doesn't look easy to understand.

Why?  Those users that don't read corresponding language standards
will just see the compiler diagnosing any uses but those 3 kinds
and can then just read the documentation which will show in examples what is
accepted and what it will do.

Because to most users it suggests that . and -> are the only operators
that are accepted in the expression and so something like p[0].a is not
a valid argument.

Those who don't read the manual will be puzzled when, after having had
p[0].a accepted, p->a[0] will trigger an error.

We do not want to allow INDIRECT_REF, ARRAY_REF, etc.

Why not?  What exactly is the concern?

Because only the . and -> operators are needed to get at the non-static
member declaration.  INDIRECT_REF or ARRAY_REF aren't useful for that,
and then it raises the question what exactly is supposed to be the behavior
when you use *expr or expr[0] or expr->field[0].  Those expression don't
have any decl, so we'd be back at your suggestion to pretty randomly
sometimes return DECL_ATTRIBUTES, sometimes TYPE_ATTRIBUTES, sometimes both. That is just a bad design.  If people want type attributes, they should use
__typeof or decltype or just type itself in the argument.

I never suggested to "pretty randomly sometimes return
DECL_ATTRIBUTES, sometimes TYPE_ATTRIBUTES, or sometimes both."
That's a silly mischaracterization, just as it would be to say
the same thing about __alignof__, and it works much the same way.
It operates on expressions and returns the alignment either
explicitly speciified for the variable (or function) or that
specified for its type.

I modeled the built-in on __alignof__.  There may bugs where it
behaves differently, or subtle deviations where I chose a different
approach, but it's certainly not random.  I'd like to fix the bugs,
and I'm open to reconsidering the deviations, but using either as
a justification for rejecting those kinds of expressions would
result in hard-to-use API.  And _that_ would be bad design.

An example of a deviation from __alignof__ that comes to mind
is this:

  __attribute__ ((aligned (8))) int a[2];

  _Static_assert (__alignof__ (a) == 8);
  _Static_assert (__builtin_has_attribute (a, aligned));

  _Static_assert (a[0]) == 8);   // fails
  _Static_assert (__builtin_has_attribute (a[0], aligned));

I made the ARRAY_REF case the same as the VAR_DECL case because
the alignment of a whole array also implies the alignment of
the array's elements.  Ditto for attribute packed. (And with
the patch the INDIRECT_REF has the same effect.)

I'm guessing that what you're objecting to is that this decision
conflates the results of the builtin for an array declared with
an attribute with that of the array's elements, as in:

  __attribute__ ((vector_size (8))) int a[2];

  _Static_assert (__builtin_has_attribute (a, vector_size));
  _Static_assert (__builtin_has_attribute (a[0], vector_size));

where both assertions pass, even though just the array element
is a vector, while a itself is an ordinary array.  I can see
that is not quite right and might warrant reconsidering
the decision for ARRAY_REF.

To your point about using __typeof__: GCC is inconsistent about
what it applies variable and function attributes to, whether
the decl or its type.  For example, vector_size is documented
as a variable attribute but it applies to a type.  Similarly,
attributes alloc_size and malloc are both documented as
function attributes but the former applies to the function
type (and so can be applied to a pointer to function), while
the latter to the function decl (and is ignored with
a warning on pointers to functions).  Until this is cleaned
up, either by correcting the documentation, or preferably by
making these attributes uniformly apply to types, it should
be obvious that suggesting that "if people want type attributes,
they should use __typeof or decltype" does not offer a viable
solution.

Martin

Reply via email to