[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