aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/dependency.c
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2010-10-10 09:52:46 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2010-10-10 09:52:46 +0000
commit32af57e2269904ec2a56a9918f8a054e60aa5ef4 (patch)
tree181b725b890dbb124284cde97e1b23d530440a07 /gcc/fortran/dependency.c
parent0e88eb86942d9693ac6f73f22bcbad387a40ae77 (diff)
downloadgcc-32af57e2269904ec2a56a9918f8a054e60aa5ef4.zip
gcc-32af57e2269904ec2a56a9918f8a054e60aa5ef4.tar.gz
gcc-32af57e2269904ec2a56a9918f8a054e60aa5ef4.tar.bz2
frontend-passes.c: Include opts.h.
2010-10-09 Thomas Koenig <tkoenig@gcc.gnu.org> * frontend-passes.c: Include opts.h. (optimize_comparison): Renamed from optimize_equality. Change second argument to operation to be compared. Use flag_finite_math_only to avoid comparing REAL and COMPLEX only when NANs are honored. Simplify comparing of string concatenations where left or right operands are equal. Simplify all comparison operations, based on the result of gfc_dep_compare_expr. * dependency.c: Include arith.h. (gfc_are_identical_variables): Volatile variables should not compare equal to themselves. (gfc_dep_compare_expr): Handle string constants and string concatenations. 2010-10-09 Thomas Koenig <tkoenig@gcc.gnu.org> * gfortran.dg/character_comparison_4.f90: New test. * gfortran.dg/character_comparison_5.f90: New test. * gfortran.dg/character_comparison_6.f90: New test. From-SVN: r165248
Diffstat (limited to 'gcc/fortran/dependency.c')
-rw-r--r--gcc/fortran/dependency.c46
1 files changed, 46 insertions, 0 deletions
diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c
index ee66d21..40969f6 100644
--- a/gcc/fortran/dependency.c
+++ b/gcc/fortran/dependency.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "gfortran.h"
#include "dependency.h"
#include "constructor.h"
+#include "arith.h"
/* static declarations */
/* Enums */
@@ -125,6 +126,11 @@ gfc_are_identical_variables (gfc_expr *e1, gfc_expr *e2)
if (e1->symtree->n.sym != e2->symtree->n.sym)
return false;
+ /* Volatile variables should never compare equal to themselves. */
+
+ if (e1->symtree->n.sym->attr.volatile_)
+ return false;
+
r1 = e1->ref;
r2 = e2->ref;
@@ -306,6 +312,42 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
}
}
+ /* Compare A // B vs. C // D. */
+
+ if (e1->expr_type == EXPR_OP && e1->value.op.op == INTRINSIC_CONCAT
+ && e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_CONCAT)
+ {
+ int l, r;
+
+ l = gfc_dep_compare_expr (e1->value.op.op1, e2->value.op.op1);
+ r = gfc_dep_compare_expr (e1->value.op.op2, e2->value.op.op2);
+
+ if (l == -2)
+ return -2;
+
+ if (l == 0)
+ {
+ /* Watch out for 'A ' // x vs. 'A' // x. */
+ gfc_expr *e1_left = e1->value.op.op1;
+ gfc_expr *e2_left = e2->value.op.op1;
+
+ if (e1_left->expr_type == EXPR_CONSTANT
+ && e2_left->expr_type == EXPR_CONSTANT
+ && e1_left->value.character.length
+ != e2_left->value.character.length)
+ return -2;
+ else
+ return r;
+ }
+ else
+ {
+ if (l != 0)
+ return l;
+ else
+ return r;
+ }
+ }
+
/* Compare X vs. X-C. */
if (e2->expr_type == EXPR_OP && e2->value.op.op == INTRINSIC_MINUS)
{
@@ -321,6 +363,10 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
switch (e1->expr_type)
{
case EXPR_CONSTANT:
+ /* Compare strings for equality. */
+ if (e1->ts.type == BT_CHARACTER && e2->ts.type == BT_CHARACTER)
+ return gfc_compare_string (e1, e2);
+
if (e1->ts.type != BT_INTEGER || e2->ts.type != BT_INTEGER)
return -2;