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

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

The attached patch has been bootstrapped and regression
tested on x86_64-*-freebsd.  There were no new failures
in the testsuite.

Much old code and even new code fail to compile due to 
the Fortran 95 requirements on BOZ-literal-constants.
Read the audit trail for PR 18026 for the gory details.

Consider the following example:

troutmask:sgk[207] cat po.f90
program po
  integer x
  data x/z'ffffffff'/
  print *, x
end program po
troutmask:sgk[208] gfc4x -o z po.f90

  data x/z'ffffffff'/
Error: Arithmetic overflow converting INTEGER(16) to INTEGER(4) at (1)
troutmask:sgk[209] gfc4x -o z -fboz-kind=4 po.f90
troutmask:sgk[210] ./z

The patch simply allows an person to set the kind type parameter
used in the conversion of a BOZ to an integer.  Note, this patch
does not deal with the much more difficult problem of the nonstandard
use of BOZ to affect a bitwise copy of the BOZ into a REAL.

2006-11-13  Steven G. Kargl  <kargl@gcc.gnu.org>

	PR fortran/18026
	* gfortran.texi: Update BOZ documentation to mention -fboz-kind.
	* gfortran.h (gfc_option_t): New member flag_boz_kind.
	* lang.opt: New option -fboz-kind=<n>.
	* invoke.texi: Document -fboz-kind.
	* primary.c (match_boz_constant):  Use option and member.
	* options.c (gfc_init_options):  Initialize flag_boz_kind
	(gfc_handle_option): Parse option.


-------------- next part --------------
Index: gfortran.texi
--- gfortran.texi	(revision 118777)
+++ 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 exponent
+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 118777)
+++ 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 118777)
+++ 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 118777)
+++ 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 118777)
+++ primary.c	(working copy)
@@ -412,10 +412,12 @@ match_boz_constant (gfc_expr ** result)
      the representation method with the largest decimal exponent range
      supported by the processor."  */
-  kind = gfc_max_integer_kind;
+  kind = gfc_option.flag_boz_kind != 0
+    ? gfc_option.flag_boz_kind : gfc_max_integer_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 118777)
+++ 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