aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/expr.c39
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/data_char_2.f9012
4 files changed, 53 insertions, 10 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bea45a1..fcb8f00 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2006-01-31 Andrew Pinski <pinskia@physics.uc.edu>
+ PR middle-end/26001
+ * expr.c (expand_expr_real_1) <case ARRAY_REF>:
+ Use the corrected index for the character
+ out of the string constant.
+
+2006-01-31 Andrew Pinski <pinskia@physics.uc.edu>
+
* mode-switching.c (optimize_mode_switching): Fix size
allocated for bb_info[n_entities].
diff --git a/gcc/expr.c b/gcc/expr.c
index e10171f..362ab8b 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -7126,17 +7126,36 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
break;
}
}
- else if (TREE_CODE (init) == STRING_CST
- && 0 > compare_tree_int (index,
- TREE_STRING_LENGTH (init)))
+ else if(TREE_CODE (init) == STRING_CST)
{
- tree type = TREE_TYPE (TREE_TYPE (init));
- enum machine_mode mode = TYPE_MODE (type);
-
- if (GET_MODE_CLASS (mode) == MODE_INT
- && GET_MODE_SIZE (mode) == 1)
- return gen_int_mode (TREE_STRING_POINTER (init)
- [TREE_INT_CST_LOW (index)], mode);
+ tree index1 = index;
+ tree low_bound = array_ref_low_bound (exp);
+ index1 = fold_convert (sizetype, TREE_OPERAND (exp, 1));
+
+ /* Optimize the special-case of a zero lower bound.
+
+ We convert the low_bound to sizetype to avoid some problems
+ with constant folding. (E.g. suppose the lower bound is 1,
+ and its mode is QI. Without the conversion,l (ARRAY
+ +(INDEX-(unsigned char)1)) becomes ((ARRAY+(-(unsigned char)1))
+ +INDEX), which becomes (ARRAY+255+INDEX). Opps!) */
+
+ if (! integer_zerop (low_bound))
+ index1 = size_diffop (index1, fold_convert (sizetype,
+ low_bound));
+
+ if (0 > compare_tree_int (index1,
+ TREE_STRING_LENGTH (init)))
+ {
+ tree type = TREE_TYPE (TREE_TYPE (init));
+ enum machine_mode mode = TYPE_MODE (type);
+
+ if (GET_MODE_CLASS (mode) == MODE_INT
+ && GET_MODE_SIZE (mode) == 1)
+ return gen_int_mode (TREE_STRING_POINTER (init)
+ [TREE_INT_CST_LOW (index1)],
+ mode);
+ }
}
}
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6b5c659..50a2a7f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2006-01-31 Andrew Pinski <pinskia@physics.uc.edu>
+
+ PR middle-end/26001
+ * gfortran.dg/data_char_2.f90: New.
+
2006-01-31 Thomas Koenig <Thomas.Koenig@online.de>
PR fortran/26039
diff --git a/gcc/testsuite/gfortran.dg/data_char_2.f90 b/gcc/testsuite/gfortran.dg/data_char_2.f90
new file mode 100644
index 0000000..3e021b1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/data_char_2.f90
@@ -0,0 +1,12 @@
+! { dg-do run }
+! Test that getting a character from a
+! string data works.
+
+CHARACTER*10 INTSTR
+CHARACTER C1
+DATA INTSTR / '0123456789' /
+
+C1 = INTSTR(1:1)
+if(C1 .ne. '0') call abort()
+
+end