On 5/18/20 4:37 AM, Martin Liška wrote:
Hi.

The patch adds new no_stack_protect attribute. The change is requested
from kernel folks and is direct equivalent of Clang's no_stack_protector.
Unlike Clang, I chose to name it no_stack_protect because we already
have stack_protect attribute (used with -fstack-protector-explicit).

First part of the patch contains a small refactoring of an enum, second
implements the functionality.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.

Ready to be installed?
Thanks,
Martin

0002-Implement-no_stack_protect-attribute.patch

 From 6b3e9d32150fe17acb271b7bedee7dc95cad7dc8 Mon Sep 17 00:00:00 2001
From: Martin Liska<mli...@suse.cz>
Date: Fri, 15 May 2020 14:42:12 +0200
Subject: [PATCH 2/2] Implement no_stack_protect attribute.

gcc/ChangeLog:

2020-05-18  Martin Liska<mli...@suse.cz>

        PR c/94722
        * cfgexpand.c (stack_protect_decl_phase):
        Guard with lookup_attribute("no_stack_protect") at
        various places.
        (expand_used_vars): Likewise here.
        * doc/extend.texi: Document no_stack_protect attribute.

gcc/ada/ChangeLog:

2020-05-18  Martin Liska<mli...@suse.cz>

        PR c/94722
        * gcc-interface/utils.c (handle_no_stack_protect_attribute):
        New.
        (handle_stack_protect_attribute): Add error message for a
        no_stack_protect function.

gcc/c-family/ChangeLog:

2020-05-18  Martin Liska<mli...@suse.cz>

        PR c/94722
        * c-attribs.c (handle_no_stack_protect_function_attribute): New.
        (handle_stack_protect_attribute): Add error message for a
        no_stack_protect function.

gcc/testsuite/ChangeLog:

2020-05-18  Martin Liska<mli...@suse.cz>

        PR c/94722
        * g++.dg/no-stack-protect-attr-2.C: New test.
        * g++.dg/no-stack-protect-attr-3.C: New test.
        * g++.dg/no-stack-protect-attr.C: New test.
---
  gcc/ada/gcc-interface/utils.c                 | 32 ++++++++
  gcc/c-family/c-attribs.c                      | 33 ++++++++
  gcc/cfgexpand.c                               | 82 ++++++++++---------
  gcc/doc/extend.texi                           |  4 +
  .../g++.dg/no-stack-protect-attr-2.C          |  7 ++
  .../g++.dg/no-stack-protect-attr-3.C          | 23 ++++++
  gcc/testsuite/g++.dg/no-stack-protect-attr.C  | 16 ++++
  7 files changed, 158 insertions(+), 39 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/no-stack-protect-attr-2.C
  create mode 100644 gcc/testsuite/g++.dg/no-stack-protect-attr-3.C
  create mode 100644 gcc/testsuite/g++.dg/no-stack-protect-attr.C

diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 1527be4f6d1..144afe37d78 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -91,6 +91,7 @@ static tree handle_nonnull_attribute (tree *, tree, tree, 
int, bool *);
  static tree handle_sentinel_attribute (tree *, tree, tree, int, bool *);
  static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *);
  static tree handle_stack_protect_attribute (tree *, tree, tree, int, bool *);
+static tree handle_no_stack_protect_attribute (tree *, tree, tree, int, bool 
*);
  static tree handle_noinline_attribute (tree *, tree, tree, int, bool *);
  static tree handle_noclone_attribute (tree *, tree, tree, int, bool *);
  static tree handle_noicf_attribute (tree *, tree, tree, int, bool *);
@@ -141,6 +142,8 @@ const struct attribute_spec gnat_internal_attribute_table[] 
=
      handle_noreturn_attribute, NULL },
    { "stack_protect",0, 0, true,  false, false, false,
      handle_stack_protect_attribute, NULL },
+  { "no_stack_protect",0, 0, true,  false, false, false,
+    handle_no_stack_protect_attribute, NULL },
    { "noinline",     0, 0,  true,  false, false, false,
      handle_noinline_attribute, NULL },
    { "noclone",      0, 0,  true,  false, false, false,
@@ -6523,10 +6526,39 @@ handle_stack_protect_attribute (tree *node, tree name, 
tree, int,
        warning (OPT_Wattributes, "%qE attribute ignored", name);
        *no_add_attrs = true;
      }
+  else if (lookup_attribute ("no_stack_protect", DECL_ATTRIBUTES (*node)))
+    {
+      warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
+              "with %qs attribute", name, "no_stack_protect");
+      *no_add_attrs = true;

I know there are some somewhat complex cases the attribute exclusion
mechanism isn't general enough to handle but this seems simple enough
that it should work.  Unless I'm missing something that makes it not
feasible I would suggest to use it.

diff --git a/gcc/testsuite/g++.dg/no-stack-protect-attr-2.C 
b/gcc/testsuite/g++.dg/no-stack-protect-attr-2.C
new file mode 100644
index 00000000000..dcac6f9d389
--- /dev/null
+++ b/gcc/testsuite/g++.dg/no-stack-protect-attr-2.C
@@ -0,0 +1,7 @@
+/* PR c/94722 */
+/* { dg-do compile } */
+
+int __attribute__((no_stack_protect, stack_protect)) c() /* { dg-warning 
"'stack_protect' attribute ignored due to conflict with 'no_stack_protect' 
attribute" } */

The more likely misuse than applying incompatible attributes to
the same declaration is to redeclare the same function, once with
one attribute and then again with the other.  One of the main
benefits of the attribute exclusion mechanism is to detect both
and point at the two declarations to make correcting one or
the other easier.

Martin

Reply via email to