This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[gfortran] Specific MIN and MAX intrinsics.
- From: Paul Brook <paul at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org, fortran at gcc dot gnu dot org
- Date: Sat, 10 Jan 2004 21:14:41 +0000
- Subject: [gfortran] Specific MIN and MAX intrinsics.
- Organization: CodeSourcery
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