On Wed, Nov 09, 2011 at 06:09:58PM -0500, Andreas Kloeckner wrote:
>
> please find attached the patch and the Changelog entry for our work on
> the fortran bug #48426.
>
> The attached patch implements the options
>
> -finteger-4-integer-8
> -freal-4-real-8
> -freal-4-real-10
> -freal-4-real-16
> -freal-8-real-4
> -freal-8-real-10
> -freal-8-real-16
>
> to implement a variety of automatic type promotions. (This is
> particularly helpful if one wants to quickly check whether a
> certain code has a bug limiting its precision away from full
> machine accuracy.)
>
> A similar promotion feature is available in Fujitsu compilers, see here:
>
> http://www.lahey.com/docs/fujitsu%20compiler%20option%20list.pdf
>
> (e.g. -CcR8R16)
>
> The implementation work on this was done by Zydrunas Gimbutas, not by me.
> Zydrunas has authorized me to submit this for inclusion in gcc. Both he
> and I have gone through the FSF's copyright assignment process and have
> current papers for that on file.
>
> We tested the change by running Kahan's Fortran paranoia tests using all
> supported conversions, we ran the LINPACK tests (at all supported
> conversions) as well as a number of manually-written conversion tests.
>
All,
I have taken Zydrunas and Andreas patche applied it to my tree,
updated for it GNU Coding Style, and written the gfortran manual
entries. The ChangeLog is
2011-12-25 Zydrunas Gimbutas
Andreas Kloeckner
Steven G. Kargl
PR fortran/48426
* gfortran.h: Make global variables flag_*_kind to store
* lang.opt: Add options -freal-4-real-8, -freal-4-real-10,
-freal-4-real-16, -freal-8-real-4, -freal-8-real-10, -freal-8-real-16
and -finteger-4-integer-8.
user-desired type conversion information.
* decl.c (gfc_match_old_kind_spec,kind_expr): Type conversions
in declaration parsing.
* trans-types.c (gfc_init_kinds): User-specified type conversion
checked for current backend.
* primary.c (match_integer_constant,match_real_constant): Implement
type conversion in constant parsing.
* options.c (gfc_init_options,gfc_handle_option): Translate input
options to flags in internal options data structure.
* invoke.texi: Document new options. Re-order options in Options
summary section.
I regression tested the patch on i686-*-freebsd. No problems occurred.
Can one of the other gfortran reviewers/committers cast a quick glance
over the patch. I would like to commit this within next day or two.
OK for trunk?
--
Steve
Index: decl.c
===
--- decl.c (revision 182680)
+++ decl.c (working copy)
@@ -2101,6 +2101,33 @@ gfc_match_old_kind_spec (gfc_typespec *t
return MATCH_ERROR;
}
ts->kind /= 2;
+
+}
+
+ if (ts->type == BT_INTEGER && ts->kind == 4 && gfc_option.flag_integer4_kind == 8)
+ts->kind = 8;
+
+ if (ts->type == BT_REAL || ts->type == BT_COMPLEX)
+{
+ if (ts->kind == 4)
+ {
+ if (gfc_option.flag_real4_kind == 8)
+ ts->kind = 8;
+ if (gfc_option.flag_real4_kind == 10)
+ ts->kind = 10;
+ if (gfc_option.flag_real4_kind == 16)
+ ts->kind = 16;
+ }
+
+ if (ts->kind == 8)
+ {
+ if (gfc_option.flag_real8_kind == 4)
+ ts->kind = 4;
+ if (gfc_option.flag_real8_kind == 10)
+ ts->kind = 10;
+ if (gfc_option.flag_real8_kind == 16)
+ ts->kind = 16;
+ }
}
if (gfc_validate_kind (ts->type, ts->kind, true) < 0)
@@ -2246,7 +2273,33 @@ kind_expr:
if(m == MATCH_ERROR)
gfc_current_locus = where;
-
+
+ if (ts->type == BT_INTEGER && ts->kind == 4 && gfc_option.flag_integer4_kind == 8)
+ts->kind = 8;
+
+ if (ts->type == BT_REAL || ts->type == BT_COMPLEX)
+{
+ if (ts->kind == 4)
+ {
+ if (gfc_option.flag_real4_kind == 8)
+ ts->kind = 8;
+ if (gfc_option.flag_real4_kind == 10)
+ ts->kind = 10;
+ if (gfc_option.flag_real4_kind == 16)
+ ts->kind = 16;
+ }
+
+ if (ts->kind == 8)
+ {
+ if (gfc_option.flag_real8_kind == 4)
+ ts->kind = 4;
+ if (gfc_option.flag_real8_kind == 10)
+ ts->kind = 10;
+ if (gfc_option.flag_real8_kind == 16)
+ ts->kind = 16;
+ }
+}
+
/* Return what we know from the test(s). */
return m;
Index: trans-types.c
===
--- trans-types.c (revision 182680)
+++ trans-types.c (working copy)
@@ -362,7 +362,7 @@ gfc_init_kinds (void)
unsigned int mode;
int i_index, r_index, kind;
bool saw_i4 = false, saw_i8 = false;
- bool saw_r4 = false, saw_r8 = false, saw_r16 = false;
+ bool saw_r4 = false, saw_r8 = false, saw_r10 = false, saw_r16 = false;
for (i_index = 0, mode = MIN_MODE_INT; mode <= MAX_MODE_INT; mode++)
{
@@ -456,6 +456,8 @@ gfc_init_kinds (void)
saw_r4 = true;
if (kind == 8)
saw_r8 = true;
+ if (kind == 10)
+ saw_r10 = true;
if (kind ==