[PATCH] PR fortran/20786
Steve Kargl
sgk@troutmask.apl.washington.edu
Thu Oct 6 23:54:00 GMT 2005
The attached patch has been bubblestrapped and regression tested
on amd64-*-freebsd.
What does it do? Currently, the program
program aint_test
implicit none
real(4) :: r = 42.0
r = aint(r,kind=8)
print *, r
end program aint_test
generates a value of 0.0, which is wrong by 42.0. The problem
comes from iresolve.c and trans-intrinsic.c confusion. In
iresolve,c, we set the KIND of the return value to kind=8, which
is then used by trans-intrincis.c to find __builtin_trunc. Here
is a snippet from -fdump-tree-original.
MAIN__ ()
{
static real4 r = 4.2e+1;
r = (real4) __builtin_trunc (r, 8);
}
Note, we are indeed using a function that returns a kind=8
value. However, we are feeding the functions a kind=4 variable.
So, the patch will convert the type of the argument to the
KIND of the kind variable if it is present in aint(r, [kind]).
With the patch installed, -fdump-tree-original gives
MAIN__ ()
{
static real4 r = 4.26999969482421875e+1;
r = (real4) __builtin_trunc ((real8) r, 8);
}
which will generate the desired result of 42.
OK for mainline and 4.0?
2005-10-06 Steven G. Kargl <kargls@comcast.net>
PR fortran/20786
*iresolve.c (gfc_resolve_aint, gfc_resolve_anint ): Type conversion
of the argument.
PR fortran/20786
gfortran.dg/aint_anint_1.f90: New test.
--
Steve
-------------- next part --------------
program aint_anint_1
implicit none
real(4) :: r = 42.7, r1, r2
real(8) :: s = 42.7D0, s1, s2
r1 = aint(r)
r2 = aint(r,kind=8)
if (abs(r1 - r2) > 0.1) call abort()
r1 = anint(r)
r2 = anint(r,kind=8)
if (abs(r1 - r2) > 0.1) call abort()
s1 = aint(s)
s2 = aint(s, kind=4)
if (abs(s1 - s2) > 0.1) call abort()
s1 = anint(s)
s2 = anint(s, kind=4)
if (abs(s1 - s2) > 0.1) call abort()
end program aint_anint_1
-------------- next part --------------
Index: iresolve.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/iresolve.c,v
retrieving revision 1.41
diff -c -p -r1.41 iresolve.c
*** iresolve.c 3 Oct 2005 07:22:18 -0000 1.41
--- iresolve.c 6 Oct 2005 22:55:58 -0000
*************** gfc_resolve_aimag (gfc_expr * f, gfc_exp
*** 105,113 ****
--- 105,121 ----
void
gfc_resolve_aint (gfc_expr * f, gfc_expr * a, gfc_expr * kind)
{
+ gfc_typespec ts;
+
f->ts.type = a->ts.type;
f->ts.kind = (kind == NULL) ? a->ts.kind : mpz_get_si (kind->value.integer);
+ if (a->ts.kind != f->ts.kind)
+ {
+ ts.type = f->ts.type;
+ ts.kind = f->ts.kind;
+ gfc_convert_type (a, &ts, 2);
+ }
/* The resolved name is only used for specific intrinsics where
the return kind is the same as the arg kind. */
f->value.function.name =
*************** gfc_resolve_all (gfc_expr * f, gfc_expr
*** 143,151 ****
--- 151,168 ----
void
gfc_resolve_anint (gfc_expr * f, gfc_expr * a, gfc_expr * kind)
{
+ gfc_typespec ts;
+
f->ts.type = a->ts.type;
f->ts.kind = (kind == NULL) ? a->ts.kind : mpz_get_si (kind->value.integer);
+ if (a->ts.kind != f->ts.kind)
+ {
+ ts.type = f->ts.type;
+ ts.kind = f->ts.kind;
+ gfc_convert_type (a, &ts, 2);
+ }
+
/* The resolved name is only used for specific intrinsics where
the return kind is the same as the arg kind. */
f->value.function.name =
More information about the Fortran
mailing list