This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] java.util.StringTokenizer assumes order of parameterevaluation


Ranjit Mathew writes:
 > Sorry guys, but I just referred to the JLS (section 15.12.4.2,
 > "Evaluate Arguments"):
 > 
 > http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#45449
 > 
 > and I quote:
 > 
 > "The argument expressions are evaluated in order, from left to right..."
 > 
 > Therefore, the coder for StringTokenizer *can* assume the
 > order of evaluation - there must be some other problem that
 > I need to figure out.
 > 
 > BTW, does GCJ guarantee this order at all times? (I just saw
 > Andrew Haley's patch for a fix for *static* method invocation,
 > but the StringTokenizer problem is in a member method.)

Ah, here's another version of that patch.  I won't commit it because
it's not fully tested yet.

One thing that strikes me about this is that we could easily have
avoided all this pain by building a call like this:

{
   int temp0 = expr0...;
   int temp1 = expr1...;
   int temp2 = expr2...;
   foo (temp0, temp1, temp2);
}

instead of all this messing about with SAVE_EXPRs.  However, I don't
want to rewrite it right now.

Andrew.


2002-10-15  Andrew Haley  <aph@redhat.com>

	* parse.y (patch_invoke): Call force_evaluation_order on a static
	arg list.
	(resolve_qualified_expression_name): Call force_evaluation_order
	on a arg list that is part of a Qualified Expression Name.

	* lang.c (dump_compound_expr): New.
	(java_dump_tree): New.

Index: lang.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/lang.c,v
retrieving revision 1.112
diff -p -2 -c -r1.112 lang.c
*** lang.c	14 Oct 2002 18:12:12 -0000	1.112
--- lang.c	16 Oct 2002 12:57:13 -0000
*************** The Free Software Foundation is independ
*** 43,46 ****
--- 43,47 ----
  #include "tree-inline.h"
  #include "splay-tree.h"
+ #include "tree-dump.h"
  
  struct string_option
*************** static int inline_init_test_initializati
*** 75,78 ****
--- 76,80 ----
  						    void *));
  static bool java_can_use_bit_fields_p PARAMS ((void));
+ static int java_dump_tree PARAMS ((void *, tree));
  
  #ifndef TARGET_OBJECT_SUFFIX
*************** struct language_function GTY(())
*** 287,290 ****
--- 289,295 ----
  #define LANG_HOOKS_TREE_INLINING_WALK_SUBTREES java_tree_inlining_walk_subtrees
  
+ #undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
+ #define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN java_dump_tree
+ 
  /* Each front end provides its own.  */
  const struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER;
*************** java_inlining_map_static_initializers (f
*** 1042,1044 ****
--- 1047,1158 ----
  }
  
+ /* Avoid voluminous output for deep recursion of compound exprs.  */
+ 
+ static void
+ dump_compound_expr (di, t)
+      dump_info_p di;
+      tree t;
+ {
+   int i;
+ 
+   for (i=0; i<2; i++)
+     {
+       switch (TREE_CODE (TREE_OPERAND (t, i)))
+ 	{
+ 	case COMPOUND_EXPR:
+ 	  dump_compound_expr (di, TREE_OPERAND (t, i));
+ 	  break;
+ 
+ 	case EXPR_WITH_FILE_LOCATION:
+ 	    {
+ 	      tree wfl_node = EXPR_WFL_NODE (TREE_OPERAND (t, i));
+ 	      dump_child ("expr", wfl_node);
+ 	      break;
+ 	    }
+ 
+ 	default:
+ 	  dump_child ("expr", TREE_OPERAND (t, i));
+ 	}
+     }
+ }
+   
+ static int
+ java_dump_tree (dump_info, t)
+      void *dump_info;
+      tree t;
+ {
+   enum tree_code code;
+   dump_info_p di = (dump_info_p) dump_info;
+ 
+   /* Figure out what kind of node this is.  */
+   code = TREE_CODE (t);
+ 
+   switch (code)
+     {
+     case FUNCTION_DECL:
+       dump_child ("args", DECL_ARGUMENTS (t));
+       if (DECL_EXTERNAL (t))
+ 	dump_string (di, "undefined");
+       if (TREE_PUBLIC (t))
+ 	dump_string (di, "extern");
+       else
+ 	dump_string (di, "static");
+       if (DECL_LANG_SPECIFIC (t))
+ 	dump_child ("body", DECL_FUNCTION_BODY (t));
+       if (DECL_LANG_SPECIFIC (t) && !dump_flag (di, TDF_SLIM, t))
+ 	dump_child ("inline body", DECL_SAVED_TREE (t));
+       return 1;
+ 
+     case RETURN_EXPR:
+       dump_child ("expr", TREE_OPERAND (t, 0));
+       return 1;
+ 
+     case GOTO_EXPR:
+       dump_child ("goto", TREE_OPERAND (t, 0));
+       return 1;
+ 
+     case LABEL_EXPR:
+       dump_child ("label", TREE_OPERAND (t, 0));
+       return 1;
+ 
+     case LABELED_BLOCK_EXPR:
+       dump_child ("label", TREE_OPERAND (t, 0));
+       dump_child ("block", TREE_OPERAND (t, 1));
+       return 1;
+ 
+     case EXIT_BLOCK_EXPR:
+       dump_child ("block", TREE_OPERAND (t, 0));
+       dump_child ("val", TREE_OPERAND (t, 1));
+       return 1;
+ 
+     case BLOCK:
+       if (BLOCK_EXPR_BODY (t))
+ 	{
+ 	  tree local = BLOCK_VARS (t);
+ 	  while (local)
+ 	    {
+ 	      tree next = TREE_CHAIN (local);
+ 	      dump_child ("var", local);
+ 	      local = next;
+ 	    }
+ 	  
+ 	  {
+ 	    tree block = BLOCK_EXPR_BODY (t);
+ 	    dump_child ("body", block);
+ 	    block = TREE_CHAIN (block);
+ 	  }
+ 	}
+       return 1;
+       
+     case COMPOUND_EXPR:
+       if (!dump_flag (di, TDF_SLIM, t))
+ 	return 0;
+       dump_compound_expr (di, t);
+       return 1;
+ 
+     default:
+       break;
+     }
+   return 0;
+ }
  #include "gt-java-lang.h"
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.400
diff -p -2 -c -r1.400 parse.y
*** parse.y	9 Oct 2002 20:54:37 -0000	1.400
--- parse.y	16 Oct 2002 12:57:21 -0000
*************** dump_java_tree (phase, t)
*** 7440,7443 ****
--- 7440,7444 ----
  
    stream = dump_begin (phase, &flags);
+   flags |= TDF_SLIM;
    if (stream)
      {
*************** resolve_qualified_expression_name (wfl, 
*** 9505,9508 ****
--- 9506,9511 ----
  	  *type_found = type = QUAL_DECL_TYPE (*where_found);
  
+ 	  *where_found = force_evaluation_order (*where_found);
+ 
  	  /* If we're creating an inner class instance, check for that
  	     an enclosing instance is in scope */
*************** patch_invoke (patch, method, args)
*** 10786,10790 ****
        tree list;
        tree fndecl = current_function_decl;
!       tree save = save_expr (patch);
        tree type = TREE_TYPE (patch);
  
--- 10789,10796 ----
        tree list;
        tree fndecl = current_function_decl;
!       /* We have to call force_evaluation_order now because creating a
! 	 COMPOUND_EXPR wraps the arg list in a way that makes it
! 	 unrecognizable by force_evaluation_order later.  Yuk.  */
!       tree save = save_expr (force_evaluation_order (patch));
        tree type = TREE_TYPE (patch);
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]