diff options
author | Janus Weil <janus@gcc.gnu.org> | 2015-01-11 23:00:06 +0100 |
---|---|---|
committer | Janus Weil <janus@gcc.gnu.org> | 2015-01-11 23:00:06 +0100 |
commit | 517d78beb772c6a1a11e4952e1d51e49113e79dc (patch) | |
tree | fde48c9c70d6e157f37c7edee1084a3f26a10b8c /gcc/fortran/interface.c | |
parent | c34d453f05d09ff166db25491a6901a7a40fba5b (diff) | |
download | gcc-517d78beb772c6a1a11e4952e1d51e49113e79dc.zip gcc-517d78beb772c6a1a11e4952e1d51e49113e79dc.tar.gz gcc-517d78beb772c6a1a11e4952e1d51e49113e79dc.tar.bz2 |
re PR fortran/63733 ([OOP] wrong resolution for OPERATOR generics)
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.
From-SVN: r219440
Diffstat (limited to 'gcc/fortran/interface.c')
-rw-r--r-- | gcc/fortran/interface.c | 93 |
1 files changed, 44 insertions, 49 deletions
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index ca9751f..dd3ad2a 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -3720,6 +3720,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; @@ -3736,6 +3738,48 @@ 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) @@ -3786,58 +3830,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; } |