diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2011-05-29 18:41:00 +0000 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2011-05-29 18:41:00 +0000 |
commit | fb03a37e57f31ad176cd901fcc39243d524d4cd4 (patch) | |
tree | 5226f832c787830f57624fc0a90fe130920aef55 /gcc/fortran/interface.c | |
parent | 427180d243e562912cc37f09b140a4d8c042ae4c (diff) | |
download | gcc-fb03a37e57f31ad176cd901fcc39243d524d4cd4.zip gcc-fb03a37e57f31ad176cd901fcc39243d524d4cd4.tar.gz gcc-fb03a37e57f31ad176cd901fcc39243d524d4cd4.tar.bz2 |
re PR fortran/45786 (Relational operators .eq. and == are not recognized as equivalent)
2011-05-29 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/45786
* interface.c (gfc_equivalent_op): New function.
(gfc_check_interface): Use gfc_equivalent_op instead
of switch statement.
* decl.c (access_attr_decl): Also set access to an
equivalent operator.
2011-05-29 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/45786
* gfortran.dg/operator_7.f90: New test case.
From-SVN: r174412
Diffstat (limited to 'gcc/fortran/interface.c')
-rw-r--r-- | gcc/fortran/interface.c | 122 |
1 files changed, 57 insertions, 65 deletions
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index 6575fbe..46f9d14 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -1264,6 +1264,54 @@ check_uop_interfaces (gfc_user_op *uop) } } +/* Given an intrinsic op, return an equivalent op if one exists, + or INTRINSIC_NONE otherwise. */ + +gfc_intrinsic_op +gfc_equivalent_op (gfc_intrinsic_op op) +{ + switch(op) + { + case INTRINSIC_EQ: + return INTRINSIC_EQ_OS; + + case INTRINSIC_EQ_OS: + return INTRINSIC_EQ; + + case INTRINSIC_NE: + return INTRINSIC_NE_OS; + + case INTRINSIC_NE_OS: + return INTRINSIC_NE; + + case INTRINSIC_GT: + return INTRINSIC_GT_OS; + + case INTRINSIC_GT_OS: + return INTRINSIC_GT; + + case INTRINSIC_GE: + return INTRINSIC_GE_OS; + + case INTRINSIC_GE_OS: + return INTRINSIC_GE; + + case INTRINSIC_LT: + return INTRINSIC_LT_OS; + + case INTRINSIC_LT_OS: + return INTRINSIC_LT; + + case INTRINSIC_LE: + return INTRINSIC_LE_OS; + + case INTRINSIC_LE_OS: + return INTRINSIC_LE; + + default: + return INTRINSIC_NONE; + } +} /* For the namespace, check generic, user operator and intrinsic operator interfaces for consistency and to remove duplicate @@ -1304,75 +1352,19 @@ gfc_check_interfaces (gfc_namespace *ns) for (ns2 = ns; ns2; ns2 = ns2->parent) { + gfc_intrinsic_op other_op; + if (check_interface1 (ns->op[i], ns2->op[i], 0, interface_name, true)) goto done; - switch (i) - { - case INTRINSIC_EQ: - if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_EQ_OS], - 0, interface_name, true)) goto done; - break; - - case INTRINSIC_EQ_OS: - if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_EQ], - 0, interface_name, true)) goto done; - break; - - case INTRINSIC_NE: - if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_NE_OS], - 0, interface_name, true)) goto done; - break; - - case INTRINSIC_NE_OS: - if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_NE], - 0, interface_name, true)) goto done; - break; - - case INTRINSIC_GT: - if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_GT_OS], - 0, interface_name, true)) goto done; - break; - - case INTRINSIC_GT_OS: - if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_GT], - 0, interface_name, true)) goto done; - break; - - case INTRINSIC_GE: - if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_GE_OS], - 0, interface_name, true)) goto done; - break; - - case INTRINSIC_GE_OS: - if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_GE], - 0, interface_name, true)) goto done; - break; - - case INTRINSIC_LT: - if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_LT_OS], - 0, interface_name, true)) goto done; - break; - - case INTRINSIC_LT_OS: - if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_LT], - 0, interface_name, true)) goto done; - break; - - case INTRINSIC_LE: - if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_LE_OS], - 0, interface_name, true)) goto done; - break; - - case INTRINSIC_LE_OS: - if (check_interface1 (ns->op[i], ns2->op[INTRINSIC_LE], - 0, interface_name, true)) goto done; - break; - - default: - break; - } + /* i should be gfc_intrinsic_op, but has to be int with this cast + here for stupid C++ compatibility rules. */ + other_op = gfc_equivalent_op ((gfc_intrinsic_op) i); + if (other_op != INTRINSIC_NONE + && check_interface1 (ns->op[i], ns2->op[other_op], + 0, interface_name, true)) + goto done; } } |