Blame SOURCES/gcc7-0022-Default-values-for-certain-field-descriptors-in-form.patch

ed1ed2
diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c
ed1ed2
index d93dcfa..f47565c 100644
ed1ed2
--- a/gcc/fortran/io.c
ed1ed2
+++ b/gcc/fortran/io.c
ed1ed2
@@ -909,6 +909,13 @@ data_desc:
ed1ed2
 
ed1ed2
       if (u != FMT_POSINT)
ed1ed2
 	{
ed1ed2
+	  if (flag_dec)
ed1ed2
+	    {
ed1ed2
+	      /* Assume a default width based on the variable size.  */
ed1ed2
+	      saved_token = u;
ed1ed2
+	      break;
ed1ed2
+	    }
ed1ed2
+
ed1ed2
 	  format_locus.nextc += format_string_pos;
ed1ed2
 	  gfc_error ("Positive width required in format "
ed1ed2
 			 "specifier %s at %L", token_to_string (t),
ed1ed2
@@ -1030,6 +1037,13 @@ data_desc:
ed1ed2
 	goto fail;
ed1ed2
       if (t != FMT_ZERO && t != FMT_POSINT)
ed1ed2
 	{
ed1ed2
+	  if (flag_dec)
ed1ed2
+	    {
ed1ed2
+	      /* Assume the default width is expected here and continue lexing.  */
ed1ed2
+	      value = 0; /* It doesn't matter what we set the value to here.  */
ed1ed2
+	      saved_token = t;
ed1ed2
+	      break;
ed1ed2
+	    }
ed1ed2
 	  error = nonneg_required;
ed1ed2
 	  goto syntax;
ed1ed2
 	}
ed1ed2
@@ -1099,8 +1113,17 @@ data_desc:
ed1ed2
 	goto fail;
ed1ed2
       if (t != FMT_ZERO && t != FMT_POSINT)
ed1ed2
 	{
ed1ed2
-	  error = nonneg_required;
ed1ed2
-	  goto syntax;
ed1ed2
+	  if (flag_dec)
ed1ed2
+	    {
ed1ed2
+	      /* Assume the default width is expected here and continue lexing.  */
ed1ed2
+	      value = 0; /* It doesn't matter what we set the value to here.  */
ed1ed2
+	      saved_token = t;
ed1ed2
+	    }
ed1ed2
+	  else
ed1ed2
+	    {
ed1ed2
+	      error = nonneg_required;
ed1ed2
+	      goto syntax;
ed1ed2
+	    }
ed1ed2
 	}
ed1ed2
       else if (is_input && t == FMT_ZERO)
ed1ed2
 	{
ed1ed2
diff --git a/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90
ed1ed2
new file mode 100644
ed1ed2
index 0000000..b087b8f
ed1ed2
--- /dev/null
ed1ed2
+++ b/gcc/testsuite/gfortran.dg/fmt_f_default_field_width.f90
ed1ed2
@@ -0,0 +1,43 @@
ed1ed2
+! { dg-do run }
ed1ed2
+! { dg-options -fdec }
ed1ed2
+!
ed1ed2
+! Test case for the default field widths enabled by the -fdec-format-defaults flag.
ed1ed2
+!
ed1ed2
+! This feature is not part of any Fortran standard, but it is supported by the
ed1ed2
+! Oracle Fortran compiler and others.
ed1ed2
+!
ed1ed2
+! libgfortran uses printf() internally to implement FORMAT. If you print float
ed1ed2
+! values to a higher precision than the type can actually store, the results
ed1ed2
+! are implementation dependent: some platforms print zeros, others print random
ed1ed2
+! numbers. Don't depend on this behaviour in tests because they will not be
ed1ed2
+! portable.
ed1ed2
+
ed1ed2
+    character(50) :: buffer
ed1ed2
+
ed1ed2
+    real*4 :: real_4
ed1ed2
+    real*8 :: real_8
ed1ed2
+    real*16 :: real_16
ed1ed2
+    integer :: len
ed1ed2
+
ed1ed2
+    real_4 = 4.18
ed1ed2
+    write(buffer, '(A, F, A)') ':',real_4,':'
ed1ed2
+    print *,buffer
ed1ed2
+    if (buffer.ne.":      4.1799998:") call abort
ed1ed2
+
ed1ed2
+    real_4 = 0.00000018
ed1ed2
+    write(buffer, '(A, F, A)') ':',real_4,':'
ed1ed2
+    print *,buffer
ed1ed2
+    if (buffer.ne.":      0.0000002:") call abort
ed1ed2
+
ed1ed2
+    real_8 = 4.18
ed1ed2
+    write(buffer, '(A, F, A)') ':',real_8,':'
ed1ed2
+    print *,buffer
ed1ed2
+    len = len_trim(buffer)
ed1ed2
+    if (len /= 27) call abort
ed1ed2
+
ed1ed2
+    real_16 = 4.18
ed1ed2
+    write(buffer, '(A, F, A)') ':',real_16,':'
ed1ed2
+    print *,buffer
ed1ed2
+    len = len_trim(buffer)
ed1ed2
+    if (len /= 44) call abort
ed1ed2
+end
ed1ed2
diff --git a/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90
ed1ed2
new file mode 100644
ed1ed2
index 0000000..3d3a476
ed1ed2
--- /dev/null
ed1ed2
+++ b/gcc/testsuite/gfortran.dg/fmt_g_default_field_width.f90
ed1ed2
@@ -0,0 +1,48 @@
ed1ed2
+! { dg-do run }
ed1ed2
+! { dg-options -fdec }
ed1ed2
+!
ed1ed2
+! Test case for the default field widths enabled by the -fdec-format-defaults flag.
ed1ed2
+!
ed1ed2
+! This feature is not part of any Fortran standard, but it is supported by the
ed1ed2
+! Oracle Fortran compiler and others.
ed1ed2
+!
ed1ed2
+! libgfortran uses printf() internally to implement FORMAT. If you print float
ed1ed2
+! values to a higher precision than the type can actually store, the results
ed1ed2
+! are implementation dependent: some platforms print zeros, others print random
ed1ed2
+! numbers. Don't depend on this behaviour in tests because they will not be
ed1ed2
+! portable.
ed1ed2
+
ed1ed2
+    character(50) :: buffer
ed1ed2
+
ed1ed2
+    real*4 :: real_4
ed1ed2
+    real*8 :: real_8
ed1ed2
+    real*16 :: real_16
ed1ed2
+    integer :: len
ed1ed2
+
ed1ed2
+    real_4 = 4.18
ed1ed2
+    write(buffer, '(A, G, A)') ':',real_4,':'
ed1ed2
+    print *,buffer
ed1ed2
+    if (buffer.ne.":   4.180000    :") call abort
ed1ed2
+
ed1ed2
+    real_4 = 0.00000018
ed1ed2
+    write(buffer, '(A, G, A)') ':',real_4,':'
ed1ed2
+    print *,buffer
ed1ed2
+    if (buffer.ne.":  0.1800000E-06:") call abort
ed1ed2
+
ed1ed2
+    real_4 = 18000000.4
ed1ed2
+    write(buffer, '(A, G, A)') ':',real_4,':'
ed1ed2
+    print *,buffer
ed1ed2
+    if (buffer.ne.":  0.1800000E+08:") call abort
ed1ed2
+
ed1ed2
+    real_8 = 4.18
ed1ed2
+    write(buffer, '(A, G, A)') ':',real_8,':'
ed1ed2
+    print *,buffer
ed1ed2
+    len = len_trim(buffer)
ed1ed2
+    if (len /= 27) call abort
ed1ed2
+
ed1ed2
+    real_16 = 4.18
ed1ed2
+    write(buffer, '(A, G, A)') ':',real_16,':'
ed1ed2
+    print *,buffer
ed1ed2
+    len = len_trim(buffer)
ed1ed2
+    if (len /= 44) call abort
ed1ed2
+end
ed1ed2
diff --git a/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90 b/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90
ed1ed2
new file mode 100644
ed1ed2
index 0000000..ac4e165
ed1ed2
--- /dev/null
ed1ed2
+++ b/gcc/testsuite/gfortran.dg/fmt_i_default_field_width.f90
ed1ed2
@@ -0,0 +1,38 @@
ed1ed2
+! { dg-do run }
ed1ed2
+! { dg-options -fdec }
ed1ed2
+!
ed1ed2
+! Test case for the default field widths enabled by the -fdec-format-defaults flag.
ed1ed2
+!
ed1ed2
+! This feature is not part of any Fortran standard, but it is supported by the
ed1ed2
+! Oracle Fortran compiler and others.
ed1ed2
+
ed1ed2
+    character(50) :: buffer
ed1ed2
+    character(1) :: colon
ed1ed2
+
ed1ed2
+    integer*2 :: integer_2
ed1ed2
+    integer*4 :: integer_4
ed1ed2
+    integer*8 :: integer_8
ed1ed2
+
ed1ed2
+    write(buffer, '(A, I, A)') ':',12340,':'
ed1ed2
+    print *,buffer
ed1ed2
+    if (buffer.ne.":       12340:") call abort
ed1ed2
+
ed1ed2
+    read(buffer, '(A1, I, A1)') colon, integer_4, colon
ed1ed2
+    if (integer_4.ne.12340) call abort
ed1ed2
+
ed1ed2
+    integer_2 = -99
ed1ed2
+    write(buffer, '(A, I, A)') ':',integer_2,':'
ed1ed2
+    print *,buffer
ed1ed2
+    if (buffer.ne.":    -99:") call abort
ed1ed2
+
ed1ed2
+    integer_8 = -11112222
ed1ed2
+    write(buffer, '(A, I, A)') ':',integer_8,':'
ed1ed2
+    print *,buffer
ed1ed2
+    if (buffer.ne.":              -11112222:") call abort
ed1ed2
+
ed1ed2
+! If the width is 7 and there are 7 leading zeroes, the result should be zero.
ed1ed2
+    integer_2 = 789
ed1ed2
+    buffer = '0000000789'
ed1ed2
+    read(buffer, '(I)') integer_2
ed1ed2
+    if (integer_2.ne.0) call abort
ed1ed2
+end
ed1ed2
diff --git a/libgfortran/io/format.c b/libgfortran/io/format.c
ed1ed2
index c2abdd7..692b1ff 100644
ed1ed2
--- a/libgfortran/io/format.c
ed1ed2
+++ b/libgfortran/io/format.c
ed1ed2
@@ -956,12 +956,33 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd)
ed1ed2
 	  *seen_dd = true;
ed1ed2
 	  if (u != FMT_POSINT && u != FMT_ZERO)
ed1ed2
 	    {
ed1ed2
+	      if (dtp->common.flags & IOPARM_DT_DEC_EXT)
ed1ed2
+		{
ed1ed2
+		  tail->u.real.w = DEFAULT_WIDTH;
ed1ed2
+		  tail->u.real.d = 0;
ed1ed2
+		  tail->u.real.e = -1;
ed1ed2
+		  fmt->saved_token = u;
ed1ed2
+		  break;
ed1ed2
+		}
ed1ed2
 	      fmt->error = nonneg_required;
ed1ed2
 	      goto finished;
ed1ed2
 	    }
ed1ed2
 	}
ed1ed2
+      else if (u == FMT_ZERO)
ed1ed2
+	{
ed1ed2
+	  fmt->error = posint_required;
ed1ed2
+	  goto finished;
ed1ed2
+	}
ed1ed2
       else if (u != FMT_POSINT)
ed1ed2
 	{
ed1ed2
+	  if (dtp->common.flags & IOPARM_DT_DEC_EXT)
ed1ed2
+	    {
ed1ed2
+	      tail->u.real.w = DEFAULT_WIDTH;
ed1ed2
+	      tail->u.real.d = 0;
ed1ed2
+	      tail->u.real.e = -1;
ed1ed2
+	      fmt->saved_token = u;
ed1ed2
+	      break;
ed1ed2
+	    }
ed1ed2
 	  fmt->error = posint_required;
ed1ed2
 	  goto finished;
ed1ed2
 	}
ed1ed2
@@ -1099,6 +1120,13 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd)
ed1ed2
 	{
ed1ed2
 	  if (t != FMT_POSINT)
ed1ed2
 	    {
ed1ed2
+	      if (dtp->common.flags & IOPARM_DT_DEC_EXT)
ed1ed2
+		{
ed1ed2
+		  tail->u.integer.w = DEFAULT_WIDTH;
ed1ed2
+		  tail->u.integer.m = -1;
ed1ed2
+		  fmt->saved_token = t;
ed1ed2
+		  break;
ed1ed2
+		}
ed1ed2
 	      fmt->error = posint_required;
ed1ed2
 	      goto finished;
ed1ed2
 	    }
ed1ed2
@@ -1107,6 +1135,13 @@ parse_format_list (st_parameter_dt *dtp, bool *seen_dd)
ed1ed2
 	{
ed1ed2
 	  if (t != FMT_ZERO && t != FMT_POSINT)
ed1ed2
 	    {
ed1ed2
+	      if (dtp->common.flags & IOPARM_DT_DEC_EXT)
ed1ed2
+		{
ed1ed2
+		  tail->u.integer.w = DEFAULT_WIDTH;
ed1ed2
+		  tail->u.integer.m = -1;
ed1ed2
+		  fmt->saved_token = t;
ed1ed2
+		  break;
ed1ed2
+		}
ed1ed2
 	      fmt->error = nonneg_required;
ed1ed2
 	      goto finished;
ed1ed2
 	    }
ed1ed2
diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h
ed1ed2
index 5583183..d1d08e8 100644
ed1ed2
--- a/libgfortran/io/io.h
ed1ed2
+++ b/libgfortran/io/io.h
ed1ed2
@@ -981,5 +981,55 @@ memset4 (gfc_char4_t *p, gfc_char4_t c, int k)
ed1ed2
     *p++ = c;
ed1ed2
 }
ed1ed2
 
ed1ed2
+/* Used in width fields to indicate that the default should be used */
ed1ed2
+#define DEFAULT_WIDTH -1
ed1ed2
+
ed1ed2
+/* Defaults for certain format field descriptors. These are decided based on
ed1ed2
+ * the type of the value being formatted.
ed1ed2
+ *
ed1ed2
+ * The behaviour here is modelled on the Oracle Fortran compiler. At the time
ed1ed2
+ * of writing, the details were available at this URL:
ed1ed2
+ *
ed1ed2
+ *   https://docs.oracle.com/cd/E19957-01/805-4939/6j4m0vnc3/index.html#z4000743746d
ed1ed2
+ */
ed1ed2
+
ed1ed2
+static inline int
ed1ed2
+default_width_for_integer (int kind)
ed1ed2
+{
ed1ed2
+  switch (kind)
ed1ed2
+    {
ed1ed2
+    case 1:
ed1ed2
+    case 2:  return  7;
ed1ed2
+    case 4:  return 12;
ed1ed2
+    case 8:  return 23;
ed1ed2
+    case 16: return 44;
ed1ed2
+    default: return  0;
ed1ed2
+    }
ed1ed2
+}
ed1ed2
+
ed1ed2
+static inline int
ed1ed2
+default_width_for_float (int kind)
ed1ed2
+{
ed1ed2
+  switch (kind)
ed1ed2
+    {
ed1ed2
+    case 4:  return 15;
ed1ed2
+    case 8:  return 25;
ed1ed2
+    case 16: return 42;
ed1ed2
+    default: return  0;
ed1ed2
+    }
ed1ed2
+}
ed1ed2
+
ed1ed2
+static inline int
ed1ed2
+default_precision_for_float (int kind)
ed1ed2
+{
ed1ed2
+  switch (kind)
ed1ed2
+    {
ed1ed2
+    case 4:  return 7;
ed1ed2
+    case 8:  return 16;
ed1ed2
+    case 16: return 33;
ed1ed2
+    default: return 0;
ed1ed2
+    }
ed1ed2
+}
ed1ed2
+
ed1ed2
 #endif
ed1ed2
 
ed1ed2
diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c
ed1ed2
index 2c9de48..e911e35 100644
ed1ed2
--- a/libgfortran/io/read.c
ed1ed2
+++ b/libgfortran/io/read.c
ed1ed2
@@ -629,6 +629,12 @@ read_decimal (st_parameter_dt *dtp, const fnode *f, char *dest, int length)
ed1ed2
 
ed1ed2
   w = f->u.w;
ed1ed2
 
ed1ed2
+  /* This is a legacy extension, and the frontend will only allow such cases
ed1ed2
+   * through when -fdec-format-defaults is passed.
ed1ed2
+   */
ed1ed2
+  if (w == DEFAULT_WIDTH)
ed1ed2
+    w = default_width_for_integer (length);
ed1ed2
+
ed1ed2
   p = read_block_form (dtp, &w);
ed1ed2
 
ed1ed2
   if (p == NULL)
ed1ed2
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
ed1ed2
index a7307a8..c8e52fb 100644
ed1ed2
--- a/libgfortran/io/write.c
ed1ed2
+++ b/libgfortran/io/write.c
ed1ed2
@@ -684,9 +684,8 @@ write_l (st_parameter_dt *dtp, const fnode *f, char *source, int len)
ed1ed2
   p[wlen - 1] = (n) ? 'T' : 'F';
ed1ed2
 }
ed1ed2
 
ed1ed2
-
ed1ed2
 static void
ed1ed2
-write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n)
ed1ed2
+write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n, int len)
ed1ed2
 {
ed1ed2
   int w, m, digits, nzero, nblank;
ed1ed2
   char *p;
ed1ed2
@@ -719,6 +718,9 @@ write_boz (st_parameter_dt *dtp, const fnode *f, const char *q, int n)
ed1ed2
   /* Select a width if none was specified.  The idea here is to always
ed1ed2
      print something.  */
ed1ed2
 
ed1ed2
+  if (w == DEFAULT_WIDTH)
ed1ed2
+    w = default_width_for_integer (len);
ed1ed2
+
ed1ed2
   if (w == 0)
ed1ed2
     w = ((digits < m) ? m : digits);
ed1ed2
 
ed1ed2
@@ -845,6 +847,8 @@ write_decimal (st_parameter_dt *dtp, const fnode *f, const char *source,
ed1ed2
 
ed1ed2
   /* Select a width if none was specified.  The idea here is to always
ed1ed2
      print something.  */
ed1ed2
+  if (w == DEFAULT_WIDTH)
ed1ed2
+    w = default_width_for_integer (len);
ed1ed2
 
ed1ed2
   if (w == 0)
ed1ed2
     w = ((digits < m) ? m : digits) + nsign;
ed1ed2
@@ -1187,13 +1191,13 @@ write_b (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
ed1ed2
   if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
ed1ed2
     {
ed1ed2
       p = btoa_big (source, itoa_buf, len, &n);
ed1ed2
-      write_boz (dtp, f, p, n);
ed1ed2
+      write_boz (dtp, f, p, n, len);
ed1ed2
     }
ed1ed2
   else
ed1ed2
     {
ed1ed2
       n = extract_uint (source, len);
ed1ed2
       p = btoa (n, itoa_buf, sizeof (itoa_buf));
ed1ed2
-      write_boz (dtp, f, p, n);
ed1ed2
+      write_boz (dtp, f, p, n, len);
ed1ed2
     }
ed1ed2
 }
ed1ed2
 
ed1ed2
@@ -1208,13 +1212,13 @@ write_o (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
ed1ed2
   if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
ed1ed2
     {
ed1ed2
       p = otoa_big (source, itoa_buf, len, &n);
ed1ed2
-      write_boz (dtp, f, p, n);
ed1ed2
+      write_boz (dtp, f, p, n, len);
ed1ed2
     }
ed1ed2
   else
ed1ed2
     {
ed1ed2
       n = extract_uint (source, len);
ed1ed2
       p = otoa (n, itoa_buf, sizeof (itoa_buf));
ed1ed2
-      write_boz (dtp, f, p, n);
ed1ed2
+      write_boz (dtp, f, p, n, len);
ed1ed2
     }
ed1ed2
 }
ed1ed2
 
ed1ed2
@@ -1228,13 +1232,13 @@ write_z (st_parameter_dt *dtp, const fnode *f, const char *source, int len)
ed1ed2
   if (len > (int) sizeof (GFC_UINTEGER_LARGEST))
ed1ed2
     {
ed1ed2
       p = ztoa_big (source, itoa_buf, len, &n);
ed1ed2
-      write_boz (dtp, f, p, n);
ed1ed2
+      write_boz (dtp, f, p, n, len);
ed1ed2
     }
ed1ed2
   else
ed1ed2
     {
ed1ed2
       n = extract_uint (source, len);
ed1ed2
       p = gfc_xtoa (n, itoa_buf, sizeof (itoa_buf));
ed1ed2
-      write_boz (dtp, f, p, n);
ed1ed2
+      write_boz (dtp, f, p, n, len);
ed1ed2
     }
ed1ed2
 }
ed1ed2
 
ed1ed2
@@ -1504,7 +1508,7 @@ size_from_kind (st_parameter_dt *dtp, const fnode *f, int kind)
ed1ed2
 {
ed1ed2
   int size;
ed1ed2
 
ed1ed2
-  if (f->format == FMT_F && f->u.real.w == 0)
ed1ed2
+  if ((f->format == FMT_F && f->u.real.w == 0) || f->u.real.w == DEFAULT_WIDTH)
ed1ed2
     {
ed1ed2
       switch (kind)
ed1ed2
       {
ed1ed2
diff --git a/libgfortran/io/write_float.def b/libgfortran/io/write_float.def
ed1ed2
index 7f0aa1d..73dc910 100644
ed1ed2
--- a/libgfortran/io/write_float.def
ed1ed2
+++ b/libgfortran/io/write_float.def
ed1ed2
@@ -113,7 +113,8 @@ determine_precision (st_parameter_dt * dtp, const fnode * f, int len)
ed1ed2
 static void
ed1ed2
 build_float_string (st_parameter_dt *dtp, const fnode *f, char *buffer,
ed1ed2
 		    size_t size, int nprinted, int precision, int sign_bit,
ed1ed2
-		    bool zero_flag, int npad, char *result, size_t *len)
ed1ed2
+		    bool zero_flag, int npad, int default_width, char *result,
ed1ed2
+                    size_t *len)
ed1ed2
 {
ed1ed2
   char *put;
ed1ed2
   char *digits;
ed1ed2
@@ -132,8 +133,17 @@ build_float_string (st_parameter_dt *dtp, const fnode *f, char *buffer,
ed1ed2
   sign_t sign;
ed1ed2
 
ed1ed2
   ft = f->format;
ed1ed2
-  w = f->u.real.w;
ed1ed2
-  d = f->u.real.d;
ed1ed2
+  if (f->u.real.w == DEFAULT_WIDTH)
ed1ed2
+    /* This codepath can only be reached with -fdec-format-defaults. */
ed1ed2
+    {
ed1ed2
+      w = default_width;
ed1ed2
+      d = precision;
ed1ed2
+    }
ed1ed2
+  else
ed1ed2
+    {
ed1ed2
+      w = f->u.real.w;
ed1ed2
+      d = f->u.real.d;
ed1ed2
+    }
ed1ed2
   p = dtp->u.p.scale_factor;
ed1ed2
 
ed1ed2
   rchar = '5';
ed1ed2
@@ -958,6 +968,11 @@ determine_en_precision (st_parameter_dt *dtp, const fnode *f,
ed1ed2
       int save_scale_factor;\
ed1ed2
       volatile GFC_REAL_ ## x temp;\
ed1ed2
       save_scale_factor = dtp->u.p.scale_factor;\
ed1ed2
+      if (w == DEFAULT_WIDTH)\
ed1ed2
+	{\
ed1ed2
+	  w = default_width;\
ed1ed2
+	  d = precision;\
ed1ed2
+	}\
ed1ed2
       switch (dtp->u.p.current_unit->round_status)\
ed1ed2
 	{\
ed1ed2
 	  case ROUND_ZERO:\
ed1ed2
@@ -1033,7 +1048,8 @@ determine_en_precision (st_parameter_dt *dtp, const fnode *f,
ed1ed2
 	  nprinted = FDTOA(y,precision,m);\
ed1ed2
 	}\
ed1ed2
       build_float_string (dtp, &newf, buffer, size, nprinted, precision,\
ed1ed2
-				   sign_bit, zero_flag, npad, result, res_len);\
ed1ed2
+				   sign_bit, zero_flag, npad, default_width,\
ed1ed2
+				   result, res_len);\
ed1ed2
       dtp->u.p.scale_factor = save_scale_factor;\
ed1ed2
     }\
ed1ed2
   else\
ed1ed2
@@ -1043,7 +1059,8 @@ determine_en_precision (st_parameter_dt *dtp, const fnode *f,
ed1ed2
       else\
ed1ed2
 	nprinted = DTOA(y,precision,m);\
ed1ed2
       build_float_string (dtp, f, buffer, size, nprinted, precision,\
ed1ed2
-				   sign_bit, zero_flag, npad, result, res_len);\
ed1ed2
+				   sign_bit, zero_flag, npad, default_width,\
ed1ed2
+				   result, res_len);\
ed1ed2
     }\
ed1ed2
 }\
ed1ed2
 
ed1ed2
@@ -1057,6 +1074,16 @@ get_float_string (st_parameter_dt *dtp, const fnode *f, const char *source,
ed1ed2
 {
ed1ed2
   int sign_bit, nprinted;
ed1ed2
   bool zero_flag;
ed1ed2
+  int default_width = 0;
ed1ed2
+
ed1ed2
+  if (f->u.real.w == DEFAULT_WIDTH)
ed1ed2
+    /* This codepath can only be reached with -fdec-format-defaults. The default
ed1ed2
+     * values are based on those used in the Oracle Fortran compiler.
ed1ed2
+     */
ed1ed2
+    {
ed1ed2
+      default_width = default_width_for_float (kind);
ed1ed2
+      precision = default_precision_for_float (kind);
ed1ed2
+    }
ed1ed2
 
ed1ed2
   switch (kind)
ed1ed2
     {