This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug fortran/32298] MINLOC / MAXLOC: off-by one for PARAMETER arrays
- From: "pault at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 20 Jun 2007 12:15:24 -0000
- Subject: [Bug fortran/32298] MINLOC / MAXLOC: off-by one for PARAMETER arrays
- References: <bug-32298-14685@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #3 from pault at gcc dot gnu dot org 2007-06-20 12:15 -------
This does the job by detecting the generation of a temporary. In this case the
loop is zero based but the calculated value for the position does not reflect
this.
I'll have a think about whether or not this is the cleanest way to fix the bug
and then I will submit tonight.
Paul
Index: gcc/fortran/trans-intrinsic.c
===================================================================
*** gcc/fortran/trans-intrinsic.c (révision 125706)
--- gcc/fortran/trans-intrinsic.c (copie de travail)
*************** gfc_conv_intrinsic_minmaxloc (gfc_se * s
*** 2046,2052 ****
gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
/* Remember where we are. */
! gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]);
ifbody = gfc_finish_block (&ifblock);
--- 2046,2060 ----
gfc_add_modify_expr (&ifblock, limit, arrayse.expr);
/* Remember where we are. */
! if (loop.temp_dim)
! {
! tmp = build2 (PLUS_EXPR, TREE_TYPE (pos),
! loop.loopvar[0],
! build_int_cst (type, 1));
! gfc_add_modify_expr (&ifblock, pos, tmp);
! }
! else
! gfc_add_modify_expr (&ifblock, pos, loop.loopvar[0]);
ifbody = gfc_finish_block (&ifblock);
*************** gfc_conv_intrinsic_minmaxloc (gfc_se * s
*** 2099,2109 ****
gfc_cleanup_loop (&loop);
/* Return a value in the range 1..SIZE(array). */
! tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, loop.from[0],
! gfc_index_one_node);
! tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, pos, tmp);
/* And convert to the required type. */
! se->expr = convert (type, tmp);
}
static void
--- 2107,2120 ----
gfc_cleanup_loop (&loop);
/* Return a value in the range 1..SIZE(array). */
! if (!loop.temp_dim)
! {
! tmp = fold_build2 (MINUS_EXPR, gfc_array_index_type, loop.from[0],
! gfc_index_one_node);
! pos = fold_build2 (MINUS_EXPR, gfc_array_index_type, pos, tmp);
! }
/* And convert to the required type. */
! se->expr = convert (type, pos);
}
static void
Index: gcc/testsuite/gfortran.dg/minmax_loc_1.f90
===================================================================
*** gcc/testsuite/gfortran.dg/minmax_loc_1.f90 (révision 0)
--- gcc/testsuite/gfortran.dg/minmax_loc_1.f90 (révision 0)
***************
*** 0 ****
--- 1,29 ----
+ ! { dg-do run }
+ ! Tests the fix for PR32298, in which the scalarizer would generate
+ ! a temporary in the course of evaluating MINLOC or MAXLOC, thereby
+ ! setting the start of the scalarizer loop to zero.
+ !
+ ! Contributed by Jens Bischoff <jens.bischoff@freenet.de>
+ !
+ PROGRAM ERR_MINLOC
+
+ INTEGER, PARAMETER :: N = 7
+
+ DOUBLE PRECISION, DIMENSION (N), PARAMETER :: A &
+ = (/ 0.3D0, 0.455D0, 0.6D0, 0.7D0, 0.72D0, 0.76D0, 0.79D0 /)
+
+ DOUBLE PRECISION :: B
+ INTEGER :: I, J(N), K(N)
+
+ DO I = 1, N
+ B = A(I)
+ J(I) = MINLOC (ABS (A - B), 1)
+ K(I) = MAXLOC (ABS (A - B), 1)
+ END DO
+
+ if (any (J .NE. (/1,2,3,4,5,6,7/))) call abort ()
+ if (any (K .NE. (/7,7,1,1,1,1,1/))) call abort ()
+
+ STOP
+
+ END PROGRAM ERR_MINLOC
--
pault at gcc dot gnu dot org changed:
What |Removed |Added
----------------------------------------------------------------------------
AssignedTo|unassigned at gcc dot gnu |pault at gcc dot gnu dot org
|dot org |
Status|NEW |ASSIGNED
Last reconfirmed|2007-06-12 16:05:26 |2007-06-20 12:15:24
date| |
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32298