[gfortran] Specific MIN and MAX intrinsics.

Paul Brook paul@codesourcery.com
Sat Jan 10 21:14:00 GMT 2004


When specific named min and max intrinsics are used (eg. amax0) are used we 
end up with calls where the type of the result does not match the type of the 
arguments.

The proper solution is to deal with these during resolution. As a temporary 
hack we instead do the conversions as when building the trees.

Paul

2004-01-10  Paul Brook  <paul@codesourcery.com>

	* trans-intrinsic.c (gfc_conv_intrinsic_minmax): Convert mismatched
	types.

	* gfortran.fortran-torture/execute/intrinsic_minmax.f90: Test
	specific names.

Index: fortran/trans-intrinsic.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/Attic/trans-intrinsic.c,v
retrieving revision 1.1.2.25
diff -u -p -r1.1.2.25 trans-intrinsic.c
--- fortran/trans-intrinsic.c	31 Dec 2003 12:15:42 -0000	1.1.2.25
+++ fortran/trans-intrinsic.c	10 Jan 2004 21:01:46 -0000
@@ -981,6 +981,8 @@ gfc_conv_intrinsic_char (gfc_se * se, gf
     }
  */
 
+/* TODO: Mismatching types can occur when specific names are used.
+   These should be handled during resolution.  */
 static void
 gfc_conv_intrinsic_minmax (gfc_se * se, gfc_expr * expr, int op)
 {
@@ -997,8 +999,10 @@ gfc_conv_intrinsic_minmax (gfc_se * se, 
   type = gfc_typenode_for_spec (&expr->ts);
 
   limit = TREE_VALUE (arg);
+  if (TREE_TYPE (limit) != type)
+    limit = convert (type, limit);
   /* Only evaluate the argument once.  */
-  if (TREE_CODE (limit) != VAR_DECL || !TREE_CONSTANT (limit))
+  if (TREE_CODE (limit) != VAR_DECL && !TREE_CONSTANT (limit))
     limit = gfc_evaluate_now(limit, &se->pre);
 
   mvar = gfc_create_var (type, "M");
@@ -1006,11 +1010,14 @@ gfc_conv_intrinsic_minmax (gfc_se * se, 
   for (arg = TREE_CHAIN (arg); arg != NULL_TREE; arg = TREE_CHAIN (arg))
     {
       val = TREE_VALUE (arg);
+      if (TREE_TYPE (val) != type)
+	val = convert (type, val);
+
       /* Only evaluate the argument once.  */
-      if (TREE_CODE (val) != VAR_DECL || !TREE_CONSTANT (val))
+      if (TREE_CODE (val) != VAR_DECL && !TREE_CONSTANT (val))
         val = gfc_evaluate_now(val, &se->pre);
 
-      thencase = build_v (MODIFY_EXPR, mvar, val);
+      thencase = build_v (MODIFY_EXPR, mvar, convert (type, val));
 
       tmp = build (op, boolean_type_node, val, limit);
       tmp = build_v (COND_EXPR, tmp, thencase, elsecase);
Index: testsuite/gfortran.fortran-torture/execute/intrinsic_minmax.f90
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/gfortran.fortran-torture/execute/Attic/
intrinsic_minmax.f90,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 intrinsic_minmax.f90
--- testsuite/gfortran.fortran-torture/execute/intrinsic_minmax.f90	26 Jul 
2003 16:27:49 -0000	1.1.2.1
+++ testsuite/gfortran.fortran-torture/execute/intrinsic_minmax.f90	10 Jan 
2004 21:01:49 -0000
@@ -24,5 +24,7 @@ program intrinsic_minmax
    if (max (r, s, t, u) .ne. 4) call abort
 
    if (max (4d0, r) .ne. 4d0) call abort
+   if (amax0 (i, j) .ne. 1.0) call abort
+   if (min1 (r, s) .ne. -2) call abort
 end program
 



More information about the Gcc-patches mailing list