aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexey Neyman <alex.neyman@auriga.ru>2005-03-08 13:19:40 +0000
committerRichard Henderson <rth@gcc.gnu.org>2005-03-08 05:19:40 -0800
commit6e9a32219ba643ca53c2b68822f0eddbf3280503 (patch)
treecdc25a73277e939285d67c67cd208d1cd34a0bc2 /gcc
parent25d8d27de5150007e26f4cb3397b823af63c5344 (diff)
downloadgcc-6e9a32219ba643ca53c2b68822f0eddbf3280503.zip
gcc-6e9a32219ba643ca53c2b68822f0eddbf3280503.tar.gz
gcc-6e9a32219ba643ca53c2b68822f0eddbf3280503.tar.bz2
re PR c/14411 (Request for setjmp/longjmp attributes)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/c-common.c21
-rw-r--r--gcc/calls.c4
-rw-r--r--gcc/doc/extend.texi13
-rw-r--r--gcc/testsuite/gcc.dg/attr-returns_twice-1.c23
-rw-r--r--gcc/tree.h8
6 files changed, 77 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 463175d..a89869d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/c-common.c b/gcc/c-common.c
index 39868e8..313af75 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -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. */
diff --git a/gcc/calls.c b/gcc/calls.c
index f90e1a5..d6032fc 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -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;
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 3b336d4..84349f3 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -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
index 0000000..9d3f6f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-returns_twice-1.c
@@ -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;
+}
diff --git a/gcc/tree.h b/gcc/tree.h
index acbfc93..aba1224 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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