]> gcc.gnu.org Git - gcc.git/commitdiff
re PR java/1401 (+= semantics not correct (when generating bytecode))
authorTom Tromey <tromey@redhat.com>
Mon, 19 Nov 2001 00:13:36 +0000 (00:13 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Mon, 19 Nov 2001 00:13:36 +0000 (00:13 +0000)
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
gcc/java/jcf-write.c

index d97977d5b7966ceab8da6982b4f7416a2bbfb410..8c0a1064e4e51553658f0d745acccda2d1dd6e06 100644 (file)
@@ -1,3 +1,11 @@
+2001-11-18  Tom Tromey  <tromey@redhat.com>
+
+       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  <neil@daikokuya.demon.co.uk>
 
        * lang.c (finish_parse): Rename to java_finish.
index 4262f41078fcf5f9e79dee8cae43c98b92763197..2d3e333100faebc6541631b9b92747a85948c769 100644 (file)
@@ -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);
This page took 0.227567 seconds and 5 git commands to generate.