This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran 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]

Re: [Patch, Fortran] PR 41714: [OOP] ALLOCATE SOURCE= does not properly copy the value from SOURCE


2009/10/25 Richard Guenther <richard.guenther@gmail.com>:
> On Sun, Oct 25, 2009 at 10:58 PM, Janus Weil <janus@gcc.gnu.org> wrote:
>>>> So, what to do? Are we back to
>>>>
>>>> Index: gcc/fortran/trans.c
>>>> ===================================================================
>>>> --- gcc/fortran/trans.c (Revision 153538)
>>>> +++ gcc/fortran/trans.c (Arbeitskopie)
>>>> @@ -1282,7 +1282,11 @@ gfc_trans_code (gfc_code * code)
>>>> ? ? ?if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
>>>> ? ? ? {
>>>> ? ? ? ? if (TREE_CODE (res) == STATEMENT_LIST)
>>>> - ? ? ? ? ? tree_annotate_all_with_location (&res, input_location);
>>>> + ? ? ? ? ? {
>>>> + ? ? ? ? ? ? tree_stmt_iterator i;
>>>> + ? ? ? ? ? ? for (i = tsi_start (res); !tsi_end_p (i); tsi_next (&i))
>>>> + ? ? ? ? ? ? ? SET_EXPR_LOCATION (tsi_stmt (i), input_location);
>>>> + ? ? ? ? ? }
>>>> ? ? ? ? else
>>>> ? ? ? ? ? SET_EXPR_LOCATION (res, input_location);
>>>>
>>>> or is there a better option? (One alternative could be to set the
>>>> location only for OpenMP cases, since all other things seem to work?)
>>>
>>> I suggest to find out which expressions miss a proper location and fix
>>> it where they are generated.
>>
>> Ok. What about using the above patchlet (or something similar) as an
>> ad-hoc solution (for the sake of getting this PR fixed), and opening a
>> new PR for the issue of setting correct input locations (which is in
>> no way connected to the original intention of this PR)? I promise to
>> have a look at the location issue myself (later) ...
>
> It should never happen to be a STATEMENT_LIST in the above hunk
> (at least not resulting from foldings). ?Thus, can you check just retaining
> the original SET_EXPR_LOCATION (res, input_location)?

Good point. That seems to work much better. Also removing the stuff in
trans-openmp.c seems to work, which means one can indeed remove
'tree_annotate_all_with_location' completely, and with it
'tree_annotate_one_with_location' and 'tree_should_carry_location_p'.

Will do a full boostrap + regtest of the attached patch, and probably
commit tomorrow if successful.

Afterwards, I will open a PR to check what prevents the removal of the
remaining SET_EXPR_LOCATION in trans.c.

Cheers,
Janus
Index: gcc/testsuite/gfortran.dg/class_allocate_4.f03
===================================================================
--- gcc/testsuite/gfortran.dg/class_allocate_4.f03	(Revision 0)
+++ gcc/testsuite/gfortran.dg/class_allocate_4.f03	(Revision 0)
@@ -0,0 +1,23 @@
+! { dg-do run }
+!
+! PR 41714: [OOP] ALLOCATE SOURCE= does not properly copy the value from SOURCE
+!
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+
+type t
+  integer :: i
+end type t
+type, extends(t) :: t2
+  integer :: j
+end type t2
+
+class(t), allocatable :: a
+allocate(a, source=t2(1,2))
+print *,a%i
+if(a%i /= 1) call abort()
+select type (a)
+  type is (t2)
+     print *,a%j
+     if(a%j /= 2) call abort()
+end select
+end
Index: gcc/fortran/trans-openmp.c
===================================================================
--- gcc/fortran/trans-openmp.c	(Revision 153542)
+++ gcc/fortran/trans-openmp.c	(Arbeitskopie)
@@ -1641,11 +1641,6 @@ gfc_trans_omp_workshare (gfc_code *code, gfc_omp_c
 
       if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
 	{
-	  if (TREE_CODE (res) == STATEMENT_LIST)
-	    tree_annotate_all_with_location (&res, input_location);
-	  else
-	    SET_EXPR_LOCATION (res, input_location);
-
 	  if (prev_singleunit)
 	    {
 	      if (ompws_flags & OMPWS_CURR_SINGLEUNIT)
Index: gcc/fortran/trans-stmt.c
===================================================================
--- gcc/fortran/trans-stmt.c	(Revision 153542)
+++ gcc/fortran/trans-stmt.c	(Arbeitskopie)
@@ -3983,12 +3983,13 @@ gfc_trans_allocate (gfc_code * code)
   tree stat;
   tree pstat;
   tree error_label;
+  tree memsz;
   stmtblock_t block;
 
   if (!code->ext.alloc.list)
     return NULL_TREE;
 
-  pstat = stat = error_label = tmp = NULL_TREE;
+  pstat = stat = error_label = tmp = memsz = NULL_TREE;
 
   gfc_start_block (&block);
 
@@ -4032,19 +4033,19 @@ gfc_trans_allocate (gfc_code * code)
 	      gfc_init_se (&se_sz, NULL);
 	      gfc_conv_expr (&se_sz, sz);
 	      gfc_free_expr (sz);
-	      tmp = se_sz.expr;
+	      memsz = se_sz.expr;
 	    }
 	  else if (code->expr3 && code->expr3->ts.type != BT_CLASS)
-	    tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->expr3->ts));
+	    memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->expr3->ts));
 	  else if (code->ext.alloc.ts.type != BT_UNKNOWN)
-	    tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
+	    memsz = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
 	  else
-	    tmp = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
+	    memsz = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (se.expr)));
 
-	  if (expr->ts.type == BT_CHARACTER && tmp == NULL_TREE)
-	    tmp = se.string_length;
+	  if (expr->ts.type == BT_CHARACTER && memsz == NULL_TREE)
+	    memsz = se.string_length;
 
-	  tmp = gfc_allocate_with_status (&se.pre, tmp, pstat);
+	  tmp = gfc_allocate_with_status (&se.pre, memsz, pstat);
 	  tmp = fold_build2 (MODIFY_EXPR, void_type_node, se.expr,
 			     fold_convert (TREE_TYPE (se.expr), tmp));
 	  gfc_add_expr_to_block (&se.pre, tmp);
@@ -4075,21 +4076,17 @@ gfc_trans_allocate (gfc_code * code)
       if (code->expr3)
 	{
 	  gfc_expr *rhs = gfc_copy_expr (code->expr3);
-	  if (rhs->ts.type == BT_CLASS)
+	  if (al->expr->ts.type == BT_CLASS)
 	    {
-	      gfc_se dst,src,len;
-	      gfc_expr *sz;
-	      gfc_add_component_ref (rhs, "$data");
-	      sz = gfc_copy_expr (code->expr3);
-	      gfc_add_component_ref (sz, "$size");
+	      gfc_se dst,src;
+	      if (rhs->ts.type == BT_CLASS)
+		gfc_add_component_ref (rhs, "$data");
 	      gfc_init_se (&dst, NULL);
 	      gfc_init_se (&src, NULL);
-	      gfc_init_se (&len, NULL);
 	      gfc_conv_expr (&dst, expr);
 	      gfc_conv_expr (&src, rhs);
-	      gfc_conv_expr (&len, sz);
-	      gfc_free_expr (sz);
-	      tmp = gfc_build_memcpy_call (dst.expr, src.expr, len.expr);
+	      gfc_add_block_to_block (&block, &src.pre);
+	      tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz);
 	    }
 	  else
 	    tmp = gfc_trans_assignment (gfc_expr_to_initialize (expr),
@@ -4108,8 +4105,7 @@ gfc_trans_allocate (gfc_code * code)
 	  gfc_conv_expr (&dst, expr);
 	  gfc_conv_expr (&src, init_e);
 	  gfc_add_block_to_block (&block, &src.pre);
-	  tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (&code->ext.alloc.ts));
-	  tmp = gfc_build_memcpy_call (dst.expr, src.expr, tmp);
+	  tmp = gfc_build_memcpy_call (dst.expr, src.expr, memsz);
 	  gfc_add_expr_to_block (&block, tmp);
 	}
       /* Add default initializer for those derived types that need them.  */
@@ -4127,6 +4123,7 @@ gfc_trans_allocate (gfc_code * code)
       if (expr->ts.type == BT_CLASS)
 	{
 	  gfc_expr *lhs,*rhs;
+	  gfc_se lse;
 	  /* Initialize VINDEX for CLASS objects.  */
 	  lhs = gfc_expr_to_initialize (expr);
 	  gfc_add_component_ref (lhs, "$vindex");
@@ -4158,36 +4155,11 @@ gfc_trans_allocate (gfc_code * code)
 	  /* Initialize SIZE for CLASS objects.  */
 	  lhs = gfc_expr_to_initialize (expr);
 	  gfc_add_component_ref (lhs, "$size");
-	  rhs = NULL;
-	  if (code->expr3 && code->expr3->ts.type == BT_CLASS)
-	    {
-	      /* Size must be determined at run time.  */
-	      rhs = gfc_copy_expr (code->expr3);
-	      gfc_add_component_ref (rhs, "$size");
-	      tmp = gfc_trans_assignment (lhs, rhs, false);
-	      gfc_add_expr_to_block (&block, tmp);
-	    }
-	  else
-	    {
-	      /* Size is fixed at compile time.  */
-	      gfc_typespec *ts;
-	      gfc_se lse;
-	      gfc_init_se (&lse, NULL);
-	      gfc_conv_expr (&lse, lhs);
-	      if (code->expr3)
-		ts = &code->expr3->ts;
-	      else if (code->ext.alloc.ts.type == BT_DERIVED)
-		ts = &code->ext.alloc.ts;
-	      else if (expr->ts.type == BT_CLASS)
-		ts = &expr->ts.u.derived->components->ts;
-	      else
-		ts = &expr->ts;
-	      tmp = TYPE_SIZE_UNIT (gfc_typenode_for_spec (ts));
-	      gfc_add_modify (&block, lse.expr,
-			      fold_convert (TREE_TYPE (lse.expr), tmp));
-	    }
+	  gfc_init_se (&lse, NULL);
+	  gfc_conv_expr (&lse, lhs);
+	  gfc_add_modify (&block, lse.expr,
+			  fold_convert (TREE_TYPE (lse.expr), memsz));
 	  gfc_free_expr (lhs);
-	  gfc_free_expr (rhs);
 	}
 
     }
Index: gcc/fortran/trans.c
===================================================================
--- gcc/fortran/trans.c	(Revision 153542)
+++ gcc/fortran/trans.c	(Arbeitskopie)
@@ -1281,9 +1281,7 @@ gfc_trans_code (gfc_code * code)
 
       if (res != NULL_TREE && ! IS_EMPTY_STMT (res))
 	{
-	  if (TREE_CODE (res) == STATEMENT_LIST)
-	    tree_annotate_all_with_location (&res, input_location);
-	  else
+	  if (TREE_CODE (res) != STATEMENT_LIST)
 	    SET_EXPR_LOCATION (res, input_location);
 	    
 	  /* Add the new statement to the block.  */
Index: gcc/gimplify.c
===================================================================
--- gcc/gimplify.c	(Revision 153542)
+++ gcc/gimplify.c	(Arbeitskopie)
@@ -777,24 +777,7 @@ should_carry_location_p (gimple gs)
   return true;
 }
 
-/* Same, but for a tree.  */
 
-static bool
-tree_should_carry_location_p (const_tree stmt)
-{
-  /* Don't emit a line note for a label.  We particularly don't want to
-     emit one for the break label, since it doesn't actually correspond
-     to the beginning of the loop/switch.  */
-  if (TREE_CODE (stmt) == LABEL_EXPR)
-    return false;
-
-  /* Do not annotate empty statements, since it confuses gcov.  */
-  if (!TREE_SIDE_EFFECTS (stmt))
-    return false;
-
-  return true;
-}
-
 /* Return true if a location should not be emitted for this statement
    by annotate_one_with_location.  */
 
@@ -826,17 +809,7 @@ annotate_one_with_location (gimple gs, location_t
     gimple_set_location (gs, location);
 }
 
-/* Same, but for tree T.  */
 
-static void
-tree_annotate_one_with_location (tree t, location_t location)
-{
-  if (CAN_HAVE_LOCATION_P (t)
-      && ! EXPR_HAS_LOCATION (t) && tree_should_carry_location_p (t))
-    SET_EXPR_LOCATION (t, location);
-}
-
-
 /* Set LOCATION for all the statements after iterator GSI in sequence
    SEQ.  If GSI is pointing to the end of the sequence, start with the
    first statement in SEQ.  */
@@ -872,30 +845,7 @@ annotate_all_with_location (gimple_seq stmt_p, loc
     }
 }
 
-/* Same, but for statement or statement list in *STMT_P.  */
 
-void
-tree_annotate_all_with_location (tree *stmt_p, location_t location)
-{
-  tree_stmt_iterator i;
-
-  if (!*stmt_p)
-    return;
-
-  for (i = tsi_start (*stmt_p); !tsi_end_p (i); tsi_next (&i))
-    {
-      tree t = tsi_stmt (i);
-
-      /* Assuming we've already been gimplified, we shouldn't
-	  see nested chaining constructs anymore.  */
-      gcc_assert (TREE_CODE (t) != STATEMENT_LIST
-		  && TREE_CODE (t) != COMPOUND_EXPR);
-
-      tree_annotate_one_with_location (t, location);
-    }
-}
-
-
 /* Similar to copy_tree_r() but do not copy SAVE_EXPR or TARGET_EXPR nodes.
    These nodes model computations that should only be done once.  If we
    were to unshare something like SAVE_EXPR(i++), the gimplification
Index: gcc/gimple.h
===================================================================
--- gcc/gimple.h	(Revision 153542)
+++ gcc/gimple.h	(Arbeitskopie)
@@ -939,7 +939,6 @@ extern tree create_tmp_var (tree, const char *);
 extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *);
 extern tree get_formal_tmp_var (tree, gimple_seq *);
 extern void declare_vars (tree, gimple, bool);
-extern void tree_annotate_all_with_location (tree *, location_t);
 extern void annotate_all_with_location (gimple_seq, location_t);
 
 /* Validation of GIMPLE expressions.  Note that these predicates only check

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