On Thu, 13 Jul 2017, Martin Liška wrote:

> +/* For a given IDENTIFIER_NODE, strip leading and trailing '_' characters
> +   so that we have a canonical form of attribute names.  */
> +
> +static inline tree
> +canonicalize_attr_name (tree attr_name)
> +{
> +  const size_t l = IDENTIFIER_LENGTH (attr_name);
> +  const char *s = IDENTIFIER_POINTER (attr_name);
> +
> +  if (l > 4 && s[0] == '_')
> +    {
> +      gcc_checking_assert (s[l - 2] == '_');
> +      return get_identifier_with_length (s + 2, l - 4);
> +    }
> +
> +  return attr_name;

For this to (a) be correct, (b) not trigger the assertion, there must be a 
precondition that attr_name either starts and ends with __, or does not 
start with _, or has length 4 or less.  I don't see anything in the 
callers to ensure this precondition holds, so that, for example, 
__attribute__ ((_foobar)) does not trigger the assertion, and 
__attribute__ ((_xformat__)) is not wrongly interpreted as a format 
attribute (and similarly for attribute arguments when those are 
canonicalized).

> +/* Compare attribute identifiers ATTR1 and ATTR2 with length ATTR1_LEN and
> +   ATTR2_LEN.  */
> +
> +static inline bool
> +cmp_attribs (const char *attr1, size_t attr1_len,
> +          const char *attr2, size_t attr2_len)
> +{
> +  gcc_checking_assert (attr1_len == 0 || attr1[0] != '_');
> +  gcc_checking_assert (attr2_len == 0 || attr2[0] != '_');

Of course, once you only canonicalize attributes that both start and end 
with __, you have the possibility of a canonicalized attribute name that 
still starts with _, so can't assert on it here (unless this is only ever 
called with an attribute that is already known to be valid).  (And of 
course there are cases such as __attribute__((__)) that starts and ends 
with __ but is too short to canonicalize, etc., which arise even with the 
above canonicalize_attr_name.)

-- 
Joseph S. Myers
jos...@codesourcery.com

Reply via email to