diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index f21e2a03286fbd1b9b47fe7d3951dfdb9b5f6fc1..7fe01831e138b7f07ee7189e67309dd8643eab3f 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -6,6 +6,11 @@
 	compression_method fields.
 	* zextract.c (read_zip_archive): Collect file compression info.
 
+2000-08-11  Alexandre Petit-Bianco  <apbianco@cygnus.com>
+
+	* parse.y (do_merge_string_cste): New locals. Create new
+	STRING_CSTs each time, use memcpy. Fixes gcj/311.
+
 2000-08-07  Hans Boehm  <boehm@acm.org>
 
 	* boehm.c (mark_reference_fields): Set marking bits for all words in
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index 4676153b92ef0b89a4422fc7c0bddcdb7df35c0d..d37a7f1b32b4a2186b5931214afc5e952bf026df 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -12892,20 +12892,26 @@ do_merge_string_cste (cste, string, string_len, after)
      const char *string;
      int string_len, after;
 {
-  int len = TREE_STRING_LENGTH (cste) + string_len;
   const char *old = TREE_STRING_POINTER (cste);
+  int old_len = TREE_STRING_LENGTH (cste);
+  int len = old_len + string_len;
+  char *new;
+  
+  cste = make_node (STRING_CST);
   TREE_STRING_LENGTH (cste) = len;
-  TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
+  new = TREE_STRING_POINTER (cste) = obstack_alloc (expression_obstack, len+1);
+
   if (after)
     {
-      strcpy (TREE_STRING_POINTER (cste), string);
-      strcat (TREE_STRING_POINTER (cste), old);
+      memcpy (new, string, string_len);
+      memcpy (&new [string_len], old, old_len);
     }
   else
     {
-      strcpy (TREE_STRING_POINTER (cste), old);
-      strcat (TREE_STRING_POINTER (cste), string);
+      memcpy (new, old, old_len);
+      memcpy (&new [old_len], string, string_len);
     }
+  new [len] = '\0';
   return cste;
 }