[Patch, fortran] [1/5] PR 45586: VIEW_CONVERT_EXPR wrapping

Mikael Morin mikael.morin@sfr.fr
Fri Aug 24 15:13:00 GMT 2012


This patch avoids fold_convert bombing when the types are not variants of the
same base type.  It is necessary to avoid regressing with the next patch.
It tries to take the VIEW_CONVERT_EXPR path only when it is necessary and
use the usual fold_convert otherwise.  I use gfc_nonrestricted_type in one
assertion, so I had to make it public

For what it's worth, I had another version of this patch which tried harder to
not use VIEW_CONVERT_EXPR by carefully avoiding copying the data pointer
(which is overwritten just after anyway). However, as I didn't want to pull
in the scalarizer to assign arrays, I couldn't avoid VIEW_CONVERT_EXPR in
all cases, so I finally preferred this (simpler) patch.

OK?
-------------- next part --------------
2012-08-22  Mikael Morin  <mikael@gcc.gnu.org>

	PR fortran/45586
	* trans-expr.c (gfc_trans_scalar_assign): Wrap in a VIEW_CONVERT_EXPR
	node if the types don't match.
	* trans-types.c (gfc_nonrestricted_type): Make non-static.
	* trans.h (gfc_nonrestricted_type): New declaration.
-------------- next part --------------
diff --git a/trans-expr.c b/trans-expr.c
index ebaa238..9dab898 100644
--- a/trans-expr.c
+++ b/trans-expr.c
@@ -6396,8 +6396,24 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
       gfc_add_block_to_block (&block, &rse->pre);
       gfc_add_block_to_block (&block, &lse->pre);
 
-      gfc_add_modify (&block, lse->expr,
-			   fold_convert (TREE_TYPE (lse->expr), rse->expr));
+      tree converted = NULL_TREE;
+      if (TYPE_MAIN_VARIANT (TREE_TYPE (lse->expr))
+	  != TYPE_MAIN_VARIANT (TREE_TYPE (rse->expr))
+	  && !POINTER_TYPE_P (TREE_TYPE (lse->expr))
+	  && !POINTER_TYPE_P (TREE_TYPE (rse->expr)))
+	{
+	  gcc_assert (TYPE_CANONICAL (TREE_TYPE (lse->expr))
+		      == TYPE_CANONICAL (TREE_TYPE (rse->expr))
+		      && gfc_nonrestricted_type (TREE_TYPE (lse->expr))
+			 == gfc_nonrestricted_type (TREE_TYPE (rse->expr)));
+	  /* fold_convert won't like this.  Let's bypass it.  */
+	  converted = fold_build1_loc (input_location, VIEW_CONVERT_EXPR,
+				       TREE_TYPE (lse->expr), rse->expr);
+	}
+      else
+	converted = fold_convert (TREE_TYPE (lse->expr), rse->expr);
+
+      gfc_add_modify (&block, lse->expr, converted);
 
       /* Do a deep copy if the rhs is a variable, if it is not the
 	 same as the lhs.  */
diff --git a/trans-types.c b/trans-types.c
index 3286a5a..a6e5d99 100644
--- a/trans-types.c
+++ b/trans-types.c
@@ -1924,7 +1924,6 @@ gfc_build_pointer_type (gfc_symbol * sym, tree type)
     return build_pointer_type (type);
 }
 
-static tree gfc_nonrestricted_type (tree t);
 /* Given two record or union type nodes TO and FROM, ensure
    that all fields in FROM have a corresponding field in TO,
    their type being nonrestrict variants.  This accepts a TO
@@ -1973,7 +1972,7 @@ mirror_fields (tree to, tree from)
 /* Given a type T, returns a different type of the same structure,
    except that all types it refers to (recursively) are always
    non-restrict qualified types.  */
-static tree
+tree
 gfc_nonrestricted_type (tree t)
 {
   tree ret = t;
diff --git a/trans.h b/trans.h
index 9818ceb..56b6c2f 100644
--- a/trans.h
+++ b/trans.h
@@ -639,6 +639,7 @@ tree getdecls (void);
 /* In trans-types.c.  */
 struct array_descr_info;
 bool gfc_get_array_descr_info (const_tree, struct array_descr_info *);
+tree gfc_nonrestricted_type (tree);
 
 /* In trans-openmp.c */
 bool gfc_omp_privatize_by_reference (const_tree);


More information about the Gcc-patches mailing list