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

[Bug fortran/50981] [4.4/4.5/4.6 Regression] Wrong-code for scalarizing ELEMENTAL call with absent OPTIONAL argument


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


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