This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/46328] [OOP] type-bound operator call with non-trivial polymorphic operand
- From: "janus at gcc dot gnu.org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 31 Oct 2011 21:03:49 +0000
- Subject: [Bug fortran/46328] [OOP] type-bound operator call with non-trivial polymorphic operand
- Auto-submitted: auto-generated
- References: <bug-46328-4@http.gcc.gnu.org/bugzilla/>
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").