http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46328

--- Comment #5 from janus at gcc dot gnu.org 2011-10-31 21:03:49 UTC ---
For the code in comment #2, there is actually a problem with the 'class_ok'
attribute, which can be fixed with the following patchlet:

Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c       (revision 180696)
+++ gcc/fortran/resolve.c       (working copy)
@@ -11497,6 +11497,8 @@ resolve_fl_derived0 (gfc_symbol *sym)
              c->attr.recursive = ifc->attr.recursive;
              c->attr.always_explicit = ifc->attr.always_explicit;
              c->attr.ext_attr |= ifc->attr.ext_attr;
+             if (c->ts.type == BT_CLASS)
+               c->attr.class_ok = ifc->attr.class_ok;
              /* Replace symbols in array spec.  */
              if (c->as)
                {

This gets us a bit further in 'matching_typebound_op' and changes the error on
comment #2 into an ICE.

What is further needed for comment #2, is to insert a temporary to evaluate the
call to x%t(), so that we can use the result as pass object and vptr base for
the 'multiply' generic. The following patchlet sketches where this could happen
(only flagging an ICE for the problematic case):

Index: gcc/fortran/interface.c
===================================================================
--- gcc/fortran/interface.c     (revision 180696)
+++ gcc/fortran/interface.c     (working copy)
@@ -3204,13 +3204,22 @@ build_compcall_for_operator (gfc_expr* e, gfc_actu
                             gfc_expr* base, gfc_typebound_proc* target,
                             const char *gname)
 {
-  e->expr_type = EXPR_COMPCALL;
-  e->value.compcall.tbp = target;
-  e->value.compcall.name = gname ? gname : "$op";
-  e->value.compcall.actual = actual;
-  e->value.compcall.base_object = base;
-  e->value.compcall.ignore_pass = 1;
-  e->value.compcall.assign = 0;
+  if (base->expr_type == EXPR_VARIABLE)
+    {
+      /* Generate a simple type-bound procedure call.  */
+      e->expr_type = EXPR_COMPCALL;
+      e->value.compcall.tbp = target;
+      e->value.compcall.name = gname ? gname : "$op";
+      e->value.compcall.actual = actual;
+      e->value.compcall.base_object = base;
+      e->value.compcall.ignore_pass = 1;
+      e->value.compcall.assign = 0;
+    }
+  else if (base->expr_type == EXPR_FUNCTION)
+    {
+      /* We need a temporary in order to evaluate the expression in two steps.
 */
+      gfc_error ("build_compcall_for_operator: We need a temporary at %L",
&e->where);
+    }
 }


The problem is that in 'build_compcall_for_operator', we only have access to
the operator expression. However, we need to replace the whole gfc_code (in
this case: the assignment "x=..."), preferentially by a BLOCK construct with a
local temporary.

In the case at hand, things are further complicated by the fact that we need to
replace the assignment itself by a type-bound call, too. Fortunately, this
replacement requires no additional temporary, since the passed object is simple
("x").

Reply via email to