re PR c/14411 (Request for setjmp/longjmp attributes)
authorAlexey Neyman <alex.neyman@auriga.ru>
Tue, 8 Mar 2005 13:19:40 +0000 (13:19 +0000)
committerRichard Henderson <rth@gcc.gnu.org>
Tue, 8 Mar 2005 13:19:40 +0000 (05:19 -0800)
        PR c/14411
        * calls.c (flags_from_decl_or_type): Handle eturns_twice' attribute.
        * c-common.c (handle_returns_twice): New function.
        (c_common_attribute_table): Declare eturns_twice' attribute.
        * doc/extend.texi: Document eturns_twice' attribute.
        * tree.h (DECL_IS_RETURNS_TWICE): New macro.
        (struct tree_decl): Add returns_twice_flag.

From-SVN: r96101

gcc/ChangeLog
gcc/c-common.c
gcc/calls.c
gcc/doc/extend.texi
gcc/testsuite/gcc.dg/attr-returns_twice-1.c [new file with mode: 0644]
gcc/tree.h

index 463175d64f9626b770e816ffcc17fd3f71f13fd2..a89869d96bb050bb375e818bb3a18f0a8f6300f1 100644 (file)
@@ -1,3 +1,13 @@
+2005-03-08  Alexey Neyman  <alex.neyman@auriga.ru>
+
+       PR c/14411
+       * calls.c (flags_from_decl_or_type): Handle eturns_twice' attribute.
+       * c-common.c (handle_returns_twice): New function.
+       (c_common_attribute_table): Declare eturns_twice' attribute.
+       * doc/extend.texi: Document eturns_twice' attribute.
+       * tree.h (DECL_IS_RETURNS_TWICE): New macro.
+       (struct tree_decl): Add returns_twice_flag.
+
 2005-03-08  Kazu Hirata  <kazu@cs.umass.edu>
 
        * tree-ssa-phiopt.c: Fix a comment typo.
index 39868e886592d82b0fa1f041800b448f19b362cb..313af75e6a762f67ea8fdf24d4b1c6370072d477 100644 (file)
@@ -537,6 +537,7 @@ static tree handle_tls_model_attribute (tree *, tree, tree, int,
 static tree handle_no_instrument_function_attribute (tree *, tree,
                                                     tree, int, bool *);
 static tree handle_malloc_attribute (tree *, tree, tree, int, bool *);
+static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
 static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
                                             bool *);
 static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
@@ -607,6 +608,8 @@ const struct attribute_spec c_common_attribute_table[] =
                              handle_no_instrument_function_attribute },
   { "malloc",                 0, 0, true,  false, false,
                              handle_malloc_attribute },
+  { "returns_twice",          0, 0, true,  false, false,
+                             handle_returns_twice_attribute },
   { "no_stack_limit",         0, 0, true,  false, false,
                              handle_no_limit_stack_attribute },
   { "pure",                   0, 0, true,  false, false,
@@ -4787,6 +4790,24 @@ handle_malloc_attribute (tree *node, tree name, tree ARG_UNUSED (args),
   return NULL_TREE;
 }
 
+/* Handle a "returns_twice" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_returns_twice_attribute (tree *node, tree name, tree ARG_UNUSED (args),
+                        int ARG_UNUSED (flags), bool *no_add_attrs)
+{
+  if (TREE_CODE (*node) == FUNCTION_DECL)
+    DECL_IS_RETURNS_TWICE (*node) = 1;
+  else
+    {
+      warning ("%qs attribute ignored", IDENTIFIER_POINTER (name));
+      *no_add_attrs = true;
+    }
+
+  return NULL_TREE;
+}
+
 /* Handle a "no_limit_stack" attribute; arguments as in
    struct attribute_spec.handler.  */
 
index f90e1a56ec44800640a3408e28e1ef539f856ea9..d6032fc78bcac4b1cc34bcce2753d2087c7a3448 100644 (file)
@@ -585,6 +585,10 @@ flags_from_decl_or_type (tree exp)
       if (DECL_IS_MALLOC (exp))
        flags |= ECF_MALLOC;
 
+      /* The function exp may have the `returns_twice' attribute.  */
+      if (DECL_IS_RETURNS_TWICE (exp))
+       flags |= ECF_RETURNS_TWICE;
+
       /* The function exp may have the `pure' attribute.  */
       if (DECL_IS_PURE (exp))
        flags |= ECF_PURE | ECF_LIBCALL_BLOCK;
index 3b336d44dda1c071a6fd609f3eb50765726fcabd..84349f3c373a4be35125d3718b7033bd0b665689 100644 (file)
@@ -1476,6 +1476,7 @@ the enclosing block.
 @cindex function attributes
 @cindex declaring attributes of functions
 @cindex functions that never return
+@cindex functions that return more than once
 @cindex functions that have no side effects
 @cindex functions in arbitrary sections
 @cindex functions that behave like malloc
@@ -1495,7 +1496,7 @@ The keyword @code{__attribute__} allows you to specify special
 attributes when making a declaration.  This keyword is followed by an
 attribute specification inside double parentheses.  The following
 attributes are currently defined for functions on all targets:
-@code{noreturn}, @code{noinline}, @code{always_inline},
+@code{noreturn}, @code{returns_twice}, @code{noinline}, @code{always_inline},
 @code{pure}, @code{const}, @code{nothrow}, @code{sentinel},
 @code{format}, @code{format_arg}, @code{no_instrument_function},
 @code{section}, @code{constructor}, @code{destructor}, @code{used},
@@ -2089,6 +2090,16 @@ safe since the loaders there save all registers.  (Lazy binding can be
 disabled with the linker or the loader if desired, to avoid the
 problem.)
 
+@item returns_twice
+@cindex @code{returns_twice} attribute
+The @code{returns_twice} attribute tells the compiler that a function may
+return more than one time.  The compiler will ensure that all registers
+are dead before calling such a function and will emit a warning about
+the variables that may be clobbered after the second return from the
+function.  Examples of such functions are @code{setjmp} and @code{vfork}.
+The @code{longjmp}-like counterpart of such function, if any, might need
+to be marked with the @code{noreturn} attribute.
+
 @item saveall
 @cindex save all registers on the H8/300, H8/300H, and H8S
 Use this attribute on the H8/300, H8/300H, and H8S to indicate that
diff --git a/gcc/testsuite/gcc.dg/attr-returns_twice-1.c b/gcc/testsuite/gcc.dg/attr-returns_twice-1.c
new file mode 100644 (file)
index 0000000..9d3f6f1
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile { target i?86-*-* } } */
+/* { dg-options "-W" } */
+
+int newsetjmp(void) __attribute__((returns_twice));
+void g(int);
+
+int
+main (void)
+{
+  register int reg asm ("esi") = 1; /* { dg-warning "might be clobbered" "" } */
+
+  if (!newsetjmp ())
+    {
+      reg = 2;
+      g (reg);
+    }
+  else
+    {
+      g (reg);
+    }
+
+  return 0;
+}
index acbfc93eaa68f715d6b81a70fde8ee499df82413..aba12246f784594142ea2a5c7e44287eed77f0b8 100644 (file)
@@ -2176,6 +2176,11 @@ struct tree_binfo GTY (())
    not an alias.  */
 #define DECL_IS_MALLOC(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.malloc_flag)
 
+/* Nonzero in a FUNCTION_DECL means this function may return more
+   than once.  */
+#define DECL_IS_RETURNS_TWICE(NODE) \
+  (FUNCTION_DECL_CHECK (NODE)->decl.returns_twice_flag)
+
 /* Nonzero in a FUNCTION_DECL means this function should be treated
    as "pure" function (like const function, but may read global memory).  */
 #define DECL_IS_PURE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.pure_flag)
@@ -2377,7 +2382,8 @@ struct tree_decl GTY(())
   unsigned preserve_flag: 1;
   unsigned gimple_formal_temp : 1;
   unsigned debug_expr_is_from : 1;
-  /* 12 unused bits.  */
+  unsigned returns_twice_flag : 1;
+  /* 11 unused bits.  */
 
   union tree_decl_u1 {
     /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is