[Patch, Fortran, OOP] PR 63733: [4.8/4.9/5 Regression] wrong resolution for OPERATOR generics
Janus Weil
janus@gcc.gnu.org
Sun Jan 11 14:05:00 GMT 2015
Hi all,
this patch fixes a wrong-code regression related to operators, by
making sure that we look for typebound operators first, before looking
for non-typebound ones. (Note: Each typebound operator is also added
to the list of non-typebound ones, for reasons of diagnostics.)
Regtested on x86_64-unknown-linux-gnu. Ok for trunk? 4.9/4.8?
Cheers,
Janus
2015-01-11 Janus Weil <janus@gcc.gnu.org>
PR fortran/63733
* interface.c (gfc_extend_expr): Look for type-bound operators before
non-typebound ones.
2015-01-11 Janus Weil <janus@gcc.gnu.org>
PR fortran/63733
* gfortran.dg/typebound_operator_20.f90: New.
-------------- next part --------------
Index: gcc/fortran/interface.c
===================================================================
--- gcc/fortran/interface.c (Revision 219429)
+++ gcc/fortran/interface.c (Arbeitskopie)
@@ -3706,6 +3706,8 @@ gfc_extend_expr (gfc_expr *e)
gfc_user_op *uop;
gfc_intrinsic_op i;
const char *gname;
+ gfc_typebound_proc* tbo;
+ gfc_expr* tb_base;
sym = NULL;
@@ -3722,8 +3724,50 @@ gfc_extend_expr (gfc_expr *e)
i = fold_unary_intrinsic (e->value.op.op);
+ /* See if we find a matching type-bound operator. */
if (i == INTRINSIC_USER)
+ tbo = matching_typebound_op (&tb_base, actual,
+ i, e->value.op.uop->name, &gname);
+ else
+ switch (i)
+ {
+#define CHECK_OS_COMPARISON(comp) \
+ case INTRINSIC_##comp: \
+ case INTRINSIC_##comp##_OS: \
+ tbo = matching_typebound_op (&tb_base, actual, \
+ INTRINSIC_##comp, NULL, &gname); \
+ if (!tbo) \
+ tbo = matching_typebound_op (&tb_base, actual, \
+ INTRINSIC_##comp##_OS, NULL, &gname); \
+ break;
+ CHECK_OS_COMPARISON(EQ)
+ CHECK_OS_COMPARISON(NE)
+ CHECK_OS_COMPARISON(GT)
+ CHECK_OS_COMPARISON(GE)
+ CHECK_OS_COMPARISON(LT)
+ CHECK_OS_COMPARISON(LE)
+#undef CHECK_OS_COMPARISON
+
+ default:
+ tbo = matching_typebound_op (&tb_base, actual, i, NULL, &gname);
+ break;
+ }
+
+ /* If there is a matching typebound-operator, replace the expression with
+ a call to it and succeed. */
+ if (tbo)
{
+ gcc_assert (tb_base);
+ build_compcall_for_operator (e, actual, tb_base, tbo, gname);
+
+ if (!gfc_resolve_expr (e))
+ return MATCH_ERROR;
+ else
+ return MATCH_YES;
+ }
+
+ if (i == INTRINSIC_USER)
+ {
for (ns = gfc_current_ns; ns; ns = ns->parent)
{
uop = gfc_find_uop (e->value.op.uop->name, ns);
@@ -3772,58 +3816,9 @@ gfc_extend_expr (gfc_expr *e)
if (sym == NULL)
{
- gfc_typebound_proc* tbo;
- gfc_expr* tb_base;
-
- /* See if we find a matching type-bound operator. */
- if (i == INTRINSIC_USER)
- tbo = matching_typebound_op (&tb_base, actual,
- i, e->value.op.uop->name, &gname);
- else
- switch (i)
- {
-#define CHECK_OS_COMPARISON(comp) \
- case INTRINSIC_##comp: \
- case INTRINSIC_##comp##_OS: \
- tbo = matching_typebound_op (&tb_base, actual, \
- INTRINSIC_##comp, NULL, &gname); \
- if (!tbo) \
- tbo = matching_typebound_op (&tb_base, actual, \
- INTRINSIC_##comp##_OS, NULL, &gname); \
- break;
- CHECK_OS_COMPARISON(EQ)
- CHECK_OS_COMPARISON(NE)
- CHECK_OS_COMPARISON(GT)
- CHECK_OS_COMPARISON(GE)
- CHECK_OS_COMPARISON(LT)
- CHECK_OS_COMPARISON(LE)
-#undef CHECK_OS_COMPARISON
-
- default:
- tbo = matching_typebound_op (&tb_base, actual, i, NULL, &gname);
- break;
- }
-
- /* If there is a matching typebound-operator, replace the expression with
- a call to it and succeed. */
- if (tbo)
- {
- bool result;
-
- gcc_assert (tb_base);
- build_compcall_for_operator (e, actual, tb_base, tbo, gname);
-
- result = gfc_resolve_expr (e);
- if (!result)
- return MATCH_ERROR;
-
- return MATCH_YES;
- }
-
/* Don't use gfc_free_actual_arglist(). */
free (actual->next);
free (actual);
-
return MATCH_NO;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: typebound_operator_20.f90
Type: text/x-fortran
Size: 1109 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20150111/8845fc4c/attachment.bin>
More information about the Gcc-patches
mailing list