new_rhs = save_expr (new_rhs);
patch_assignment (node, wfl_op1, wfl_op2)     tree node;     tree wfl_op1;     tree wfl_op2;{  tree rhs = TREE_OPERAND (node, 1);  tree lvalue = TREE_OPERAND (node, 0), llvalue;  tree lhs_type, rhs_type, new_rhs = NULL_TREE;  int error_found = 0;  int lvalue_from_array = 0;  /* Can't assign to a final. */  if (check_final_assignment (lvalue, wfl_op1))    error_found = 1;  EXPR_WFL_LINECOL (wfl_operator) = EXPR_WFL_LINECOL (node);  /* Lhs can be a named variable */  if (JDECL_P (lvalue))    {      lhs_type = TREE_TYPE (lvalue);    }  /* Or Lhs can be a array acccess. Should that be lvalue ? FIXME +     comment on reason why */  else if (TREE_CODE (wfl_op1) == ARRAY_REF)    {      lhs_type = TREE_TYPE (lvalue);      lvalue_from_array = 1;    }  /* Or a field access */  else if (TREE_CODE (lvalue) == COMPONENT_REF)    lhs_type = TREE_TYPE (lvalue);  /* Or a function return slot */  else if (TREE_CODE (lvalue) == RESULT_DECL)    lhs_type = TREE_TYPE (lvalue);  /* Otherwise, we might want to try to write into an optimized static     final, this is an of a different nature, reported further on. */  else if (TREE_CODE (wfl_op1) == EXPR_WITH_FILE_LOCATION	   && resolve_expression_name (wfl_op1, &llvalue))    {      if (check_final_assignment (llvalue, wfl_op1))	{	  /* What we should do instead is resetting the all the flags	     previously set, exchange lvalue for llvalue and continue. */	  error_found = 1;	  return error_mark_node;	}      else 	lhs_type = TREE_TYPE (lvalue);    }  else     {      parse_error_context (wfl_op1, "Invalid left hand side of assignment");      error_found = 1;    }  rhs_type = TREE_TYPE (rhs);  /* 5.1 Try the assignment conversion for builtin type. */  new_rhs = try_builtin_assignconv (wfl_op1, lhs_type, rhs);  /* 5.2 If it failed, try a reference conversion */  if (!new_rhs && (new_rhs = try_reference_assignconv (lhs_type, rhs)))    lhs_type = promote_type (rhs_type);  /* 15.25.2 If we have a compound assignment, convert RHS into the     type of the LHS */  else if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))    new_rhs = convert (lhs_type, rhs);  /* Explicit cast required. This is an error */  if (!new_rhs)    {      char *t1 = strdup (lang_printable_name (TREE_TYPE (rhs), 0));      char *t2 = strdup (lang_printable_name (lhs_type, 0));      tree wfl;      char operation [32];	/* Max size known */      /* If the assignment is part of a declaration, we use the WFL of	 the declared variable to point out the error and call it a	 declaration problem. If the assignment is a genuine =	 operator, we call is a operator `=' problem, otherwise we	 call it an assignment problem. In both of these last cases,	 we use the WFL of the operator to indicate the error. */      if (MODIFY_EXPR_FROM_INITIALIZATION_P (node))	{	  wfl = wfl_op1;	  strcpy (operation, "declaration");	}      else	{	  wfl = wfl_operator;	  if (COMPOUND_ASSIGN_P (TREE_OPERAND (node, 1)))	    strcpy (operation, "assignment");	  else if (TREE_CODE (TREE_OPERAND (node, 0)) == RESULT_DECL)	    strcpy (operation, "`return'");	  else	    strcpy (operation, "`='");	}      parse_error_context 	(wfl, (!valid_cast_to_p (rhs_type, lhs_type) ?	       "Incompatible type for %s. Can't convert `%s' to `%s'" :	       "Incompatible type for %s. Explicit cast "	       "needed to convert `%s' to `%s'"), operation, t1, t2);      free (t1); free (t2);      error_found = 1;    }  /* Inline read access to java.lang.PRIMTYPE.TYPE */  if (new_rhs)    new_rhs = maybe_build_primttype_type_ref (new_rhs, wfl_op2);  if (error_found)    return error_mark_node;  /* 10.10: Array Store Exception runtime check */  if (!flag_emit_class_files      && !flag_emit_xref      && lvalue_from_array       && JREFERENCE_TYPE_P (TYPE_ARRAY_ELEMENT (lhs_type))      && !CLASS_FINAL (TYPE_NAME (GET_SKIP_TYPE (rhs_type))))    {      tree check;      tree base = lvalue;      /* We need to retrieve the right argument for _Jv_CheckArrayStore */      if (TREE_CODE (lvalue) == COMPOUND_EXPR)	base = TREE_OPERAND (lvalue, 0);      else	{	  if (flag_bounds_check)	    base = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (base, 0), 1), 0);	  else	    base = TREE_OPERAND (TREE_OPERAND (base, 0), 0);	}      /* Build the invocation of _Jv_CheckArrayStore */      check = build (CALL_EXPR, void_type_node,		     build_address_of (soft_checkarraystore_node),		     tree_cons (NULL_TREE, base,				build_tree_list (NULL_TREE, new_rhs)),		     NULL_TREE);      TREE_SIDE_EFFECTS (check) = 1;      /* We have to decide on an insertion point */      if (TREE_CODE (lvalue) == COMPOUND_EXPR)	{	  tree t;	  if (flag_bounds_check)	    {	      t = TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0);	      TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (lvalue, 1), 0), 0) =		build (COMPOUND_EXPR, void_type_node, t, check);	    }	  else	    TREE_OPERAND (lvalue, 1) = build (COMPOUND_EXPR, lhs_type,					      check, TREE_OPERAND (lvalue, 1));	}      else 	{	  /* Make sure the bound check will happen before the store check */	  if (flag_bounds_check)	    TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0) =	      build (COMPOUND_EXPR, void_type_node,		     TREE_OPERAND (TREE_OPERAND (lvalue, 0), 0), check);	  else	    lvalue = build (COMPOUND_EXPR, lhs_type, check, lvalue);	}    }  TREE_OPERAND (node, 0) = lvalue;  TREE_OPERAND (node, 1) = new_rhs;  TREE_TYPE (node) = lhs_type;  return node;}