[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