This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix c/14411


Version 2: renamed to __attribute__((returns_twice)) and updated
after ECF_LONGJMP cleanup.

Regtested on i686-pc-linux-gnu.

2004-10-29  Alexey Neyman  <alex.neyman@auriga.ru>

	PR c/14411
	* calls.c (flags_from_decl_or_type): Handle `returns_twice' attribute.
	* c-common.c (handle_returns_twice): New function.
	(c_common_attribute_table): Declare `returns_twice' attribute.
	* doc/extend.texi: Document `returns_twice' attribute.
	* tree.h (DECL_IS_RETURNS_TWICE): New macro.
	(struct tree_decl): Add returns_twice_flag.


2004-10-29  Alexey Neyman  <alex.neyman@auriga.ru>
	* gcc.dg/attr-returns_twice-1.c: New test.


-- 
Of course, as a loving parent I must push you from the nest.
                        -- Pkunks, SC2
diff -crN gcc.orig/gcc/c-common.c gcc.setjmp/gcc/c-common.c
*** gcc.orig/gcc/c-common.c	Fri Nov 26 10:12:51 2004
--- gcc.setjmp/gcc/c-common.c	Fri Nov 26 10:33:35 2004
***************
*** 545,550 ****
--- 545,551 ----
  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 *);
***************
*** 615,620 ****
--- 616,623 ----
  			      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,
***************
*** 4715,4720 ****
--- 4718,4741 ----
    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 -crN gcc.orig/gcc/calls.c gcc.setjmp/gcc/calls.c
*** gcc.orig/gcc/calls.c	Thu Nov 25 17:20:06 2004
--- gcc.setjmp/gcc/calls.c	Fri Nov 26 10:33:35 2004
***************
*** 587,592 ****
--- 587,596 ----
        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 -crN gcc.orig/gcc/doc/extend.texi gcc.setjmp/gcc/doc/extend.texi
*** gcc.orig/gcc/doc/extend.texi	Wed Nov 24 10:58:45 2004
--- gcc.setjmp/gcc/doc/extend.texi	Fri Nov 26 10:33:35 2004
***************
*** 1476,1481 ****
--- 1476,1482 ----
  @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,1501 ****
  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{pure}, @code{const}, @code{nothrow}, @code{sentinel},
  @code{format}, @code{format_arg}, @code{no_instrument_function},
  @code{section}, @code{constructor}, @code{destructor}, @code{used},
--- 1496,1502 ----
  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{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},
***************
*** 2087,2092 ****
--- 2088,2103 ----
  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 -crN gcc.orig/gcc/testsuite/gcc.dg/attr-returns_twice-1.c gcc.setjmp/gcc/testsuite/gcc.dg/attr-returns_twice-1.c
*** gcc.orig/gcc/testsuite/gcc.dg/attr-returns_twice-1.c	Thu Jan  1 03:00:00 1970
--- gcc.setjmp/gcc/testsuite/gcc.dg/attr-returns_twice-1.c	Fri Nov 26 10:33:35 2004
***************
*** 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 -crN gcc.orig/gcc/tree.h gcc.setjmp/gcc/tree.h
*** gcc.orig/gcc/tree.h	Thu Nov 25 17:20:32 2004
--- gcc.setjmp/gcc/tree.h	Fri Nov 26 10:34:34 2004
***************
*** 2145,2150 ****
--- 2145,2155 ----
     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)
***************
*** 2349,2355 ****
    unsigned possibly_inlined : 1;
    unsigned preserve_flag: 1;
    unsigned gimple_formal_temp : 1;
!   /* 13 unused bits.  */
  
    union tree_decl_u1 {
      /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
--- 2354,2361 ----
    unsigned possibly_inlined : 1;
    unsigned preserve_flag: 1;
    unsigned gimple_formal_temp : 1;
!   unsigned returns_twice_flag : 1;
!   /* 12 unused bits.  */
  
    union tree_decl_u1 {
      /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]