Fix realloc_on_assign_2.f03, random segfaults/ICEs

Michael Matz matz@suse.de
Wed Mar 30 16:51:00 GMT 2011


Hello,

I noticed this some time ago already, but it went away.  Now it reoccured 
and made me suspicious.  "It" being random ICEs in fold_convert_loc, or 
segfaults, sometimes reproducable, sometimes not, on the 
realloc_on_assign_2.f03 testcase.

The issue is that the frontend leaks the address of a local variable to 
outside its containing scope.  Depending on the phase of moon, 
optimization factor and the like this stack space then is or is not 
overwritten at the use site.  For me loop->to[0] was overwritten with a 
type node, ultimately ICEing in fold_convert when it tries to convert a 
type to a, well, type :)

I haven't audited all users of gfc_copy_loopinfo_to_se, many seem to store 
the address of a local variable into the se structure.  But those I looked 
at seem to be safe, in the sense of not using the se structure 
outside places where loop is also defined.  Except for this one use I'm 
patching below, by moving the loop variable to the place that contains 
also the se structure.

Okay for trunk?  (regstrapping on x86_64-linux in progress)


Ciao,
Michael.
-- 
	* trans-expr.c (realloc_lhs_loop_for_fcn_call): Take loop as parameter,
	don't use local variable.
	(gfc_trans_arrayfunc_assign): Adjust caller.

Index: fortran/trans-expr.c
===================================================================
--- fortran/trans-expr.c	(revision 171734)
+++ fortran/trans-expr.c	(working copy)
@@ -5510,20 +5512,20 @@ arrayfunc_assign_needs_temporary (gfc_ex
    reallocatable assignments from extrinsic function calls.  */
 
 static void
-realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss)
+realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss,
+			       gfc_loopinfo *loop)
 {
-  gfc_loopinfo loop;
   /* Signal that the function call should not be made by
      gfc_conv_loop_setup. */
   se->ss->is_alloc_lhs = 1;
-  gfc_init_loopinfo (&loop);
-  gfc_add_ss_to_loop (&loop, *ss);
-  gfc_add_ss_to_loop (&loop, se->ss);
-  gfc_conv_ss_startstride (&loop);
-  gfc_conv_loop_setup (&loop, where);
-  gfc_copy_loopinfo_to_se (se, &loop);
-  gfc_add_block_to_block (&se->pre, &loop.pre);
-  gfc_add_block_to_block (&se->pre, &loop.post);
+  gfc_init_loopinfo (loop);
+  gfc_add_ss_to_loop (loop, *ss);
+  gfc_add_ss_to_loop (loop, se->ss);
+  gfc_conv_ss_startstride (loop);
+  gfc_conv_loop_setup (loop, where);
+  gfc_copy_loopinfo_to_se (se, loop);
+  gfc_add_block_to_block (&se->pre, &loop->pre);
+  gfc_add_block_to_block (&se->pre, &loop->post);
   se->ss->is_alloc_lhs = 0;
 }
 
@@ -5591,6 +5593,7 @@ gfc_trans_arrayfunc_assign (gfc_expr * e
   gfc_se se;
   gfc_ss *ss;
   gfc_component *comp = NULL;
+  gfc_loopinfo loop;
 
   if (arrayfunc_assign_needs_temporary (expr1, expr2))
     return NULL;
@@ -5641,7 +5644,7 @@ gfc_trans_arrayfunc_assign (gfc_expr * e
     {
       if (!expr2->value.function.isym)
 	{
-	  realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss);
+	  realloc_lhs_loop_for_fcn_call (&se, &expr1->where, &ss, &loop);
 	  ss->is_alloc_lhs = 1;
 	}
       else



More information about the Gcc-patches mailing list