Patch: PR 1401

Tom Tromey tromey@redhat.com
Fri Oct 5 07:17:00 GMT 2001


This patch fixes PR 1401.

It works by noticing that when we have `LHS OP= RHS', then `LHS' is
the same as TREE_OPERAND(RHS, 0).  In this case we can simply compute
LHS once and use the value it yields.

It involves a minor hack to the `binop' processing.

I tested this on the test case in the PR.  I also rebuilt libgcj with
this patch with no problems.

Ok to commit?

Tom

Index: ChangeLog
from  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.

Index: jcf-write.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-write.c,v
retrieving revision 1.92
diff -u -r1.92 jcf-write.c
--- jcf-write.c 2001/11/08 15:33:39 1.92
+++ jcf-write.c 2001/11/15 19:06:18
@@ -2034,6 +2034,61 @@
 	  }
 	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 @@
 	}
       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);



More information about the Java-patches mailing list