diff options
author | Alexey Neyman <alex.neyman@auriga.ru> | 2005-03-08 13:19:40 +0000 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2005-03-08 05:19:40 -0800 |
commit | 6e9a32219ba643ca53c2b68822f0eddbf3280503 (patch) | |
tree | cdc25a73277e939285d67c67cd208d1cd34a0bc2 /gcc | |
parent | 25d8d27de5150007e26f4cb3397b823af63c5344 (diff) | |
download | gcc-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/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/c-common.c | 21 | ||||
-rw-r--r-- | gcc/calls.c | 4 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 13 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/attr-returns_twice-1.c | 23 | ||||
-rw-r--r-- | gcc/tree.h | 8 |
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; +} @@ -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 |