Patchwork [Fortran] PR 51800 - Fix -finit-local-zero with automatic arrays and -fno-automatic

login
register
mail settings
Submitter Tobias Burnus
Date Jan. 11, 2012, 5:03 p.m.
Message ID <4F0DC0FB.7040508@net-b.de>
Download mbox | patch
Permalink /patch/135434/
State New
Headers show

Comments

Tobias Burnus - Jan. 11, 2012, 5:03 p.m.
-finit-* creates an initialization for local variables - either as 
static initializer or by "initializing" at run time.

The latter also works with automatic variables, but was breaking with 
-fno-automatic, which causes all nonautomatic local variables to be 
placed in static memory. However, combining -finit-* -fno-automatic with 
automatic arrays is failing at resolution time. The fix turned out to be 
rather simple.

I wondered about characters strings where the length is a nonconstant 
specification question (thus: they are also automatic data objects). It 
turned out that only the "initialization" was missing - no code 
generation (trans*.c) change and no other resolution change were required.

The first part fixes a regression as "-finit-* -fno-automatic" could be 
combined before (albeit without initializing the automatic arrays - but 
there was no compile error).

Build and regtested on x86-64-linux.
OK for the trunk?

Tobias
Toon Moene - Jan. 11, 2012, 7:54 p.m.
On 01/11/2012 06:03 PM, Tobias Burnus wrote:

> -finit-* creates an initialization for local variables - either as
> static initializer or by "initializing" at run time.
>
> The latter also works with automatic variables, but was breaking with
> -fno-automatic, which causes all nonautomatic local variables to be
> placed in static memory. However, combining -finit-* -fno-automatic with
> automatic arrays is failing at resolution time. The fix turned out to be
> rather simple.

Good, I wondered how this would work (the reason I thought it would 
always work with automatic arrays was that it apparently (assembler 
source and output of trial program) worked for arrays smaller than the 
limit to place them on the stack.

Unfortunately, I forgot to test this against the combination of -finit-* 
-fno-automatic, which just proves you cannot have too many test cases.

> I wondered about characters strings where the length is a nonconstant
> specification question (thus: they are also automatic data objects). It
> turned out that only the "initialization" was missing - no code
> generation (trans*.c) change and no other resolution change were required.
>
> The first part fixes a regression as "-finit-* -fno-automatic" could be
> combined before (albeit without initializing the automatic arrays - but
> there was no compile error).

Perhaps we can issue a warning.

> Build and regtested on x86-64-linux.
> OK for the trunk?

Note that I backported this change (noted in PR/51310) to the 4.6 
branch, so it's needed there too.

Thanks for fixing this !
Tobias Burnus - Jan. 11, 2012, 8:01 p.m.
Toon Moene wrote:
>> The first part fixes a regression as "-finit-* -fno-automatic" could be
>> combined before (albeit without initializing the automatic arrays - but
>> there was no compile error).
>
> Perhaps we can issue a warning.

Well, with your plus my patch it does initialize automatic arrays and 
character variables with nonconstant lengths. Thus, there is no need for 
a warning.

Before your patch: No initialization of automatic data objects
With your patch: Initialization for automatic arrays, but fails with 
-fno-automatic.
With my patch: Initialization also for nonconst-length character 
strings, no failures with -fno-automatic.


>> Build and regtested on x86-64-linux.
>> OK for the trunk?
>
> Note that I backported this change (noted in PR/51310) to the 4.6 
> branch, so it's needed there too.

Thanks for the reminder!

Tobias
Toon Moene - Jan. 11, 2012, 8:10 p.m.
On 01/11/2012 09:01 PM, Tobias Burnus wrote:

> Before your patch: No initialization of automatic data objects
> With your patch: Initialization for automatic arrays, but fails with
> -fno-automatic.
> With my patch: Initialization also for nonconst-length character
> strings, no failures with -fno-automatic.

BTW, does this mean -finit-real=snan would work via an "initialization 
expression" at run time after allocation for allocatable arrays (note 
that this isn't covered, still), i.e., that I could try to fix this in 
4.8 in the same way as it works in resolve.c, but then applied to 
trans-array.c ?

Or do I have to apply a different method ?

Thanks !
Paul Richard Thomas - Jan. 14, 2012, 11:51 a.m.
Dear Tobias,


> Build and regtested on x86-64-linux.
> OK for the trunk?

That's OK for trunk - thanks!

Paul

Patch

2012-01-11  Tobias Burnus  <burnus@net-b.de>

	PR fortran/51800
	* resolve.c (build_default_init_expr): Also initialize
	nonconstant-length strings with -finit-character=<n>.

2012-01-11  Tobias Burnus  <burnus@net-b.de>

	PR fortran/51800
	* gfortran.dg/init_flag_8.f90: New.
	* gfortran.dg/init_flag_9.f90: New.

Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c	(revision 183093)
+++ gcc/fortran/resolve.c	(working copy)
@@ -10143,6 +10143,26 @@  build_default_init_expr (gfc_symbol *sym)
 	  gfc_free_expr (init_expr);
 	  init_expr = NULL;
 	}
+      if (!init_expr && gfc_option.flag_init_character == GFC_INIT_CHARACTER_ON
+	  && sym->ts.u.cl->length)
+	{
+	  gfc_actual_arglist *arg;
+	  init_expr = gfc_get_expr ();
+	  init_expr->where = sym->declared_at;
+	  init_expr->ts = sym->ts;
+	  init_expr->expr_type = EXPR_FUNCTION;
+	  init_expr->value.function.isym =
+		gfc_intrinsic_function_by_id (GFC_ISYM_REPEAT);
+	  init_expr->value.function.name = "repeat";
+	  arg = gfc_get_actual_arglist ();
+	  arg->expr = gfc_get_character_expr (sym->ts.kind, &sym->declared_at,
+					      NULL, 1);
+	  arg->expr->value.character.string[0]
+		= gfc_option.flag_init_character_value;
+	  arg->next = gfc_get_actual_arglist ();
+	  arg->next->expr = gfc_copy_expr (sym->ts.u.cl->length);
+	  init_expr->value.function.actual = arg;
+	}
       break;
 	  
     default:
@@ -10169,10 +10189,12 @@  apply_default_init_local (gfc_symbol *sym)
   if (init == NULL)
     return;
 
-  /* For saved variables, we don't want to add an initializer at 
-     function entry, so we just add a static initializer.  */
+  /* For saved variables, we don't want to add an initializer at function
+     entry, so we just add a static initializer. Note that automatic variables
+     are stack allocated even with -fno-automatic.  */
   if (sym->attr.save || sym->ns->save_all 
-      || gfc_option.flag_max_stack_var_size == 0)
+      || (gfc_option.flag_max_stack_var_size == 0
+	  && (!sym->attr.dimension || !is_non_constant_shape_array (sym))))
     {
       /* Don't clobber an existing initializer!  */
       gcc_assert (sym->value == NULL);
Index: gcc/testsuite/gfortran.dg/init_flag_8.f90
===================================================================
--- gcc/testsuite/gfortran.dg/init_flag_8.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/init_flag_8.f90	(working copy)
@@ -0,0 +1,18 @@ 
+! { dg-do compile }
+! { dg-options "-fno-automatic -finit-local-zero" }
+!
+! PR fortran/51800
+!
+! Contributed by Mario Baumann
+!
+      SUBROUTINE FOO( N, A )
+      IMPLICIT NONE
+      INTEGER :: N
+      INTEGER :: A(1:N)
+      INTEGER :: J
+      INTEGER :: DUMMY(1:N)
+      DO J=1,N
+         DUMMY(J) = 0
+         A(J) = DUMMY(J)
+      END DO 
+      END SUBROUTINE FOO
Index: gcc/testsuite/gfortran.dg/init_flag_9.f90
===================================================================
--- gcc/testsuite/gfortran.dg/init_flag_9.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/init_flag_9.f90	(working copy)
@@ -0,0 +1,15 @@ 
+! { dg-do run }
+! { dg-options "-finit-character=89" }
+!
+! PR fortran/51800
+!
+
+subroutine foo(n)
+  character(len=n) :: str
+!  print *, str
+  if (str /= repeat ('Y', n)) call abort()
+end subroutine foo
+
+call foo(3)
+call foo(10)
+end