[FORTRAN] New -fboz-kind option to aid compilation of legacy code

Steve Kargl sgk@troutmask.apl.washington.edu
Tue Nov 14 19:06:00 GMT 2006

On Mon, Nov 13, 2006 at 09:24:39PM -0800, Brooks Moses wrote:
> Steve Kargl wrote:
> >On Mon, Nov 13, 2006 at 06:36:13PM -0800, Brooks Moses wrote:
> >>Though I agree that the "largest decimal representation" wording should 
> >>be improved, I don't quite like the idea of an integer type with an 
> >>"exponent range".  Perhaps just "largest range"?
> >
> >Check the Standard.  That wording comes directly from F2003.
> Fair point; it does say exactly that.  I still don't like the wording 
> despite the provenance, but I won't object if you want to leave it.

I went ahead and removed "exponent" in the description.

> >>Also, there isn't a check to confirm that a valid kind type is supplied, 
> >>and so I'll bet you ICE on an invalid kind.  Unfortunately, this can't 
> >>be checked in options.c (despite the fact that -qkind tried to do it 
> >>that way), since the kind types haven't been processed when that's run. 
> >
> >gfc_convert_integer issues an error of the form
> >
> >Error: Can't convert INTEGER(42) to INTEGER(4) at (1).
> >
> >If you prefer I can add a call to gfc_validate_kind right before
> >the BOZ conversion.
> I think a slightly clearer error would be better, yeah.  I'm also still 
> in favor of having it be a fatal error that happens once at startup 
> before any code processing occurs, like the other errors that come from 
> invalid options, but I wouldn't object too strenuously to having it 
> happen at the point of conversion instead.

I've added the gfc_validate_kind into matcher of BOZ literal 
constants.  For invalid kinds, gfortran now gives

troutmask:sgk[206] gfc4x -o z -fboz-kind=42 po.f90
Fatal Error: Invalid kind given in -fboz-kind=42 option

I tried a warning and resetting kind to the max kind type parameter,
but the warning got overwhelmed by ensuing overflow error.
-------------- next part --------------
Index: gfortran.texi
--- gfortran.texi	(revision 118820)
+++ gfortran.texi	(working copy)
@@ -908,10 +908,12 @@ in any initialization expression as well
 Attempts to use a BOZ literal constant to do a bitwise initialization of a
 variable can lead to confusion.  A BOZ literal constant is converted to an
-@code{INTEGER} value with the kind type with the largest decimal representation,
-and this value is then converted numerically to the type and kind of the
-variable in question.  Thus, one should not expect a bitwise copy of the BOZ
-literal constant to be assigned to a @code{REAL} variable.
+@code{INTEGER} value with the kind type with the largest decimal
+range, and this value is then converted numerically to the type and kind
+of the variable in question.  Thus, one should not expect a bitwise copy
+of the BOZ literal constant to be assigned to a @code{REAL} variable.
+The kind type parameter of the conversion can be controlled by the
+@option{-fboz-kind=@var{n}} option.
 Similarly, initializing an @code{INTEGER} variable with a statement such as
 @code{DATA i/Z'FFFFFFFF'/} will produce an integer overflow rather than the
Index: gfortran.h
--- gfortran.h	(revision 118820)
+++ gfortran.h	(working copy)
@@ -1632,6 +1632,7 @@ typedef struct
   int max_errors;
   int flag_all_intrinsics;
+  int flag_boz_kind;
   int flag_default_double;
   int flag_default_integer;
   int flag_default_real;
Index: lang.opt
--- lang.opt	(revision 118820)
+++ lang.opt	(working copy)
@@ -93,6 +93,10 @@ fblas-matmul-limit=
 Fortran RejectNegative Joined UInteger
 -fblas-matmul-limit=<n>        Size of the smallest matrix for which matmul will use BLAS
+Fortran RejectNegative Joined UInteger
+-fboz-kind=<n>        Set the INTEGER kind type parameter for BOZ conversion
 Set the default double precision kind to an 8 byte wide type
Index: invoke.texi
--- invoke.texi	(revision 118820)
+++ invoke.texi	(working copy)
@@ -115,7 +115,8 @@ by type.  Explanations are in the follow
 @table @emph
 @item Fortran Language Options
 @xref{Fortran Dialect Options,,Options Controlling Fortran Dialect}.
-@gccoptlist{-fall-intrinsics  -ffree-form  -fno-fixed-form @gol
+@gccoptlist{-fall-intrinsics  -fboz-kind=@var{n}  -fboz-kind  @gol
+-ffree-form  -fno-fixed-form @gol
 -fdollar-ok  -fimplicit-none  -fmax-identifier-length @gol
 -std=@var{std} -fd-lines-as-code  -fd-lines-as-comments @gol
 -ffixed-line-length-@var{n}  -ffixed-line-length-none @gol
@@ -196,6 +197,13 @@ Accept all of the intrinsic procedures p
 without regard to the setting of @option{-std}.  In particular, 
 this option can be quite useful with @option{-std=f95}.  Additionally,
 @command{gfortran} will ignore @option{-Wnonstd-intrinsics}.
+@cindex -fboz-kind
+@item -fboz-kind=@var{n}
+Set @code{INTEGER} kind type parameter to @var{n} for the conversion of
+a BOZ literal constants into an integer.  This option applies to
+all BOZ literal constants with the file and it also disables
+the range checking performed immediately after conversion.
 @cindex option, -fd-lines-as-code
 @cindex -fd-lines-as-code, option
Index: primary.c
--- primary.c	(revision 118820)
+++ primary.c	(working copy)
@@ -413,9 +413,18 @@ match_boz_constant (gfc_expr ** result)
      supported by the processor."  */
   kind = gfc_max_integer_kind;
+  if (gfc_option.flag_boz_kind != 0)
+    {
+      if (gfc_validate_kind (BT_INTEGER, gfc_option.flag_boz_kind, true) == -1)
+	gfc_fatal_error ("Invalid kind given in -fboz-kind=%d option",
+			gfc_option.flag_boz_kind);
+      kind = gfc_option.flag_boz_kind;
+    }
   e = gfc_convert_integer (buffer, kind, radix, &gfc_current_locus);
-  if (gfc_range_check (e) != ARITH_OK)
+  if (gfc_option.flag_boz_kind == 0 && gfc_range_check (e) != ARITH_OK)
       gfc_error ("Integer too big for integer kind %i at %C", kind);
       gfc_free_expr (e);
Index: options.c
--- options.c	(revision 118820)
+++ options.c	(working copy)
@@ -64,6 +64,7 @@ gfc_init_options (unsigned int argc ATTR
   gfc_option.max_errors = 25;
   gfc_option.flag_all_intrinsics = 0;
+  gfc_option.flag_boz_kind = 0;
   gfc_option.flag_default_double = 0;
   gfc_option.flag_default_integer = 0;
   gfc_option.flag_default_real = 0;
@@ -456,6 +457,10 @@ gfc_handle_option (size_t scode, const c
     case OPT_fblas_matmul_limit_:
       gfc_option.blas_matmul_limit = value;
+      break;
+    case OPT_fboz_kind_:
+      gfc_option.flag_boz_kind = value;
     case OPT_fd_lines_as_code:

More information about the Gcc-patches mailing list