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