From 8aeb42d06b31988d1cae8c5c8200fc2650d3e16a Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Mon, 19 Nov 2001 00:13:36 +0000 Subject: [PATCH] re PR java/1401 (+= semantics not correct (when generating bytecode)) Fix for PR java/1401: * jcf-write.c (generate_bytecode_insns) [binop]: Handle case where arg0 is null. (generate_bytecode_insns) [MODIFY_EXPR]: Handle `OP=' case correctly. From-SVN: r47156 --- gcc/java/ChangeLog | 8 +++++++ gcc/java/jcf-write.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index d97977d..8c0a106 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,11 @@ +2001-11-18 Tom Tromey + + Fix for PR java/1401: + * jcf-write.c (generate_bytecode_insns) [binop]: Handle case where + arg0 is null. + (generate_bytecode_insns) [MODIFY_EXPR]: Handle `OP=' case + correctly. + 2001-11-18 Neil Booth * lang.c (finish_parse): Rename to java_finish. diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c index 4262f41..2d3e333 100644 --- a/gcc/java/jcf-write.c +++ b/gcc/java/jcf-write.c @@ -2034,6 +2034,61 @@ generate_bytecode_insns (exp, target, state) } else offset = 0; + + /* If the rhs is a binary expression and the left operand is + `==' to the lhs then we have an OP= expression. In this + case we must do some special processing. */ + if (TREE_CODE_CLASS (TREE_CODE (rhs)) == '2' + && lhs == TREE_OPERAND (rhs, 0)) + { + if (TREE_CODE (lhs) == COMPONENT_REF) + { + tree field = TREE_OPERAND (lhs, 1); + if (! FIELD_STATIC (field)) + { + /* Duplicate the object reference so we can get + the field. */ + emit_dup (TYPE_IS_WIDE (field) ? 2 : 1, 0, state); + NOTE_POP (1); + } + field_op (field, (FIELD_STATIC (field) + ? OPCODE_getstatic + : OPCODE_getfield), + state); + + NOTE_PUSH (TYPE_IS_WIDE (TREE_TYPE (field)) ? 2 : 1); + } + else if (TREE_CODE (lhs) == VAR_DECL + || TREE_CODE (lhs) == PARM_DECL) + { + if (FIELD_STATIC (lhs)) + { + field_op (lhs, OPCODE_getstatic, state); + NOTE_PUSH (TYPE_IS_WIDE (TREE_TYPE (lhs)) ? 2 : 1); + } + else + emit_load (lhs, state); + } + else if (TREE_CODE (lhs) == ARRAY_REF) + { + /* Duplicate the array and index, which are on the + stack, so that we can load the old value. */ + emit_dup (2, 0, state); + NOTE_POP (2); + jopcode = OPCODE_iaload + adjust_typed_op (TREE_TYPE (lhs), 7); + RESERVE (1); + OP1 (jopcode); + NOTE_PUSH (TYPE_IS_WIDE (TREE_TYPE (lhs)) ? 2 : 1); + } + else + abort (); + + /* This function correctly handles the case where the LHS + of a binary expression is NULL_TREE. */ + rhs = build (TREE_CODE (rhs), TREE_TYPE (rhs), + NULL_TREE, TREE_OPERAND (rhs, 1)); + } + generate_bytecode_insns (rhs, STACK_TARGET, state); if (target != IGNORE_TARGET) emit_dup (TYPE_IS_WIDE (type) ? 2 : 1 , offset, state); @@ -2112,7 +2167,11 @@ generate_bytecode_insns (exp, target, state) } else { - generate_bytecode_insns (arg0, target, state); + /* ARG0 will be NULL_TREE if we're handling an `OP=' + expression. In this case the stack already holds the + LHS. See the MODIFY_EXPR case. */ + if (arg0 != NULL_TREE) + generate_bytecode_insns (arg0, target, state); if (jopcode >= OPCODE_lshl && jopcode <= OPCODE_lushr) arg1 = convert (int_type_node, arg1); generate_bytecode_insns (arg1, target, state); -- 2.7.4