diff options
author | Paul Brook <paul@codesourcery.com> | 2006-03-02 19:38:43 +0000 |
---|---|---|
committer | Paul Brook <paul@codesourcery.com> | 2006-03-02 19:38:43 +0000 |
commit | fc448c490975feae3e2c3fadb6e1231fd84d9461 (patch) | |
tree | b7b3d985d2c3a4638fd66a298c98b23f50d02fa9 /gcc/expr.c | |
parent | b7b4b172d05b06a4854245eda25a42d067a1ce04 (diff) |
Merge from gcc-4_1-branch revision 111560 (gcc-4_1_0-release)
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/csl/sourcerygxx-4_1@111645 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/expr.c')
-rw-r--r-- | gcc/expr.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/gcc/expr.c b/gcc/expr.c index 04549d4e4e1..9f7e7bb45d2 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -7095,17 +7095,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); + } } } } |