[PATCH] attribs: Fix ICEs on attributes starting with _ [PR103365]
Andrew Pinski
pinskia@gmail.com
Wed Nov 24 08:53:02 GMT 2021
On Wed, Nov 24, 2021 at 12:48 AM Jakub Jelinek via Gcc-patches
<gcc-patches@gcc.gnu.org> wrote:
>
> Hi!
>
> As the patch shows, we have quite a few asserts that we don't call
> lookup_attribute etc. with attr_name that starts with an underscore,
> to make sure nobody is trying to call it with non-canonicalized
> attribute name like "__cold__" instead of "cold".
> We canonicalize only attributes that start with 2 underscores and end
> with 2 underscores though.
> Before Marek's patch, that wasn't an issue, we had no attributes like
> "_foo" or "__bar_" etc., so lookup_scoped_attribute_spec would
> always return NULL for those and we wouldn't try to register them,
> look them up etc., just with -Wattributes would warn about them.
> But now, as the new testcase shows, users can actually request such
> attributes to be ignored, and we ICE for those during
> register_scoped_attribute and when that is fixed, ICE later on when
> somebody uses those attributes because they will be looked up
> to find out that they should be ignored.
>
> So, the following patch instead of or in addition to, depending on
> how performance sensitive a particular spot is, checking that
> attribute doesn't start with underscore allows attribute
> names that start with underscore as long as it doesn't canonicalize
> (i.e. doesn't start and end with 2 underscores).
> In addition to that, I've noticed lookup_attribute_by_prefix
> was calling get_attribute_name twice unnecessarily, and 2 tests
> were running in c++98 mode with -std=c++98 -std=c++11 which IMHO
> isn't useful because -std=c++11 testing is done too when testing
> all language versions.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2021-11-24 Jakub Jelinek <jakub@redhat.com>
>
> PR middle-end/103365
> * attribs.h (lookup_attribute): Allow attr_name to start with
> underscore, as long as canonicalize_attr_name returns false.
> (lookup_attribute_by_prefix): Don't call get_attribute_name twice.
> * attribs.c (extract_attribute_substring): Reimplement using
> canonicalize_attr_name.
> (register_scoped_attribute): Change gcc_assert into
> gcc_checking_assert, verify !canonicalize_attr_name rather than
> that str.str doesn't start with '_'.
>
> * c-c++-common/Wno-attributes-1.c: Require effective target
> c || c++11 and drop dg-additional-options.
> * c-c++-common/Wno-attributes-2.c: Likewise.
> * c-c++-common/Wno-attributes-4.c: New test.
Only one comment on the new testcases, you might want to add a
testcase for the option on the command line too.
Thanks,
Andrew Pinski
>
> --- gcc/attribs.h.jj 2021-11-22 10:06:42.173498383 +0100
> +++ gcc/attribs.h 2021-11-23 23:35:13.757972934 +0100
> @@ -188,7 +188,11 @@ is_attribute_p (const char *attr_name, c
> static inline tree
> lookup_attribute (const char *attr_name, tree list)
> {
> - gcc_checking_assert (attr_name[0] != '_');
> + if (CHECKING_P && attr_name[0] != '_')
> + {
> + size_t attr_len = strlen (attr_name);
> + gcc_checking_assert (!canonicalize_attr_name (attr_name, attr_len));
> + }
> /* In most cases, list is NULL_TREE. */
> if (list == NULL_TREE)
> return NULL_TREE;
> @@ -219,7 +223,8 @@ lookup_attribute_by_prefix (const char *
> size_t attr_len = strlen (attr_name);
> while (list)
> {
> - size_t ident_len = IDENTIFIER_LENGTH (get_attribute_name (list));
> + tree name = get_attribute_name (list);
> + size_t ident_len = IDENTIFIER_LENGTH (name);
>
> if (attr_len > ident_len)
> {
> @@ -227,7 +232,7 @@ lookup_attribute_by_prefix (const char *
> continue;
> }
>
> - const char *p = IDENTIFIER_POINTER (get_attribute_name (list));
> + const char *p = IDENTIFIER_POINTER (name);
> gcc_checking_assert (attr_len == 0 || p[0] != '_');
>
> if (strncmp (attr_name, p, attr_len) == 0)
> --- gcc/attribs.c.jj 2021-11-22 10:06:42.172498397 +0100
> +++ gcc/attribs.c 2021-11-23 14:58:25.076233815 +0100
> @@ -115,12 +115,7 @@ static const struct attribute_spec empty
> static void
> extract_attribute_substring (struct substring *str)
> {
> - if (str->length > 4 && str->str[0] == '_' && str->str[1] == '_'
> - && str->str[str->length - 1] == '_' && str->str[str->length - 2] == '_')
> - {
> - str->length -= 4;
> - str->str += 2;
> - }
> + canonicalize_attr_name (str->str, str->length);
> }
>
> /* Insert an array of attributes ATTRIBUTES into a namespace. This
> @@ -387,7 +382,7 @@ register_scoped_attribute (const struct
>
> /* Attribute names in the table must be in the form 'text' and not
> in the form '__text__'. */
> - gcc_assert (str.length > 0 && str.str[0] != '_');
> + gcc_checking_assert (!canonicalize_attr_name (str.str, str.length));
>
> slot = name_space->attribute_hash
> ->find_slot_with_hash (&str, substring_hash (str.str, str.length),
> --- gcc/testsuite/c-c++-common/Wno-attributes-1.c.jj 2021-11-11 14:35:37.637348034 +0100
> +++ gcc/testsuite/c-c++-common/Wno-attributes-1.c 2021-11-23 15:03:05.426198652 +0100
> @@ -1,6 +1,5 @@
> /* PR c++/101940 */
> -/* { dg-do compile } */
> -/* { dg-additional-options "-std=c++11" { target c++ } } */
> +/* { dg-do compile { target { c || c++11 } } } */
> /* { dg-additional-options "-Wno-attributes=company::,yoyodyne::attr" } */
> /* { dg-additional-options "-Wno-attributes=c1::attr,c1::attr,c1::__attr__" } */
> /* { dg-additional-options "-Wno-attributes=c2::,c2::attr" } */
> --- gcc/testsuite/c-c++-common/Wno-attributes-2.c.jj 2021-11-11 14:35:37.637348034 +0100
> +++ gcc/testsuite/c-c++-common/Wno-attributes-2.c 2021-11-23 15:03:14.637066079 +0100
> @@ -1,6 +1,5 @@
> /* PR c++/101940 */
> -/* { dg-do compile } */
> -/* { dg-additional-options "-std=c++11" { target c++ } } */
> +/* { dg-do compile { target { c || c++11 } } } */
>
> #pragma GCC diagnostic ignored_attributes "company::,yoyodyne::attr"
> #pragma GCC diagnostic ignored_attributes "c1::attr,c1::attr,c1::__attr__"
> --- gcc/testsuite/c-c++-common/Wno-attributes-4.c.jj 2021-11-23 15:00:47.584182655 +0100
> +++ gcc/testsuite/c-c++-common/Wno-attributes-4.c 2021-11-23 15:02:23.348804286 +0100
> @@ -0,0 +1,8 @@
> +/* PR middle-end/103365 */
> +/* { dg-do compile { target { c || c++11 } } } */
> +
> +#pragma GCC diagnostic ignored_attributes "foo::_bar"
> +#pragma GCC diagnostic ignored_attributes "_foo::bar"
> +
> +[[foo::_bar]] void foo (void);
> +[[_foo::bar]] void bar (void);
>
> Jakub
>
More information about the Gcc-patches
mailing list