diff -uNr gcc-4061.orig/gcc/fortran/arith.c gcc-4061/gcc/fortran/arith.c
--- gcc-4061.orig/gcc/fortran/arith.c	2004-11-11 10:14:34.000000000 +0900
+++ gcc-4061/gcc/fortran/arith.c	2005-05-28 21:35:43.000000000 +0900
@@ -2189,3 +2189,96 @@
 
   return result;
 }
+
+/* Convert Hollerith to integer. */
+
+gfc_expr *
+gfc_hollerith2int (gfc_expr * src, int kind)
+{
+  gfc_expr *result;
+  int len;
+
+  len = src->value.character.length;
+
+  result = gfc_get_expr ();
+  result->expr_type = EXPR_CONSTANT;
+  result->ts.type = BT_INTEGER;
+  result->ts.kind = kind;
+  result->where = src->where;
+  result->from_H = 1;
+
+  if (len > kind)
+    {
+      gfc_warning ("The Hollerith constant at %L is too long to convert to %s",
+		&src->where, gfc_typename(&result->ts));
+      len = kind;
+    }
+  result->value.character.string = gfc_getmem (len + 1);
+  memcpy (result->value.character.string, src->value.character.string, len);
+  result->value.character.string[len] = '\0';
+  result->value.character.length = len;
+
+  return result;
+}
+
+/* Convert Hollerith to real. */
+
+gfc_expr *
+gfc_hollerith2real (gfc_expr * src, int kind)
+{
+  gfc_expr *result;
+  int len;
+
+  len = src->value.character.length;
+
+  result = gfc_get_expr ();
+  result->expr_type = EXPR_CONSTANT;
+  result->ts.type = BT_REAL;
+  result->ts.kind = kind;
+  result->where = src->where;
+  result->from_H = 1;
+
+  if (len > kind)
+    {
+      gfc_warning ("The Hollerith constant at %L is too long to convert to %s",
+		&src->where, gfc_typename(&result->ts));
+      len = kind;
+    }
+  result->value.character.string = gfc_getmem (len + 1);
+  memcpy (result->value.character.string, src->value.character.string, len);
+  result->value.character.string[len] = '\0';
+  result->value.character.length = len;
+
+  return result;
+}
+
+/* Convert Hollerith to complex. */
+
+gfc_expr *
+gfc_hollerith2complex (gfc_expr * src, int kind)
+{
+  gfc_expr *result;
+  int len;
+
+  len = src->value.character.length;
+
+  result = gfc_get_expr ();
+  result->expr_type = EXPR_CONSTANT;
+  result->ts.type = BT_COMPLEX;
+  result->ts.kind = kind;
+  result->where = src->where;
+  result->from_H = 1;
+
+  if (len > kind*2)
+    {
+      gfc_warning ("The Hollerith constant at %L is too long to convert to %s",
+		&src->where, gfc_typename(&result->ts));
+      len = kind*2;
+    }
+  result->value.character.string = gfc_getmem (len + 1);
+  memcpy (result->value.character.string, src->value.character.string, len);
+  result->value.character.string[len] = '\0';
+  result->value.character.length = len;
+
+  return result;
+}
diff -uNr gcc-4061.orig/gcc/fortran/arith.h gcc-4061/gcc/fortran/arith.h
--- gcc-4061.orig/gcc/fortran/arith.h	2004-08-19 06:58:33.000000000 +0900
+++ gcc-4061/gcc/fortran/arith.h	2005-05-28 21:35:43.000000000 +0900
@@ -80,6 +80,9 @@
 gfc_expr *gfc_complex2real (gfc_expr *, int);
 gfc_expr *gfc_complex2complex (gfc_expr *, int);
 gfc_expr *gfc_log2log (gfc_expr *, int);
+gfc_expr *gfc_hollerith2int (gfc_expr *, int);
+gfc_expr *gfc_hollerith2real (gfc_expr *, int);
+gfc_expr *gfc_hollerith2complex (gfc_expr *, int);
 
 #endif /* GFC_ARITH_H  */
 
diff -uNr gcc-4061.orig/gcc/fortran/expr.c gcc-4061/gcc/fortran/expr.c
--- gcc-4061.orig/gcc/fortran/expr.c	2004-09-16 08:45:15.000000000 +0900
+++ gcc-4061/gcc/fortran/expr.c	2005-05-28 21:35:43.000000000 +0900
@@ -147,6 +147,12 @@
   switch (e->expr_type)
     {
     case EXPR_CONSTANT:
+      if (e->from_H)
+	{
+	  gfc_free (e->value.character.string);
+	  break;
+	}
+
       switch (e->ts.type)
 	{
 	case BT_INTEGER:
@@ -158,6 +164,7 @@
 	  break;
 
 	case BT_CHARACTER:
+	case BT_HOLLERITH:
 	  gfc_free (e->value.character.string);
 	  break;
 
@@ -402,6 +409,15 @@
       break;
 
     case EXPR_CONSTANT:
+      if (p->from_H)
+	{
+	  s = gfc_getmem (p->value.character.length + 1);
+	  q->value.character.string = s;
+
+	  memcpy (s, p->value.character.string,
+		  p->value.character.length + 1);
+	  break;
+	}
       switch (q->ts.type)
 	{
 	case BT_INTEGER:
@@ -423,6 +439,7 @@
 	  break;
 
 	case BT_CHARACTER:
+	case BT_HOLLERITH:
 	  s = gfc_getmem (p->value.character.length + 1);
 	  q->value.character.string = s;
 
@@ -1820,7 +1837,8 @@
 
   if (!conform)
     {
-      if (gfc_numeric_ts (&lvalue->ts) && gfc_numeric_ts (&rvalue->ts))
+      if (gfc_numeric_ts (&lvalue->ts)
+	&& (gfc_numeric_ts (&rvalue->ts) || rvalue->ts.type == BT_HOLLERITH))
 	return SUCCESS;
 
       gfc_error ("Incompatible types in assignment at %L, %s to %s",
diff -uNr gcc-4061.orig/gcc/fortran/gfortran.h gcc-4061/gcc/fortran/gfortran.h
--- gcc-4061.orig/gcc/fortran/gfortran.h	2005-05-28 21:17:44.000000000 +0900
+++ gcc-4061/gcc/fortran/gfortran.h	2005-05-28 21:35:43.000000000 +0900
@@ -130,7 +130,7 @@
 
 typedef enum
 { BT_UNKNOWN = 1, BT_INTEGER, BT_REAL, BT_COMPLEX,
-  BT_LOGICAL, BT_CHARACTER, BT_DERIVED, BT_PROCEDURE
+  BT_LOGICAL, BT_CHARACTER, BT_DERIVED, BT_PROCEDURE, BT_HOLLERITH
 }
 bt;
 
@@ -1056,6 +1056,9 @@
   struct gfc_expr *op1, *op2;
   locus where;
 
+  /* True if it is converted from Hollerith constant.  */
+  unsigned int from_H : 1;
+
   union
   {
     int logical;
diff -uNr gcc-4061.orig/gcc/fortran/intrinsic.c gcc-4061/gcc/fortran/intrinsic.c
--- gcc-4061.orig/gcc/fortran/intrinsic.c	2004-11-11 10:14:34.000000000 +0900
+++ gcc-4061/gcc/fortran/intrinsic.c	2005-05-28 21:35:43.000000000 +0900
@@ -82,6 +82,10 @@
       c = 'c';
       break;
 
+    case BT_HOLLERITH:
+      c = 'h';
+      break;
+
     default:
       c = 'u';
       break;
@@ -2040,6 +2044,19 @@
 		  BT_INTEGER, gfc_integer_kinds[i].kind, gfc_convert_constant);
       }
 
+  /* Hollerith-Integer conversions.  */
+  for (i = 0; gfc_integer_kinds[i].kind != 0; i++)
+    add_conv (BT_HOLLERITH, gfc_default_character_kind,
+		  BT_INTEGER, gfc_integer_kinds[i].kind, gfc_convert_constant);
+  /* Hollerith-Real conversions.  */
+  for (i = 0; gfc_real_kinds[i].kind != 0; i++)
+    add_conv (BT_HOLLERITH, gfc_default_character_kind,
+		  BT_REAL, gfc_real_kinds[i].kind, gfc_convert_constant);
+  /* Hollerith-Complex conversions.  */
+  for (i = 0; gfc_real_kinds[i].kind != 0; i++)
+    add_conv (BT_HOLLERITH, gfc_default_character_kind,
+		  BT_COMPLEX, gfc_real_kinds[i].kind, gfc_convert_constant);
+
   /* Real/Complex - Real/Complex conversions.  */
   for (i = 0; gfc_real_kinds[i].kind != 0; i++)
     for (j = 0; gfc_real_kinds[j].kind != 0; j++)
diff -uNr gcc-4061.orig/gcc/fortran/io.c gcc-4061/gcc/fortran/io.c
--- gcc-4061.orig/gcc/fortran/io.c	2004-10-16 06:02:52.000000000 +0900
+++ gcc-4061/gcc/fortran/io.c	2005-05-28 21:35:43.000000000 +0900
@@ -978,7 +978,7 @@
 
   if (tag == &tag_format)
     {
-      if (e->rank != 1 && e->rank != 0)
+      if (e->rank != 1 && e->rank != 0 && e->ts.type == BT_CHARACTER)
 	{
 	  gfc_error ("FORMAT tag at %L cannot be array of strings",
 		     &e->where);
diff -uNr gcc-4061.orig/gcc/fortran/misc.c gcc-4061/gcc/fortran/misc.c
--- gcc-4061.orig/gcc/fortran/misc.c	2004-10-16 06:02:52.000000000 +0900
+++ gcc-4061/gcc/fortran/misc.c	2005-05-28 21:35:43.000000000 +0900
@@ -161,6 +161,9 @@
     case BT_CHARACTER:
       p = "CHARACTER";
       break;
+    case BT_HOLLERITH:
+      p = "HOLLERITH";
+      break;
     case BT_DERIVED:
       p = "DERIVED";
       break;
@@ -209,6 +212,9 @@
     case BT_CHARACTER:
       sprintf (buffer, "CHARACTER(%d)", ts->kind);
       break;
+    case BT_HOLLERITH:
+      sprintf (buffer, "HOLLERITH");
+      break;
     case BT_DERIVED:
       sprintf (buffer, "TYPE(%s)", ts->derived->name);
       break;
diff -uNr gcc-4061.orig/gcc/fortran/primary.c gcc-4061/gcc/fortran/primary.c
--- gcc-4061.orig/gcc/fortran/primary.c	2004-11-11 10:14:35.000000000 +0900
+++ gcc-4061/gcc/fortran/primary.c	2005-05-28 21:35:43.000000000 +0900
@@ -229,6 +229,74 @@
 }
 
 
+/* Match a Hollerith constant.  */
+
+static match
+match_hollerith_constant (gfc_expr ** result)
+{
+  locus old_loc;
+  gfc_expr *e;
+  const char * msg;
+  char * buffer;
+  unsigned int num;
+  unsigned int i;  
+
+  old_loc = gfc_current_locus;
+  gfc_gobble_whitespace ();
+
+  if (match_integer_constant (&e, 0) == MATCH_YES
+	&& gfc_match_char ('h') == MATCH_YES)
+    {
+      msg = gfc_extract_int (e, &num);
+      if (msg != NULL)
+	{
+	  gfc_error (msg);
+	  goto cleanup;
+	}
+      if (num == 0)
+	{
+	  gfc_error ("Invalid Hollerith constant: must contain at least one ",
+			"character");
+	  goto cleanup;
+	}
+      if (e->ts.kind != gfc_default_integer_kind)
+	{
+	  gfc_error ("Invalid Hollerith constant: Interger kind at %L ",
+		"should be default", &old_loc);
+	  goto cleanup;
+	}
+      else
+	{
+	  if (gfc_notify_std (GFC_STD_F95_DEL,
+		"Obsolete: Hollerith constant at %C")
+	      == FAILURE)
+	    goto cleanup;
+
+	  buffer = (char *)gfc_getmem (sizeof(char)*num+1);
+	  for (i = 0; i < num; i++)
+	    {
+	      buffer[i] = gfc_next_char_literal (1);
+	    }
+	  gfc_free_expr (e);
+	  e = gfc_constant_result (BT_HOLLERITH,
+		gfc_default_character_kind, &gfc_current_locus);
+	  e->value.character.string = gfc_getmem (num+1);
+	  memcpy (e->value.character.string, buffer, num);
+	  e->value.character.length = num;
+	  *result = e;
+	  return MATCH_YES;
+	}
+    }
+ 
+  gfc_current_locus = old_loc;
+  return MATCH_NO;
+
+cleanup:
+  gfc_free_expr (e);
+  return MATCH_ERROR;
+}
+
+
 /* Match a binary, octal or hexadecimal constant that can be found in
    a DATA statement.  */
 
@@ -1268,6 +1336,10 @@
   if (m != MATCH_NO)
     return m;
 
+  m = match_hollerith_constant (result);
+  if (m != MATCH_NO)
+    return m;
+
   m = match_integer_constant (result, signflag);
   if (m != MATCH_NO)
     return m;
diff -uNr gcc-4061.orig/gcc/fortran/simplify.c gcc-4061/gcc/fortran/simplify.c
--- gcc-4061.orig/gcc/fortran/simplify.c	2004-11-11 10:14:35.000000000 +0900
+++ gcc-4061/gcc/fortran/simplify.c	2005-05-28 21:35:43.000000000 +0900
@@ -3726,6 +3726,26 @@
       f = gfc_log2log;
       break;
 
+    case BT_HOLLERITH:
+      switch (type)
+	{
+	case BT_INTEGER:
+	  f = gfc_hollerith2int;
+	  break;
+
+	case BT_REAL:
+	  f = gfc_hollerith2real;
+	  break;
+
+	case BT_COMPLEX:
+	  f = gfc_hollerith2complex;
+	  break;
+
+	default:
+	  goto oops;
+	}
+      break;
+
     default:
     oops:
       gfc_internal_error ("gfc_convert_constant(): Unexpected type");
diff -uNr gcc-4061.orig/gcc/fortran/trans-const.c gcc-4061/gcc/fortran/trans-const.c
--- gcc-4061.orig/gcc/fortran/trans-const.c	2004-11-11 10:14:35.000000000 +0900
+++ gcc-4061/gcc/fortran/trans-const.c	2005-05-28 21:56:27.000000000 +0900
@@ -303,15 +303,50 @@
   switch (expr->ts.type)
     {
     case BT_INTEGER:
+#if 0
       return gfc_conv_mpz_to_tree (expr->value.integer, expr->ts.kind);
+#else
+      /* If it is converted from Hollerith constant, we build string constant
+       and VIEW_CONVERT to this type.  */
+      if (expr->from_H)
+	return build1 (VIEW_CONVERT_EXPR,
+			gfc_get_int_type (expr->ts.kind),
+			gfc_build_string_const (expr->value.character.length,
+				expr->value.character.string));
+      else
+	return gfc_conv_mpz_to_tree (expr->value.integer, expr->ts.kind);
+#endif
 
     case BT_REAL:
+#if 0
       return gfc_conv_mpfr_to_tree (expr->value.real, expr->ts.kind);
+#else
+      /* If it is converted from Hollerith constant, we build string constant
+       and VIEW_CONVERT to this type.  */
+      if (expr->from_H)
+	return build1 (VIEW_CONVERT_EXPR,
+			gfc_get_real_type (expr->ts.kind),
+			gfc_build_string_const (expr->value.character.length,
+				expr->value.character.string));
+      else
+	return gfc_conv_mpfr_to_tree (expr->value.real, expr->ts.kind);
+#endif
 
     case BT_LOGICAL:
       return build_int_cst (NULL_TREE, expr->value.logical);
 
     case BT_COMPLEX:
+#if 0
+#else
+      /* If it is converted from Hollerith constant, we build string constant
+       and VIEW_CONVERT to this type.  */
+      if (expr->from_H)
+	return build1 (VIEW_CONVERT_EXPR,
+			gfc_get_complex_type (expr->ts.kind),
+			gfc_build_string_const (expr->value.character.length,
+				expr->value.character.string));
+    else
+#endif
       {
 	tree real = gfc_conv_mpfr_to_tree (expr->value.complex.r,
 					  expr->ts.kind);
diff -uNr gcc-4061.orig/gcc/fortran/trans-io.c gcc-4061/gcc/fortran/trans-io.c
--- gcc-4061.orig/gcc/fortran/trans-io.c	2004-11-11 10:14:36.000000000 +0900
+++ gcc-4061/gcc/fortran/trans-io.c	2005-05-28 21:59:41.000000000 +0900
@@ -384,6 +384,52 @@
   gfc_add_modify_expr (block, tmp, se.expr);
 }
 
+/* Converts array to string. Used for Hollerith constant.  */
+
+static void
+gfc_convert_array_to_string (gfc_se * se, gfc_expr * e)
+{
+  tree tmp;
+  tree array;
+  tree type;
+  tree size;
+  gfc_array_spec *as;
+  gfc_symbol *sym;
+
+  sym = e->symtree->n.sym;
+  as = sym->as;
+
+  if (e->ref->u.ar.type == AR_FULL)
+    {
+      se->expr = gfc_get_symbol_decl (sym);
+      se->expr = gfc_conv_array_data (se->expr);
+    }
+  else
+    {
+      gfc_conv_expr (se, e);
+    }
+
+  array = sym->backend_decl;
+  type = TREE_TYPE (array);
+  gcc_assert (GFC_ARRAY_TYPE_P (type));
+
+  size = GFC_TYPE_ARRAY_SIZE (type);
+  gcc_assert (size);
+
+  /* If it is an element, we need the its address and size of the rest.  */
+  if (e->ref->u.ar.type == AR_ELEMENT)
+    {
+      size = fold (build (MINUS_EXPR, gfc_array_index_type, size,
+		TREE_OPERAND (se->expr, 1)));
+      se->expr = gfc_build_addr_expr (NULL, se->expr);
+    }
+
+  tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type));
+  size = fold (build (MULT_EXPR, gfc_array_index_type, size, tmp));
+
+  se->string_length = size;
+}
+
 
 /* Generate code to store a string and its length into the
    ioparm structure.  */
@@ -409,7 +455,7 @@
   if (e->ts.type == BT_INTEGER && e->symtree->n.sym->attr.assign == 1)
     {
       msg =
-        gfc_build_cstring_const ("Assigned label is not a format label");
+	gfc_build_cstring_const ("Assigned label is not a format label");
       tmp = GFC_DECL_STRING_LEN (se.expr);
       tmp = build2 (LE_EXPR, boolean_type_node,
 		    tmp, convert (TREE_TYPE (tmp), integer_minus_one_node));
@@ -419,6 +465,15 @@
     }
   else
     {
+#if 0
+#else
+      /* Hollerith constant.  */
+      if (e->ts.type != BT_CHARACTER && e->symtree->n.sym->as->rank > 0)
+	gfc_convert_array_to_string (&se, e);
+      else
+	gfc_conv_expr (&se, e);
+
+#endif
       gfc_conv_string_parameter (&se);
       gfc_add_modify_expr (&se.pre, io, fold_convert (TREE_TYPE (io), se.expr));
       gfc_add_modify_expr (&se.pre, len, se.string_length);
@@ -426,7 +481,6 @@
 
   gfc_add_block_to_block (block, &se.pre);
   gfc_add_block_to_block (postblock, &se.post);
-
 }
 
 
diff -uNr gcc-4061.orig/libgfortran/io/transfer.c gcc-4061/libgfortran/io/transfer.c
--- gcc-4061.orig/libgfortran/io/transfer.c	2004-11-11 10:16:31.000000000 +0900
+++ gcc-4061/libgfortran/io/transfer.c	2005-05-28 21:35:43.000000000 +0900
@@ -469,8 +469,6 @@
 	case FMT_A:
 	  if (n == 0)
 	    goto need_data;
-	  if (require_type (BT_CHARACTER, type, f))
-	    return;
 
 	  if (g.mode == READING)
 	    read_a (f, p, len);
