aboutsummaryrefslogtreecommitdiff
path: root/gcc/java/jcf-write.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2001-11-19 00:13:36 +0000
committerTom Tromey <tromey@gcc.gnu.org>2001-11-19 00:13:36 +0000
commit8aeb42d06b31988d1cae8c5c8200fc2650d3e16a (patch)
tree74f7255a1621b75d125be3749271ff8bdc41d0f4 /gcc/java/jcf-write.c
parent604407070be6a945b7ccfe3fa89e51cfe112614f (diff)
downloadgcc-8aeb42d06b31988d1cae8c5c8200fc2650d3e16a.zip
gcc-8aeb42d06b31988d1cae8c5c8200fc2650d3e16a.tar.gz
gcc-8aeb42d06b31988d1cae8c5c8200fc2650d3e16a.tar.bz2
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
Diffstat (limited to 'gcc/java/jcf-write.c')
-rw-r--r--gcc/java/jcf-write.c61
1 files changed, 60 insertions, 1 deletions
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);