This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/50981] [4.4/4.5/4.6 Regression] Wrong-code for scalarizing ELEMENTAL call with absent OPTIONAL argument
- From: "mikael at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Wed, 11 Jan 2012 23:31:32 +0000
- Subject: [Bug fortran/50981] [4.4/4.5/4.6 Regression] Wrong-code for scalarizing ELEMENTAL call with absent OPTIONAL argument
- Auto-submitted: auto-generated
- References: <bug-50981-4@http.gcc.gnu.org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50981
--- Comment #18 from Mikael Morin <mikael at gcc dot gnu.org> 2012-01-11 23:31:32 UTC ---
(In reply to comment #17)
> I think the proper solution is to remove the trans-stmt.c manual scalarization
> and handle somewhere in trans-{array,expr}.c the array bounds.
>
Some of it might actually be dead code. I don't see where the `temp' variable
is used.
> Stupid attempts fail for various reasons: Changing the BT_CLASS to BT_DERIVED
> in gfc_trans_allocate does not work as one the offsets will no longer be
> class._size (why?). Keeping BT_CLASS but removing the gfc_add_data_component > in trans-stmt.c will ICE for dataref - and removing that as well will lead to
> valid code with class._size, but without scalarization loop ...
Below is my `stupid' attempt at the not-so-proper solution: it does an
`intelligent' e->ts.type == BT_CLASS in the new conditions in
gfc_conv_procedure_call. It passes gfortran.dg/*elemental* and
gfortran.dg/*class*. But it is admittedly somewhat hackish.
diff --git a/trans-expr.c b/trans-expr.c
index a2268a1..1a24d4b 100644
--- a/trans-expr.c
+++ b/trans-expr.c
@@ -3259,6 +3259,35 @@ conv_isocbinding_procedure (gfc_se * se, gfc_symbol *
sym,
}
+static bool
+needs_class_data_ref (gfc_expr *e)
+{
+ gfc_ref *ref;
+ bool result;
+
+ if (e->expr_type != EXPR_VARIABLE)
+ return false;
+
+ if (e->symtree->n.sym->ts.type == BT_CLASS)
+ result = true;
+
+ for (ref = e->ref; ref; ref = ref->next)
+ {
+ if (ref->type != REF_COMPONENT)
+ {
+ result = false;
+ continue;
+ }
+
+ if (ref->u.c.component->ts.type == BT_CLASS)
+ result = true;
+ else if (!strcmp (ref->u.c.component->name, "_data"))
+ result = false;
+ }
+
+ return result;
+}
+
/* Generate code for a procedure call. Note can return se->post != NULL.
If se->direct_byref is set then se->expr contains the return parameter.
Return nonzero, if the call has alternate specifiers.
@@ -3435,7 +3464,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
else
gfc_conv_expr_reference (&parmse, e);
- if (fsym && fsym->ts.type == BT_DERIVED && e->ts.type == BT_CLASS)
+ if (fsym && fsym->ts.type == BT_DERIVED && needs_class_data_ref (e))
parmse.expr = gfc_class_data_get (parmse.expr);
/* The scalarizer does not repackage the reference to a class
@@ -3514,7 +3543,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
if (fsym && fsym->ts.type == BT_DERIVED
- && e->ts.type == BT_CLASS)
+ && needs_class_data_ref (e))
parmse.expr = gfc_class_data_get (parmse.expr);
/* A class array element needs converting back to be a