From: Fritz Reese Date: Thu, 3 Nov 2016 18:09:44 +0000 (+0000) Subject: Default missing exponents to 0 with -fdec. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6869e9c69f446161edba48722a75813934643382;p=gcc.git Default missing exponents to 0 with -fdec. gcc/fortran/ * gfortran.texi: Document. * gfortran.h (gfc_dt): New field default_exp. * primary.c (match_real_constant): Default exponent with -fdec. * io.c (match_io): Set dt.default_exp with -fdec. * ioparm.def (IOPARM_dt_default_exp): New. * trans-io.c (build_dt): Set IOPARM_dt_default_exp with -fdec. libgfortran/io/ * io.h (IOPARM_DT_DEFAULT_EXP): New flag bit. * list_read.c (parse_real, read_real): Allow omission of exponent with IOPARM_DT_DEFAULT_EXP. * read.c (read_f): Ditto. gcc/testsuite/gfortran.dg/ * dec_exp_1.f90, dec_exp_2.f90, dec_exp_3.f90: New testcases. From-SVN: r241828 --- diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index baec7bf3eb5..b3cc871688c 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,12 @@ +2016-11-03 Fritz Reese + + * gfortran.texi: Document. + * gfortran.h (gfc_dt): New field default_exp. + * primary.c (match_real_constant): Default exponent with -fdec. + * io.c (match_io): Set dt.default_exp with -fdec. + * ioparm.def (IOPARM_dt_default_exp): New. + * trans-io.c (build_dt): Set IOPARM_dt_default_exp with -fdec. + 2016-11-03 Fritz O. Reese * decl.c (gfc_match_parameter): Allow omitted '()' with -std=legacy. diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index b559e8ac5cb..3fb6f4152ce 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -2336,6 +2336,7 @@ typedef struct gfc_expr *io_unit, *format_expr, *rec, *advance, *iostat, *size, *iomsg, *id, *pos, *asynchronous, *blank, *decimal, *delim, *pad, *round, *sign, *extra_comma, *dt_io_kind, *udtio; + char default_exp; gfc_symbol *namelist; /* A format_label of `format_asterisk' indicates the "*" format */ diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi index cd2c5a52575..6de6c9bfeeb 100644 --- a/gcc/fortran/gfortran.texi +++ b/gcc/fortran/gfortran.texi @@ -1472,6 +1472,7 @@ compatibility extensions along with those enabled by @option{-std=legacy}. * Bitwise logical operators:: * Extended I/O specifiers:: * Legacy PARAMETER statements:: +* Default exponents:: @end menu @node Old-style kind specifications @@ -2713,6 +2714,14 @@ real c parameter c = 3.0e8 @end smallexample +@node Default exponents +@subsection Default exponents +@cindex exponent + +For compatibility, GNU Fortran supports a default exponent of zero in real +constants with @option{-fdec}. For example, @code{9e} would be +interpreted as @code{9e0}, rather than an error. + @node Extensions not implemented in GNU Fortran @section Extensions not implemented in GNU Fortran diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c index 80cf8308da7..04cc1a25358 100644 --- a/gcc/fortran/io.c +++ b/gcc/fortran/io.c @@ -4167,6 +4167,10 @@ get_io_list: goto syntax; } + /* See if we want to use defaults for missing exponents in real transfers. */ + if (flag_dec) + dt->default_exp = 1; + /* A full IO statement has been matched. Check the constraints. spec_end is supplied for cases where no locus is supplied. */ m = check_io_constraints (k, dt, io_code, &spec_end); diff --git a/gcc/fortran/ioparm.def b/gcc/fortran/ioparm.def index f1bf7330fd0..46691874e10 100644 --- a/gcc/fortran/ioparm.def +++ b/gcc/fortran/ioparm.def @@ -118,4 +118,5 @@ IOPARM (dt, round, 1 << 23, char2) IOPARM (dt, sign, 1 << 24, char1) #define IOPARM_dt_f2003 (1 << 25) #define IOPARM_dt_dtio (1 << 26) +#define IOPARM_dt_default_exp (1 << 27) IOPARM (dt, u, 0, pad) diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c index 2101644fcdc..f26740d42ef 100644 --- a/gcc/fortran/primary.c +++ b/gcc/fortran/primary.c @@ -483,7 +483,7 @@ backup: static match match_real_constant (gfc_expr **result, int signflag) { - int kind, count, seen_dp, seen_digits, is_iso_c; + int kind, count, seen_dp, seen_digits, is_iso_c, default_exponent; locus old_loc, temp_loc; char *p, *buffer, c, exp_char; gfc_expr *e; @@ -494,6 +494,7 @@ match_real_constant (gfc_expr **result, int signflag) e = NULL; + default_exponent = 0; count = 0; seen_dp = 0; seen_digits = 0; @@ -575,8 +576,14 @@ match_real_constant (gfc_expr **result, int signflag) if (!ISDIGIT (c)) { - gfc_error ("Missing exponent in real number at %C"); - return MATCH_ERROR; + /* With -fdec, default exponent to 0 instead of complaining. */ + if (flag_dec) + default_exponent = 1; + else + { + gfc_error ("Missing exponent in real number at %C"); + return MATCH_ERROR; + } } while (ISDIGIT (c)) @@ -597,8 +604,8 @@ done: gfc_current_locus = old_loc; gfc_gobble_whitespace (); - buffer = (char *) alloca (count + 1); - memset (buffer, '\0', count + 1); + buffer = (char *) alloca (count + default_exponent + 1); + memset (buffer, '\0', count + default_exponent + 1); p = buffer; c = gfc_next_ascii_char (); @@ -621,6 +628,8 @@ done: c = gfc_next_ascii_char (); } + if (default_exponent) + *p++ = '0'; kind = get_kind (&is_iso_c); if (kind == -1) diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c index 285e551585c..253a5ac70a9 100644 --- a/gcc/fortran/trans-io.c +++ b/gcc/fortran/trans-io.c @@ -1911,6 +1911,9 @@ build_dt (tree function, gfc_code * code) if (dt->udtio) mask |= IOPARM_dt_dtio; + if (dt->default_exp) + mask |= IOPARM_dt_default_exp; + if (dt->namelist) { if (dt->format_expr || dt->format_label) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3b395839e11..2a7d3360857 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2016-11-03 Fritz Reese + + * gfortran.dg/dec_exp_1.f90: New test. + * gfortran.dg/dec_exp_2.f90: Likewise. + * gfortran.dg/dec_exp_3.f90: Likewise. + 2016-11-03 Fritz O. Reese * gfortran.dg/dec_parameter_1.f: New test. diff --git a/gcc/testsuite/gfortran.dg/dec_exp_1.f90 b/gcc/testsuite/gfortran.dg/dec_exp_1.f90 new file mode 100644 index 00000000000..c8b395aa9ce --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dec_exp_1.f90 @@ -0,0 +1,35 @@ +! { dg-do run } +! { dg-options "-fdec" } +! +! Test support for providing a default exponent of zero when unspecified in +! real constants with -fdec. +! + +subroutine asserteq (rexp, ract, msg) + real, intent(in) :: rexp, ract + character(*), intent(in) :: msg + if (rexp .ne. ract) then + write (*, '(A,F12.6,F12.6)') msg, rexp, ract + call abort() + endif +end subroutine + +implicit none + +real, parameter :: r1 = 8e0 +real, parameter :: r2 = 8e ! { equivalent to 8e0 } +real, volatile :: r3, r4 +character(2) :: s +r3 = 8e ! { equivalent to 8e0 } +s = '8e' + +read (s, *) r4 + +call asserteq (r1, r2, "[const]") +call asserteq (r1, r3, "[vol. ]") +call asserteq (r1, r4, "[read ]") + +r4 = 8e + 48e +call asserteq (56e, r4, "[sum ]") + +end diff --git a/gcc/testsuite/gfortran.dg/dec_exp_2.f90 b/gcc/testsuite/gfortran.dg/dec_exp_2.f90 new file mode 100644 index 00000000000..9137aabc4b3 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dec_exp_2.f90 @@ -0,0 +1,13 @@ +! { dg-do compile } +! { dg-options "" } +! +! Make sure we still see an error for missing exponents without -fdec. +! + +implicit none + +real, parameter :: r1 = 8e ! { dg-error "Missing exponent" } +real, volatile :: r2 +r2 = 8e ! { dg-error "Missing exponent" } + +end diff --git a/gcc/testsuite/gfortran.dg/dec_exp_3.f90 b/gcc/testsuite/gfortran.dg/dec_exp_3.f90 new file mode 100644 index 00000000000..34835a77b32 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/dec_exp_3.f90 @@ -0,0 +1,15 @@ +! { dg-do run "xfail *-*-*" } +! { dg-options "" } +! +! Make sure we still see an error for missing exponents without -fdec. +! + +implicit none + +real :: r +character(2) :: s +s = '8e' + +read (s, *) r ! { XFAIL "Bad real number" } + +end diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index 745adf798d2..d50ef47b475 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,10 @@ +2016-11-03 Fritz Reese + + * io/io.h (IOPARM_DT_DEFAULT_EXP): New flag bit. + * io/list_read.c (parse_real, read_real): Allow omission of exponent + with IOPARM_DT_DEFAULT_EXP. + * io/read.c (read_f): Ditto. + 2016-10-31 Jerry DeLisle PR libgfortran/54679 diff --git a/libgfortran/io/io.h b/libgfortran/io/io.h index 7a548497af9..cd0a26f6aa0 100644 --- a/libgfortran/io/io.h +++ b/libgfortran/io/io.h @@ -443,6 +443,7 @@ st_parameter_inquire; #define IOPARM_DT_HAS_SIGN (1 << 24) #define IOPARM_DT_HAS_F2003 (1 << 25) #define IOPARM_DT_HAS_UDTIO (1 << 26) +#define IOPARM_DT_DEFAULT_EXP (1 << 27) /* Internal use bit. */ #define IOPARM_DT_IONML_SET (1u << 31) diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c index f258c9d9249..a35beb88a00 100644 --- a/libgfortran/io/list_read.c +++ b/libgfortran/io/list_read.c @@ -1374,7 +1374,16 @@ parse_real (st_parameter_dt *dtp, void *buffer, int length) exp2: if (!isdigit (c)) - goto bad_exponent; + { + /* Extension: allow default exponent of 0 when omitted. */ + if (dtp->common.flags & IOPARM_DT_DEFAULT_EXP) + { + push_char (dtp, '0'); + goto done; + } + else + goto bad_exponent; + } push_char (dtp, c); @@ -1816,7 +1825,16 @@ read_real (st_parameter_dt *dtp, void * dest, int length) exp2: if (!isdigit (c)) - goto bad_exponent; + { + /* Extension: allow default exponent of 0 when omitted. */ + if (dtp->common.flags & IOPARM_DT_DEFAULT_EXP) + { + push_char (dtp, '0'); + goto done; + } + else + goto bad_exponent; + } push_char (dtp, c); diff --git a/libgfortran/io/read.c b/libgfortran/io/read.c index 23b6f644429..508b3a04fb0 100644 --- a/libgfortran/io/read.c +++ b/libgfortran/io/read.c @@ -1087,7 +1087,13 @@ exponent: the d parameter before explict conversion takes place. */ if (w == 0) - goto bad_float; + { + /* Extension: allow default exponent of 0 when omitted. */ + if (dtp->common.flags & IOPARM_DT_DEFAULT_EXP) + goto done; + else + goto bad_float; + } if (dtp->u.p.blank_status == BLANK_UNSPECIFIED) {