Re: [PATCH] Fix PR56982, handle setjmp like non-local labels

2013-04-20 Thread Andreas Schwab
Richard Biener rguent...@suse.de writes:

   PR tree-optimization/56982
   * builtins.def (BUILT_IN_LONGJMP): longjmp is not a leaf
   function.
   * gimplify.c (gimplify_call_expr): Notice special calls.
   (gimplify_modify_expr): Likewise.
   * tree-cfg.c (make_abnormal_goto_edges): Handle setjmp-like
   abnormal control flow receivers.
   (call_can_make_abnormal_goto): Handle cfun-calls_setjmp
   in the same way as cfun-has_nonlocal_labels.
   (gimple_purge_dead_abnormal_call_edges): Likewise.
   (stmt_starts_bb_p): Make setjmp-like abnormal control flow
   receivers start a basic-block.

This breaks libgo.

../../../gcc/libgo/runtime/proc.c: In function ‘runtime_mcall.constprop.7’:
../../../gcc/libgo/runtime/proc.c:419:13: error: ‘({anonymous})’ may be used 
uninitialized in this function [-Werror=maybe-uninitialized]
   getcontext(gp-context);
 ^

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
And now for something completely different.


Re: [PATCH] Fix PR56982, handle setjmp like non-local labels

2013-04-20 Thread Ian Lance Taylor
On Sat, Apr 20, 2013 at 5:14 AM, Andreas Schwab sch...@linux-m68k.org wrote:
 Richard Biener rguent...@suse.de writes:

   PR tree-optimization/56982
   * builtins.def (BUILT_IN_LONGJMP): longjmp is not a leaf
   function.
   * gimplify.c (gimplify_call_expr): Notice special calls.
   (gimplify_modify_expr): Likewise.
   * tree-cfg.c (make_abnormal_goto_edges): Handle setjmp-like
   abnormal control flow receivers.
   (call_can_make_abnormal_goto): Handle cfun-calls_setjmp
   in the same way as cfun-has_nonlocal_labels.
   (gimple_purge_dead_abnormal_call_edges): Likewise.
   (stmt_starts_bb_p): Make setjmp-like abnormal control flow
   receivers start a basic-block.

 This breaks libgo.

 ../../../gcc/libgo/runtime/proc.c: In function ‘runtime_mcall.constprop.7’:
 ../../../gcc/libgo/runtime/proc.c:419:13: error: ‘({anonymous})’ may be used 
 uninitialized in this function [-Werror=maybe-uninitialized]
getcontext(gp-context);
  ^

That's an unusually useless error message.  There are no local structs
in this function.  Without digging into the compiler I'm not sure what
this means or how to fix it.

Ian


[PATCH] Fix PR56982, handle setjmp like non-local labels

2013-04-17 Thread Richard Biener

This fixes PR56982 by properly modeling the control-flow
of setjmp.  It basically behaves as a non-local goto target
so this patch treats it so - it makes it start a basic-block
and get abnormal edges from possible sources of non-local
gotos.  The patch also fixes the bug that longjmp is marked
as leaf.

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok for trunk?
What about release branches (after it had some time to settle on
trunk of course)?

Thanks,
Richard.

2013-04-17  Richard Biener  rguent...@suse.de

PR tree-optimization/56982
* builtins.def (BUILT_IN_LONGJMP): longjmp is not a leaf
function.
* gimplify.c (gimplify_call_expr): Notice special calls.
(gimplify_modify_expr): Likewise.
* tree-cfg.c (make_abnormal_goto_edges): Handle setjmp-like
abnormal control flow receivers.
(call_can_make_abnormal_goto): Handle cfun-calls_setjmp
in the same way as cfun-has_nonlocal_labels.
(gimple_purge_dead_abnormal_call_edges): Likewise.
(stmt_starts_bb_p): Make setjmp-like abnormal control flow
receivers start a basic-block.

* gcc.c-torture/execute/pr56982.c: New testcase.

Index: gcc/gimplify.c
===
*** gcc/gimplify.c  (revision 198021)
--- gcc/gimplify.c  (working copy)
*** gimplify_call_expr (tree *expr_p, gimple
*** 2729,2734 
--- 2729,2735 
gimple_stmt_iterator gsi;
call = gimple_build_call_from_tree (*expr_p);
gimple_call_set_fntype (call, TREE_TYPE (fnptrtype));
+   notice_special_calls (call);
gimplify_seq_add_stmt (pre_p, call);
gsi = gsi_last (*pre_p);
fold_stmt (gsi);
*** gimplify_modify_expr (tree *expr_p, gimp
*** 4968,4973 
--- 4969,4975 
STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
assign = gimple_build_call_from_tree (*from_p);
gimple_call_set_fntype (assign, TREE_TYPE (fnptrtype));
+   notice_special_calls (assign);
if (!gimple_call_noreturn_p (assign))
gimple_call_set_lhs (assign, *to_p);
  }
Index: gcc/tree-cfg.c
===
*** gcc/tree-cfg.c  (revision 198021)
--- gcc/tree-cfg.c  (working copy)
*** make_abnormal_goto_edges (basic_block bb
*** 967,991 
gimple_stmt_iterator gsi;
  
FOR_EACH_BB (target_bb)
! for (gsi = gsi_start_bb (target_bb); !gsi_end_p (gsi); gsi_next (gsi))
!   {
!   gimple label_stmt = gsi_stmt (gsi);
!   tree target;
  
!   if (gimple_code (label_stmt) != GIMPLE_LABEL)
! break;
  
!   target = gimple_label_label (label_stmt);
  
!   /* Make an edge to every label block that has been marked as a
!  potential target for a computed goto or a non-local goto.  */
!   if ((FORCED_LABEL (target)  !for_call)
!   || (DECL_NONLOCAL (target)  for_call))
! {
make_edge (bb, target_bb, EDGE_ABNORMAL);
!   break;
! }
!   }
  }
  
  /* Create edges for a goto statement at block BB.  */
--- 971,1005 
gimple_stmt_iterator gsi;
  
FOR_EACH_BB (target_bb)
! {
!   for (gsi = gsi_start_bb (target_bb); !gsi_end_p (gsi); gsi_next (gsi))
!   {
! gimple label_stmt = gsi_stmt (gsi);
! tree target;
  
! if (gimple_code (label_stmt) != GIMPLE_LABEL)
!   break;
  
! target = gimple_label_label (label_stmt);
  
! /* Make an edge to every label block that has been marked as a
!potential target for a computed goto or a non-local goto.  */
! if ((FORCED_LABEL (target)  !for_call)
! || (DECL_NONLOCAL (target)  for_call))
!   {
! make_edge (bb, target_bb, EDGE_ABNORMAL);
! break;
!   }
!   }
!   if (!gsi_end_p (gsi))
!   {
! /* Make an edge to every setjmp-like call.  */
! gimple call_stmt = gsi_stmt (gsi);
! if (is_gimple_call (call_stmt)
!  (gimple_call_flags (call_stmt)  ECF_RETURNS_TWICE))
make_edge (bb, target_bb, EDGE_ABNORMAL);
!   }
! }
  }
  
  /* Create edges for a goto statement at block BB.  */
*** call_can_make_abnormal_goto (gimple t)
*** 2147,2153 
  {
/* If the function has no non-local labels, then a call cannot make an
   abnormal transfer of control.  */
!   if (!cfun-has_nonlocal_label)
 return false;
  
/* Likewise if the call has no side effects.  */
--- 2161,2168 
  {
/* If the function has no non-local labels, then a call cannot make an
   abnormal transfer of control.  */
!   if (!cfun-has_nonlocal_label
!!cfun-calls_setjmp)
 return false;
  
/* Likewise if the call has no side effects.  */
*** stmt_starts_bb_p (gimple stmt, gimple pr
*** 2302,2307 
--- 2317,2327 
else