Patchwork [Fortran] Handle 'q' exponent-letter in real-literal-constant

login
register
mail settings
Submitter Steve Kargl
Date April 26, 2011, 4:52 p.m.
Message ID <20110426165258.GA5025@troutmask.apl.washington.edu>
Download mbox | patch
Permalink /patch/92940/
State New
Headers show

Comments

Steve Kargl - April 26, 2011, 4:52 p.m.
On Mon, Apr 25, 2011 at 11:15:35PM +0300, Janne Blomqvist wrote:
> On Mon, Apr 25, 2011 at 22:45, Steve Kargl
> <sgk@troutmask.apl.washington.edu> wrote:
> > On Mon, Apr 25, 2011 at 10:26:20PM +0300, Janne Blomqvist wrote:
> >> Hmm, I'd prefer if the warning was issued only with -Wsomething which
> >> would be included in -Wall. But I suppose this can be done as a
> >> follow-up patch.
> >
> > I thought about adding a -freal-q-constant option.
> 
> -Wreal-q-constant, presumably?
> 

Yes.  I've implemented in the revised patch, and I've
updated the docs.

2011-04-26  Steven G. Kargl  <kargl@gcc.gnu.org>

	PR fortran/48720
	* gfortran.texi: Document the 'Q' exponent-letter extension.
	* invoke.texi: Document -Wreal-q-constant.
	* lang.opt: Add -Wreal-q-constant option.
	* gfortran.h: Add warn_real_q_constant to option struct.
	* primary.c (match_real_constant):  Use it.  Accept 'Q' as
	exponent-letter for REAL(16) real-literal-constant with a
	fallback to REAL(10) or error if REAL(10) is not available.
	* options.c (gfc_init_options, set_Wall) Set it.
	(gfc_handle_option): Handle new option.

OK?
Mikael Morin - April 26, 2011, 10:23 p.m.
On Tuesday 26 April 2011 18:52:58 Steve Kargl wrote:
> On Mon, Apr 25, 2011 at 11:15:35PM +0300, Janne Blomqvist wrote:
> > On Mon, Apr 25, 2011 at 22:45, Steve Kargl
> > 
> > <sgk@troutmask.apl.washington.edu> wrote:
> > > On Mon, Apr 25, 2011 at 10:26:20PM +0300, Janne Blomqvist wrote:
> > >> Hmm, I'd prefer if the warning was issued only with -Wsomething which
> > >> would be included in -Wall. But I suppose this can be done as a
> > >> follow-up patch.
> > > 
> > > I thought about adding a -freal-q-constant option.
> > 
> > -Wreal-q-constant, presumably?
> 
> Yes.  I've implemented in the revised patch, and I've
> updated the docs.
> 
> 2011-04-26  Steven G. Kargl  <kargl@gcc.gnu.org>
> 
> 	PR fortran/48720
> 	* gfortran.texi: Document the 'Q' exponent-letter extension.
> 	* invoke.texi: Document -Wreal-q-constant.
> 	* lang.opt: Add -Wreal-q-constant option.
> 	* gfortran.h: Add warn_real_q_constant to option struct.
> 	* primary.c (match_real_constant):  Use it.  Accept 'Q' as
> 	exponent-letter for REAL(16) real-literal-constant with a
> 	fallback to REAL(10) or error if REAL(10) is not available.
> 	* options.c (gfc_init_options, set_Wall) Set it.
> 	(gfc_handle_option): Handle new option.
> 
> OK?
Sorry to jump late on this.


> Index: primary.c
> ===================================================================
> --- primary.c   (revision 172974)
> +++ primary.c   (working copy)
> @@ -541,6 +541,17 @@ match_real_constant (gfc_expr **result, 
>      goto done;
>    exp_char = c;
>  
> +
> +  if (c == 'q')
> +    {
> +      if (gfc_notify_std (GFC_STD_GNU, "Extension: exponent-letter 'q' in "
> +                        "real-literal-constant at %C") == FAILURE)
> +       return MATCH_ERROR;
> +      else if (gfc_option.warn_real_q_constant)
> +       gfc_warning("Extension: exponent-letter 'q' in real-literal-constant 
"
> +                   "at %C");
> +    }
I think the above could generate double warnings. With -pedantic for example 
(but I didn't check). 
By the way testcases are missing :-p.

> @@ -616,6 +627,29 @@ done:
>        kind = gfc_default_double_kind;
>        break;
>  
> +    case 'q':
> +      if (kind != -2)
> +       {
> +         gfc_error ("Real number at %C has a 'q' exponent and an explicit "
> +                    "kind");
> +         goto cleanup;
> +       }
> +
> +      /* The maximum possible real kind type parameter is 16.  First, try
> +        that for the kind, then fallback to trying kind=10 (Intel 80 bit)
> +        extended precision.  If neither value works, just given up.  */
> +      kind = 16;
> +      if (gfc_validate_kind (BT_REAL, kind, true) < 0)
> +       {
> +         kind = 10;
> +          if (gfc_validate_kind (BT_REAL, kind, true) < 0)
> +           {
> +             gfc_error ("Invalid real kind %d at %C", kind);
> +             goto cleanup;
> +           }
Here kind is guaranteed to be 10 in the error. As the user didn't specify 
kind=10 explicitely, I suggest a more informative message like (for example):
Use of 'q' exponent requires REAL(16) or REAL(10) support at %C

I only glanced at the rest, but Jane OK'ed it anyway :-).

Mikael
Steve Kargl - April 26, 2011, 11:06 p.m.
On Wed, Apr 27, 2011 at 12:23:03AM +0200, Mikael Morin wrote:
> On Tuesday 26 April 2011 18:52:58 Steve Kargl wrote:
> > On Mon, Apr 25, 2011 at 11:15:35PM +0300, Janne Blomqvist wrote:
> > > On Mon, Apr 25, 2011 at 22:45, Steve Kargl
> > > 
> > > <sgk@troutmask.apl.washington.edu> wrote:
> > > > On Mon, Apr 25, 2011 at 10:26:20PM +0300, Janne Blomqvist wrote:
> > > >> Hmm, I'd prefer if the warning was issued only with -Wsomething which
> > > >> would be included in -Wall. But I suppose this can be done as a
> > > >> follow-up patch.
> > > > 
> > > > I thought about adding a -freal-q-constant option.
> > > 
> > > -Wreal-q-constant, presumably?
> > 
> > Yes.  I've implemented in the revised patch, and I've
> > updated the docs.
> > 
> > 2011-04-26  Steven G. Kargl  <kargl@gcc.gnu.org>
> > 
> > 	PR fortran/48720
> > 	* gfortran.texi: Document the 'Q' exponent-letter extension.
> > 	* invoke.texi: Document -Wreal-q-constant.
> > 	* lang.opt: Add -Wreal-q-constant option.
> > 	* gfortran.h: Add warn_real_q_constant to option struct.
> > 	* primary.c (match_real_constant):  Use it.  Accept 'Q' as
> > 	exponent-letter for REAL(16) real-literal-constant with a
> > 	fallback to REAL(10) or error if REAL(10) is not available.
> > 	* options.c (gfc_init_options, set_Wall) Set it.
> > 	(gfc_handle_option): Handle new option.
> > 
> > OK?
> Sorry to jump late on this.
> 

No problem.  I would rather get it right than rush something
into the tree.

> > Index: primary.c
> > ===================================================================
> > --- primary.c   (revision 172974)
> > +++ primary.c   (working copy)
> > @@ -541,6 +541,17 @@ match_real_constant (gfc_expr **result, 
> >      goto done;
> >    exp_char = c;
> >  
> > +
> > +  if (c == 'q')
> > +    {
> > +      if (gfc_notify_std (GFC_STD_GNU, "Extension: exponent-letter 'q' in "
> > +                        "real-literal-constant at %C") == FAILURE)
> > +       return MATCH_ERROR;
> > +      else if (gfc_option.warn_real_q_constant)
> > +       gfc_warning("Extension: exponent-letter 'q' in real-literal-constant 
> "
> > +                   "at %C");
> > +    }
> I think the above could generate double warnings. With -pedantic for example 
> (but I didn't check). 

It's an 'if -- else if' construct.  If gfc_notify_std == FAILURE, then
the error message is issues and the function returns.   If it is TRUE,
then there should be no messages and else if() is tested.

laptop:kargl[204] gfc4x -pedantic -o z ui.f90
ui.f90:3.12:

   q = 1.23q45
            1
Warning: Extension: exponent-letter 'q' in real-literal-constant at (1)
laptop:kargl[205] gfc4x -pedantic -o z -std=f95 ui.f90
ui.f90:3.12:

   q = 1.23q45
            1
Error: Extension: exponent-letter 'q' in real-literal-constant at (1)

> By the way testcases are missing :-p.

I haven't figure out how to write the testcases (yet).  :-)

> > @@ -616,6 +627,29 @@ done:
> >        kind = gfc_default_double_kind;
> >        break;
> >  
> > +    case 'q':
> > +      if (kind != -2)
> > +       {
> > +         gfc_error ("Real number at %C has a 'q' exponent and an explicit "
> > +                    "kind");
> > +         goto cleanup;
> > +       }
> > +
> > +      /* The maximum possible real kind type parameter is 16.  First, try
> > +        that for the kind, then fallback to trying kind=10 (Intel 80 bit)
> > +        extended precision.  If neither value works, just given up.  */
> > +      kind = 16;
> > +      if (gfc_validate_kind (BT_REAL, kind, true) < 0)
> > +       {
> > +         kind = 10;
> > +          if (gfc_validate_kind (BT_REAL, kind, true) < 0)
> > +           {
> > +             gfc_error ("Invalid real kind %d at %C", kind);
> > +             goto cleanup;
> > +           }
> Here kind is guaranteed to be 10 in the error. As the user didn't specify 
> kind=10 explicitely, I suggest a more informative message like (for example):
> Use of 'q' exponent requires REAL(16) or REAL(10) support at %C

Good catch!  I'll update the error message based on your suggestion.
Mikael Morin - April 27, 2011, 8:54 p.m.
On Wednesday 27 April 2011 01:06:26 Steve Kargl wrote:
> > > Index: primary.c
> > > ===================================================================
> > > --- primary.c   (revision 172974)
> > > +++ primary.c   (working copy)
> > > @@ -541,6 +541,17 @@ match_real_constant (gfc_expr **result,
> > > 
> > >      goto done;
> > >    
> > >    exp_char = c;
> > > 
> > > +
> > > +  if (c == 'q')
> > > +    {
> > > +      if (gfc_notify_std (GFC_STD_GNU, "Extension: exponent-letter 'q'
> > > in " +                        "real-literal-constant at %C") ==
> > > FAILURE) +       return MATCH_ERROR;
> > > +      else if (gfc_option.warn_real_q_constant)
> > > +       gfc_warning("Extension: exponent-letter 'q' in
> > > real-literal-constant
> > 
> > "
> > 
> > > +                   "at %C");
> > > +    }
> > 
> > I think the above could generate double warnings. With -pedantic for
> > example (but I didn't check).
> 
> It's an 'if -- else if' construct.  If gfc_notify_std == FAILURE, then
> the error message is issues and the function returns.   If it is TRUE,
> then there should be no messages and else if() is tested.
My concern is that gfc_notify_std seems to return SUCCESS on warnings (I can't 
test right now as make has decided to rebuild the whole middle-end :-(). Then, 
I expect double warnings with -pedantic -Wreal-q-constant as -pedantic is a 
(the only one ?) case outputing warnings for GNU extensions.

Mikael
Steve Kargl - April 27, 2011, 9:10 p.m.
On Wed, Apr 27, 2011 at 10:54:37PM +0200, Mikael Morin wrote:
> On Wednesday 27 April 2011 01:06:26 Steve Kargl wrote:
> > 
> > It's an 'if -- else if' construct.  If gfc_notify_std == FAILURE, then
> > the error message is issues and the function returns.   If it is TRUE,
> > then there should be no messages and else if() is tested.
> My concern is that gfc_notify_std seems to return SUCCESS on warnings (I can't 
> test right now as make has decided to rebuild the whole middle-end :-(). Then, 
> I expect double warnings with -pedantic -Wreal-q-constant as -pedantic is a 
> (the only one ?) case outputing warnings for GNU extensions.
> 
> Mikael

laptop:kargl[220] gfc4x -pedantic -Wreal-q-constant -o z ui.f90
ui.f90:3.12:

   q = 1.23q45
            1
Warning: Extension: exponent-letter 'q' in real-literal-constant at (1)
laptop:kargl[221] gfc4x -pedantic -o z ui.f90
ui.f90:3.12:

   q = 1.23q45
            1
Warning: Extension: exponent-letter 'q' in real-literal-constant at (1)
laptop:kargl[222] gfc4x -Wreal-q-constant -o z ui.f90
ui.f90:3.12:

   q = 1.23q45
            1
Warning: Extension: exponent-letter 'q' in real-literal-constant at (1)

PS: People should not use -pedantic, anyway.  It doesn't do what
people think it does.
Mikael Morin - April 27, 2011, 11:06 p.m.
On Wednesday 27 April 2011 23:10:14 Steve Kargl wrote:
> On Wed, Apr 27, 2011 at 10:54:37PM +0200, Mikael Morin wrote:
> > On Wednesday 27 April 2011 01:06:26 Steve Kargl wrote:
> > > It's an 'if -- else if' construct.  If gfc_notify_std == FAILURE, then
> > > the error message is issues and the function returns.   If it is TRUE,
> > > then there should be no messages and else if() is tested.
> > 
> > My concern is that gfc_notify_std seems to return SUCCESS on warnings (I
> > can't test right now as make has decided to rebuild the whole middle-end
> > :-(). Then, I expect double warnings with -pedantic -Wreal-q-constant as
> > -pedantic is a (the only one ?) case outputing warnings for GNU
> > extensions.
> > 
> > Mikael
> 
> laptop:kargl[220] gfc4x -pedantic -Wreal-q-constant -o z ui.f90
> ui.f90:3.12:
> 
>    q = 1.23q45
>             1
> Warning: Extension: exponent-letter 'q' in real-literal-constant at (1)
> laptop:kargl[221] gfc4x -pedantic -o z ui.f90
> ui.f90:3.12:
> 
>    q = 1.23q45
>             1
> Warning: Extension: exponent-letter 'q' in real-literal-constant at (1)
> laptop:kargl[222] gfc4x -Wreal-q-constant -o z ui.f90
> ui.f90:3.12:
> 
>    q = 1.23q45
>             1
> Warning: Extension: exponent-letter 'q' in real-literal-constant at (1)
Well, that's something odd that I don't want to investigate further. 
As it is clean from a user point of view, let's move on.

Mikael

Patch

Index: gfortran.texi
===================================================================
--- gfortran.texi	(revision 172974)
+++ gfortran.texi	(working copy)
@@ -1237,6 +1237,7 @@  without warning.
 * Missing period in FORMAT specifications::
 * I/O item lists::
 * BOZ literal constants::
+* @code{Q} exponent-letter::
 * Real array indices::
 * Unary operators::
 * Implicitly convert LOGICAL and INTEGER values::
@@ -1427,6 +1428,18 @@  To support legacy codes, GNU Fortran all
 of the @code{READ} statement, and the output item lists of the
 @code{WRITE} and @code{PRINT} statements, to start with a comma.
 
+@node @code{Q} exponent-letter
+@subsection @code{Q} exponent-letter
+@cindex @code{Q} exponent-letter
+
+GNU Fortran accepts real literal constants with an exponent-letter
+of @code{Q}, for example, @code{1.23Q45}.  The constant is interpreted
+as a @code{REAL(16)} entity on targets that suppports this type.  If
+the target does not support @code{REAL(16)} but has a @code{REAL(10)}
+type, then the real-literal-constant will be interpreted as a
+@code{REAL(10)} entity.  In the absence of @code{REAL(16)} and
+@code{REAL(10)}, an error will occur.
+
 @node BOZ literal constants
 @subsection BOZ literal constants
 @cindex BOZ literal constants
Index: gfortran.h
===================================================================
--- gfortran.h	(revision 172974)
+++ gfortran.h	(working copy)
@@ -2189,6 +2189,7 @@  typedef struct
   int warn_character_truncation;
   int warn_array_temp;
   int warn_align_commons;
+  int warn_real_q_constant;
   int warn_unused_dummy_argument;
   int max_errors;
 
Index: lang.opt
===================================================================
--- lang.opt	(revision 172974)
+++ lang.opt	(working copy)
@@ -242,6 +242,10 @@  Wintrinsics-std
 Fortran Warning
 Warn on intrinsics not part of the selected standard
 
+Wreal-q-constant
+Fortran Warning
+Warn about real-literal-constants with 'q' exponent-letter
+
 Wreturn-type
 Fortran Warning
 ; Documented in C
Index: invoke.texi
===================================================================
--- invoke.texi	(revision 172974)
+++ invoke.texi	(working copy)
@@ -134,12 +134,13 @@  by type.  Explanations are in the follow
 @item Error and Warning Options
 @xref{Error and Warning Options,,Options to request or suppress errors
 and warnings}.
-@gccoptlist{-fmax-errors=@var{n} @gol
--fsyntax-only  -pedantic  -pedantic-errors @gol
--Wall  -Waliasing  -Wampersand  -Warray-bounds -Wcharacter-truncation @gol
--Wconversion -Wimplicit-interface  -Wimplicit-procedure  -Wline-truncation @gol
--Wintrinsics-std  -Wsurprising  -Wno-tabs  -Wunderflow  -Wunused-parameter @gol
--Wintrinsic-shadow  -Wno-align-commons -Wfunction-elimination}
+@gccoptlist{-fmax-errors=@var{n}
+-fsyntax-only -pedantic -pedantic-errors -Wall @gol
+-Waliasing -Wampersand -Warray-bounds -Wcharacter-truncation @gol
+-Wconversion -Wimplicit-interface -Wimplicit-procedure -Wline-truncation @gol
+-Wintrinsics-std -Wreal-q-format -Wsurprising -Wno-tabs -Wunderflow @gol
+-Wunused-parameter -Wintrinsic-shadow -Wno-align-commons @gol
+-Wfunction-elimination}
 
 @item Debugging Options
 @xref{Debugging Options,,Options for debugging your program or GNU Fortran}.
@@ -694,7 +695,7 @@  we recommend avoiding and that we believ
 This currently includes @option{-Waliasing}, @option{-Wampersand}, 
 @option{-Wconversion}, @option{-Wsurprising}, @option{-Wintrinsics-std},
 @option{-Wno-tabs}, @option{-Wintrinsic-shadow}, @option{-Wline-truncation},
-and @option{-Wunused}.
+@option{-Wreal-q-format} and @option{-Wunused}.
 
 @item -Waliasing
 @opindex @code{Waliasing}
@@ -782,6 +783,12 @@  it as @code{EXTERNAL} procedure because 
 be used to never trigger this behavior and always link to the intrinsic
 regardless of the selected standard.
 
+@item -Wreal-q-constant
+@opindex @code{Wreal-q-constant}
+@cindex warnings, @code{q} exponent-letter
+Produce a warning if a real-literal-constant contains a @code{q}
+exponent-letter.
+
 @item -Wsurprising
 @opindex @code{Wsurprising}
 @cindex warnings, suspicious code
Index: primary.c
===================================================================
--- primary.c	(revision 172974)
+++ primary.c	(working copy)
@@ -541,6 +541,17 @@  match_real_constant (gfc_expr **result, 
     goto done;
   exp_char = c;
 
+
+  if (c == 'q')
+    {
+      if (gfc_notify_std (GFC_STD_GNU, "Extension: exponent-letter 'q' in "
+			 "real-literal-constant at %C") == FAILURE)
+	return MATCH_ERROR;
+      else if (gfc_option.warn_real_q_constant)
+	gfc_warning("Extension: exponent-letter 'q' in real-literal-constant "
+		    "at %C");
+    }
+
   /* Scan exponent.  */
   c = gfc_next_ascii_char ();
   count++;
@@ -616,6 +627,29 @@  done:
       kind = gfc_default_double_kind;
       break;
 
+    case 'q':
+      if (kind != -2)
+	{
+	  gfc_error ("Real number at %C has a 'q' exponent and an explicit "
+		     "kind");
+	  goto cleanup;
+	}
+
+      /* The maximum possible real kind type parameter is 16.  First, try
+	 that for the kind, then fallback to trying kind=10 (Intel 80 bit)
+	 extended precision.  If neither value works, just given up.  */
+      kind = 16;
+      if (gfc_validate_kind (BT_REAL, kind, true) < 0)
+	{
+	  kind = 10;
+          if (gfc_validate_kind (BT_REAL, kind, true) < 0)
+	    {
+	      gfc_error ("Invalid real kind %d at %C", kind);
+	      goto cleanup;
+	    }
+	}
+      break;
+
     default:
       if (kind == -2)
 	kind = gfc_default_real_kind;
Index: options.c
===================================================================
--- options.c	(revision 172974)
+++ options.c	(working copy)
@@ -108,6 +108,7 @@  gfc_init_options (unsigned int decoded_o
   gfc_option.warn_intrinsic_shadow = 0;
   gfc_option.warn_intrinsics_std = 0;
   gfc_option.warn_align_commons = 1;
+  gfc_option.warn_real_q_constant = 0;
   gfc_option.warn_unused_dummy_argument = 0;
   gfc_option.max_errors = 25;
 
@@ -455,6 +456,7 @@  set_Wall (int setting)
   gfc_option.warn_intrinsic_shadow = setting;
   gfc_option.warn_intrinsics_std = setting;
   gfc_option.warn_character_truncation = setting;
+  gfc_option.warn_real_q_constant = setting;
   gfc_option.warn_unused_dummy_argument = setting;
 
   warn_unused = setting;
@@ -659,6 +661,10 @@  gfc_handle_option (size_t scode, const c
       gfc_option.warn_align_commons = value;
       break;
 
+    case OPT_Wreal_q_constant:
+      gfc_option.warn_real_q_constant = value;
+      break;
+
     case OPT_Wunused_dummy_argument:
       gfc_option.warn_unused_dummy_argument = value;
       break;