i386: Change indirect_return to function type attribute
authorH.J. Lu <hongjiu.lu@intel.com>
Thu, 19 Jul 2018 10:47:23 +0000 (10:47 +0000)
committerH.J. Lu <hjl@gcc.gnu.org>
Thu, 19 Jul 2018 10:47:23 +0000 (03:47 -0700)
In

struct ucontext;
typedef struct ucontext ucontext_t;

extern int (*bar) (ucontext_t *__restrict __oucp,
                   const ucontext_t *__restrict __ucp)
  __attribute__((__indirect_return__));

extern int res;

void
foo (ucontext_t *oucp, ucontext_t *ucp)
{
  res = bar (oucp, ucp);
}

bar() may return via indirect branch.  This patch changes indirect_return
to type attribute to allow indirect_return attribute on variable or type
of function pointer so that ENDBR can be inserted after call to bar().

gcc/

PR target/86560
* config/i386/i386.c (rest_of_insert_endbranch): Lookup
indirect_return as function type attribute.
(ix86_attribute_table): Change indirect_return to function
type attribute.
* doc/extend.texi: Update indirect_return attribute.

gcc/testsuite/

PR target/86560
* gcc.target/i386/pr86560-1.c: New test.
* gcc.target/i386/pr86560-2.c: Likewise.
* gcc.target/i386/pr86560-3.c: Likewise.

From-SVN: r262877

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/doc/extend.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/pr86560-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr86560-2.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/pr86560-3.c [new file with mode: 0644]

index ecdaf32fd7794414aa91451036a07dcea588e834..78b8d39ab2b7a215888a4ffb70c3a75649a9211d 100644 (file)
@@ -1,3 +1,12 @@
+2018-07-19  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/86560
+       * config/i386/i386.c (rest_of_insert_endbranch): Lookup
+       indirect_return as function type attribute.
+       (ix86_attribute_table): Change indirect_return to function
+       type attribute.
+       * doc/extend.texi: Update indirect_return attribute.
+
 2018-07-19  Aldy Hernandez  <aldyh@redhat.com>
 
        * wide-int.h (widest2_int): New.
index 2b7e9489ed8b2cbdcdc4dbbf78cb5423701b5567..ee409cfe7e486c2524266c4ef14ef6e3de87a7ba 100644 (file)
@@ -2635,16 +2635,23 @@ rest_of_insert_endbranch (void)
                {
                  rtx call = get_call_rtx_from (insn);
                  rtx fnaddr = XEXP (call, 0);
+                 tree fndecl = NULL_TREE;
 
                  /* Also generate ENDBRANCH for non-tail call which
                     may return via indirect branch.  */
-                 if (MEM_P (fnaddr)
-                     && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF)
+                 if (GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF)
+                   fndecl = SYMBOL_REF_DECL (XEXP (fnaddr, 0));
+                 if (fndecl == NULL_TREE)
+                   fndecl = MEM_EXPR (fnaddr);
+                 if (fndecl
+                     && TREE_CODE (TREE_TYPE (fndecl)) != FUNCTION_TYPE
+                     && TREE_CODE (TREE_TYPE (fndecl)) != METHOD_TYPE)
+                   fndecl = NULL_TREE;
+                 if (fndecl && TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
                    {
-                     tree fndecl = SYMBOL_REF_DECL (XEXP (fnaddr, 0));
-                     if (fndecl
-                         && lookup_attribute ("indirect_return",
-                                              DECL_ATTRIBUTES (fndecl)))
+                     tree fntype = TREE_TYPE (fndecl);
+                     if (lookup_attribute ("indirect_return",
+                                           TYPE_ATTRIBUTES (fntype)))
                        need_endbr = true;
                    }
                }
@@ -45920,8 +45927,8 @@ static const struct attribute_spec ix86_attribute_table[] =
     ix86_handle_fndecl_attribute, NULL },
   { "function_return", 1, 1, true, false, false, false,
     ix86_handle_fndecl_attribute, NULL },
-  { "indirect_return", 0, 0, true, false, false, false,
-    ix86_handle_fndecl_attribute, NULL },
+  { "indirect_return", 0, 0, false, true, true, false,
+    NULL, NULL },
 
   /* End element.  */
   { NULL, 0, 0, false, false, false, false, NULL, NULL }
index abac85c5cb2abcc3c82538e71d37b34287402f4b..7b471ec40f701ade4dc8f15a0303885e697eb789 100644 (file)
@@ -5889,8 +5889,9 @@ foo (void)
 @item indirect_return
 @cindex @code{indirect_return} function attribute, x86
 
-The @code{indirect_return} attribute on a function is used to inform
-the compiler that the function may return via indirect branch.
+The @code{indirect_return} attribute can be applied to a function,
+as well as variable or type of function pointer to inform the
+compiler that the function may return via indirect branch.
 
 @end table
 
index f78a7c82a8937bb8322e3c900faafaf0c5669d15..8c60524cdee100cc2fcd4b173be4b8e779b03903 100644 (file)
@@ -1,3 +1,10 @@
+2018-07-19  H.J. Lu  <hongjiu.lu@intel.com>
+
+       PR target/86560
+       * gcc.target/i386/pr86560-1.c: New test.
+       * gcc.target/i386/pr86560-2.c: Likewise.
+       * gcc.target/i386/pr86560-3.c: Likewise.
+
 2018-07-19  Kyrylo Tkachov  <kyrylo.tkachov@arm.com>
 
        * gfortran.dg/max_fmax_aarch64.f90: New test.
diff --git a/gcc/testsuite/gcc.target/i386/pr86560-1.c b/gcc/testsuite/gcc.target/i386/pr86560-1.c
new file mode 100644 (file)
index 0000000..a2b7026
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcf-protection" } */
+/* { dg-final { scan-assembler-times {\mendbr} 2 } } */
+
+struct ucontext;
+
+extern int (*bar) (struct ucontext *)
+  __attribute__((__indirect_return__));
+
+extern int res;
+
+void
+foo (struct ucontext *oucp)
+{
+  res = bar (oucp);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr86560-2.c b/gcc/testsuite/gcc.target/i386/pr86560-2.c
new file mode 100644 (file)
index 0000000..6f01b38
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcf-protection" } */
+/* { dg-final { scan-assembler-times {\mendbr} 2 } } */
+
+struct ucontext;
+
+typedef int (*bar_p) (struct ucontext *)
+  __attribute__((__indirect_return__));
+
+extern int res;
+
+void
+foo (bar_p bar, struct ucontext *oucp)
+{
+  res = bar (oucp);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr86560-3.c b/gcc/testsuite/gcc.target/i386/pr86560-3.c
new file mode 100644 (file)
index 0000000..05328e2
--- /dev/null
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fcf-protection" } */
+/* { dg-final { scan-assembler-times {\mendbr} 2 } } */
+
+struct ucontext;
+
+extern int (*bar) (struct ucontext *);
+
+extern int res;
+
+void
+foo (struct ucontext *oucp)
+{
+  int (*f) (struct ucontext *) __attribute__((__indirect_return__))
+    = bar;
+  res = f (oucp);
+}