diff mbox

[fortran] PR65792 unitialized structure constructor array subcomponent

Message ID 55328ADC.4020102@sfr.fr
State New
Headers show

Commit Message

Mikael Morin April 18, 2015, 4:48 p.m. UTC
Hello,

here is a fix for PR65792 where a structure constructor used as actual
argument was not fully initialized.

The test looks like the following...

  type :: string_t
     character(LEN=1), dimension(:), allocatable :: chars
  end type string_t

  type :: string_container_t
     type(string_t) :: comp
  end type string_container_t

  type(string_t) :: prt_in

  [...]
  tmpc = new_prt_spec2 (string_container_t(prt_in))



The problem is in gfc_trans_subcomponent_assign, when initialising the
component comp with prt_in:

	  if (cm->ts.u.derived->attr.alloc_comp
	      && expr->expr_type == EXPR_VARIABLE)
	    {
	      tmp = gfc_copy_alloc_comp (cm->ts.u.derived, se.expr,
					 dest, expr->rank);
	      gfc_add_expr_to_block (&block, tmp);
	    }
	  else
	    gfc_add_modify (&block, dest,
			    fold_convert (TREE_TYPE (dest), se.expr));

The if branch deep copies allocatable components, but does nothing for
other components, which is the case here (the array elements are copied,
not the array bounds).


The patch proposed here for backport, moves the existing shallow copy
out of the else branch.

For trunk, I wanted to reuse gfc_trans_scalar_assign which has all the
logic for copying stuff around.  And as gfc_trans_scalar_assign is used
as fallback a few lines down, I have tried to use that fallback.
This change of control flow makes the patch a bit more risky, so I
prefer to use the other variant for the branches.

Setting the deep_copy argument of gfc_trans_scalar_assign to true is
necessary so that gfc_copy_alloc_comp is called as before.
Because of the branch the patch removes, I think the fallback code was
unreachable for non-derived types, and for those the deep_copy flag was
irrelevant anyway, so that that change should be rather harmless.


Both patches have been regression tested on trunk on x86_64-linux.
OK for trunk [first patch]?
OK for 4.9 and 5 (after the 5.1 release) [second patch]?

Mikael

PS: Dominiq reported that the variant of this patch posted on the PR was
also fixing PR49324.  I couldn't confirm as what seems to be the
remaining testcase there (comment #6) doesn't fail with trunk here.

Comments

Mikael Morin April 25, 2015, 3:49 p.m. UTC | #1
Dominique reported that the trunk patch breaks class_19.f90 when applied
together with Andre's PR59678 fix.
It appears to me that even without Andre's patch, the code generated is
wrong, and I don't see any easy fix.
Thus I'm withdrawing trunk's patch, and propose the backport patch also
for trunk.

Mikael
diff mbox

Patch

2015-04-18  Mikael Morin  <mikael@gcc.gnu.org>

	PR fortran/65792
	* trans-expr.c (gfc_trans_subcomponent_assign):
	Always (shallow) copy the subcomponent.

2015-04-18  Mikael Morin  <mikael@gcc.gnu.org>

	PR fortran/65792
	* gfortran.dg/derived_constructor_comps_5.f90: New.

Index: trans-expr.c
===================================================================
--- trans-expr.c	(révision 221972)
+++ trans-expr.c	(copie de travail)
@@ -6915,6 +6935,8 @@  gfc_trans_subcomponent_assign (tree dest, gfc_comp
 	  gfc_init_se (&se, NULL);
 	  gfc_conv_expr (&se, expr);
 	  gfc_add_block_to_block (&block, &se.pre);
+	  gfc_add_modify (&block, dest,
+			  fold_convert (TREE_TYPE (dest), se.expr));
 	  if (cm->ts.u.derived->attr.alloc_comp
 	      && expr->expr_type == EXPR_VARIABLE)
 	    {
@@ -6922,9 +6944,6 @@  gfc_trans_subcomponent_assign (tree dest, gfc_comp
 					 dest, expr->rank);
 	      gfc_add_expr_to_block (&block, tmp);
 	    }
-	  else
-	    gfc_add_modify (&block, dest,
-			    fold_convert (TREE_TYPE (dest), se.expr));
 	  gfc_add_block_to_block (&block, &se.post);
 	}
       else