This is the mail archive of the java@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]

Re: PR 1208



Tom Tromey writes:

> Is this patch ok for the trunk or just the branch?

Well: it fixes a bug and at the time didn't introduce any regressions,
so I guess it's good to go in the branch and the trunk. I remember
that I worked a bit on this patch. Here's what I found. I don't think
my contribution deserves an entry, it's just part of your patch.

./A

FIXME: My changes are minor but don't have an entry (this is Tom's
patch. My hunk covers:)

+			EXPR_WFL_LINECOL (wfl_operator) = 
+			  EXPR_WFL_LINECOL (exp);

and around.

Index: jcf-write.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/java/jcf-write.c,v
retrieving revision 1.70
diff -u -p -r1.70 jcf-write.c
--- jcf-write.c	2000/12/06 18:55:42	1.70
+++ jcf-write.c	2001/01/22 22:44:20
@@ -294,6 +294,8 @@ static struct jcf_block * get_jcf_label_
 static void put_linenumber PARAMS ((int, struct jcf_partial *));
 static void localvar_alloc PARAMS ((tree, struct jcf_partial *));
 static void localvar_free PARAMS ((tree, struct jcf_partial *));
+static struct localvar_info **localvar_finish PARAMS ((tree,
+						       struct jcf_partial *));
 static int get_access_flags PARAMS ((tree));
 static void write_chunks PARAMS ((FILE *, struct chunk *));
 static int adjust_typed_op PARAMS ((tree, int));
@@ -624,8 +626,13 @@ localvar_alloc (decl, state)
     }
 }
 
-static void
-localvar_free (decl, state)
+ /* Free a local variable, but keep it allocated. Basis of
+    `localvar_free', used as is in cases to avoid problems with
+    inappropriate variable reuse in some situations. Return the
+    localvar_info entry for the local var being retired.  */
+
+static struct localvar_info **
+localvar_finish (decl, state)
      tree decl;     
      struct jcf_partial *state;
 {
@@ -633,12 +640,26 @@ localvar_free (decl, state)
   int index = DECL_LOCAL_INDEX (decl);
   register struct localvar_info **ptr = &localvar_buffer [index];
   register struct localvar_info *info = *ptr;
-  int wide = TYPE_IS_WIDE (TREE_TYPE (decl));
 
   info->end_label = end_label;
 
   if (info->decl != decl)
-    abort ();
+   abort ();
+  
+  return ptr;
+}
+
+/* Free a local, destroying its entry, which allows it to be reused
+   when appropriate.  */
+ 
+static void
+localvar_free (decl, state)
+     tree decl;     
+     struct jcf_partial *state;
+{
+  int wide = TYPE_IS_WIDE (TREE_TYPE (decl));
+  struct localvar_info **ptr = localvar_finish (decl, state);
+
   ptr[0] = NULL;
   if (wide)
     {
@@ -1726,6 +1747,7 @@ generate_bytecode_insns (exp, target, st
 	else
 	  {
 	    HOST_WIDE_INT i;
+	    int found_error = 0;
 	    /* Copy the chain of relocs into a sorted array. */
 	    struct jcf_relocation **relocs = (struct jcf_relocation **)
 	      xmalloc (sw_state.num_cases * sizeof (struct jcf_relocation *));
@@ -1737,6 +1759,25 @@ generate_bytecode_insns (exp, target, st
 	    for (reloc = sw_state.cases;  reloc != NULL;  reloc = reloc->next)
 	      {
 		HOST_WIDE_INT case_value = reloc->offset;
+		struct jcf_relocation *r2;
+
+		/* Check for duplicates.  */
+		for (r2 = sw_state.cases; r2 != reloc; r2 = r2->next)
+		  {
+		    HOST_WIDE_INT v2 = r2->offset;
+		    if (case_value == v2 && reloc != r2)
+		      {
+			EXPR_WFL_LINECOL (wfl_operator) = 
+			  EXPR_WFL_LINECOL (exp);
+			parse_error_context (wfl_operator,
+			/* FIXME: we really should print the locations
+			   of the duplicate and of the original.  */
+					     "Duplicate case label: `%d",
+					     (int) case_value);
+			found_error = 1;
+		      }
+		  }
+
 		while (gap_end < sw_state.num_cases)
 		  {
 		    struct jcf_relocation *end = relocs[gap_end];
@@ -1757,8 +1798,12 @@ generate_bytecode_insns (exp, target, st
 		/* Note we don't check for duplicates.  FIXME! */
 	      }
 
-	    if (2 * sw_state.num_cases
-		>= sw_state.max_case - sw_state.min_case)
+	    if (found_error)
+	      {
+		/* Nothing.  */
+	      }
+	    else if (2 * sw_state.num_cases
+		     >= sw_state.max_case - sw_state.min_case)
 	      { /* Use tableswitch. */
 		int index = 0;
 		RESERVE (13 + 4 * (sw_state.max_case - sw_state.min_case + 1));
@@ -2392,7 +2437,7 @@ generate_bytecode_insns (exp, target, st
 	RESERVE (1);
 	OP1 (OPCODE_athrow);
 	NOTE_POP (1);
-	localvar_free (exception_decl, state);
+	localvar_finish (exception_decl, state);
 
 	/* The finally block.  First save return PC into return_link. */
 	define_jcf_label (finally_label, state);
@@ -2401,7 +2446,7 @@ generate_bytecode_insns (exp, target, st
 
 	generate_bytecode_insns (finally, IGNORE_TARGET, state);
 	maybe_wide (OPCODE_ret, DECL_LOCAL_INDEX (return_link), state);
-	localvar_free (return_link, state);
+	localvar_finish (return_link, state);
 	define_jcf_label (finished_label, state);
       }
       break;


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