diff options
| author | bothner <bothner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-02-19 16:33:18 +0000 |
|---|---|---|
| committer | bothner <bothner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-02-19 16:33:18 +0000 |
| commit | 1629f3166294fa673ea904c40ea28e5a9b77a060 (patch) | |
| tree | f91030069f52afee0467bda834f76d3f91ecf256 /gcc/java/expr.c | |
| parent | 36393fed40090be90099cc1fe709100a2c8813c1 (diff) | |
| download | ppe42-gcc-1629f3166294fa673ea904c40ea28e5a9b77a060.tar.gz ppe42-gcc-1629f3166294fa673ea904c40ea28e5a9b77a060.zip | |
Force left-to-right evaluation of binary operations etc.
* expr.c (force_evaluation_order), java-tree.h: New function.
* parse.y (java_complete_lhs): Pass binary operations, procedure
calls, and ARRAY_REFs to force_evaluation_order.
(various): Set TREE_SIDE_EFFECTS more carefully.
Tolerate random (non-UTF8) encoding in comments without complaining.
* lex.c (java_read_char): Return 0xFFFE if bad UTF8 encoding.
(java_is_eol): Handle '\r' followed by '\n' instead of vice versa.
* parse.y (resolve_qualified_expression_name): Handle error_mark.
(java_complete_node case EXPR_WITH_FILE_LOCATION): Likewise.
* parse.y (java_complete_lhs): Ignore an empty statement in a
COMPOUND_EXPR. Don't complain about empty statement after return.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@25326 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java/expr.c')
| -rw-r--r-- | gcc/java/expr.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/gcc/java/expr.c b/gcc/java/expr.c index aeded3a4181..0848806ac5b 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -29,6 +29,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ #include "tree.h" #include "real.h" #include "rtl.h" +#include "flags.h" #include "expr.h" #include "java-tree.h" #include "javaop.h" @@ -2470,3 +2471,49 @@ process_jvm_instruction (PC, byte_ops, length) } return PC; } + +/* Force the (direct) sub-operands of NODE to be evaluated in left-to-right + order, as specified by Java Language Specification. + + The problem is that while expand_expr will evaluate its sub-operands in + left-to-right order, for variables it will just return an rtx (i.e. + an lvalue) for the variable (rather than an rvalue). So it is possible + that a later sub-operand will change the register, and when the + actual operation is done, it will use the new value, when it should + have used the original value. + + We fix this by using save_expr. This forces the sub-operand to be + copied into a fresh virtual register, +*/ + +tree +force_evaluation_order (node) + tree node; +{ + if (flag_syntax_only) + return node; + if (TREE_CODE_CLASS (TREE_CODE (node)) == '2' + && TREE_CODE (node) == ARRAY_REF) + { + if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1))) + TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0)); + } + else if (TREE_CODE (node) == CALL_EXPR || TREE_CODE (node) == NEW_CLASS_EXPR) + { + tree last_side_effecting_arg = NULL_TREE; + tree arg = TREE_OPERAND (node, 1); + for (; arg != NULL_TREE; arg = TREE_CHAIN (arg)) + { + if (TREE_SIDE_EFFECTS (TREE_VALUE (arg))) + last_side_effecting_arg = arg; + } + arg = TREE_OPERAND (node, 1); + for (; arg != NULL_TREE; arg = TREE_CHAIN (arg)) + { + if (arg == last_side_effecting_arg) + break; + TREE_VALUE (arg) = save_expr (TREE_VALUE (arg)); + } + } + return node; +} |

