diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2018-01-15 18:35:13 +0000 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2018-01-15 18:35:13 +0000 |
commit | 64b1806b2d94fd325759761b64fb7507ca83d5d2 (patch) | |
tree | e14d0d04d69a89aa4bda7faa882d36121d76f08b /gcc/fortran | |
parent | 650d669bb4a74cd2cc17d80b110d0f666d3f5bee (diff) | |
download | gcc-64b1806b2d94fd325759761b64fb7507ca83d5d2.zip gcc-64b1806b2d94fd325759761b64fb7507ca83d5d2.tar.gz gcc-64b1806b2d94fd325759761b64fb7507ca83d5d2.tar.bz2 |
re PR fortran/54613 ([F08] Add FINDLOC plus support MAXLOC/MINLOC with KIND=/BACK=)
2018-01-15 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/54613
* gfortran.h (gfc_check_f): Rename f4ml to f5ml.
(gfc_logical_4_kind): New macro
* intrinsic.h (gfc_simplify_minloc): Add a gfc_expr *argument.
(gfc_simplify_maxloc): Likewise.
(gfc_resolve_maxloc): Likewise.
(gfc_resolve_minloc): Likewise.
* check.c (gfc_check_minloc_maxloc): Add checking for "back"
argument; also raise error if it is used (for now). Add it
if it isn't present.
* intrinsic.c (add_sym_4ml): Rename to
(add_sym_5ml), adjust for extra argument.
(add_functions): Add "back" constant. Adjust maxloc and minloc
for back argument.
* iresolve.c (gfc_resolve_maxloc): Add back argument. If back is
not of gfc_logical_4_kind, convert.
(gfc_resolve_minloc): Likewise.
* simplify.c (gfc_simplify_minloc): Add back argument.
(gfc_simplify_maxloc): Likewise.
* trans-intinsic.c (gfc_conv_intrinsic_minmaxloc): Rename last
argument to %VAL to ensure passing by value.
(gfc_conv_intrinsic_function): Call gfc_conv_intrinsic_minmaxloc
also for library calls.
2018-01-15 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/54613
* m4/iparm.m4: Add back_arg macro if in minloc or maxloc.
* m4/iforeach-s.m4: Add optional argument back with back_arg
macro. Improve m4 quoting. If HAVE_BACK_ARG is defined, assert
that back is non-true.
* m4/iforeach.m4: Likewise.
* m4/ifunction-s.m4: Likewise.
* m4/ifunction.m4: Likewise.
* m4/maxloc0.m4: Include assert.h
* m4/minloc0.m4: Likewise.
* m4/maxloc0s.m4: #define HAVE_BACK_ARG.
* m4/minloc0s.m4: Likewise.
* m4/maxloc1s.m4: Likewise.
* m4/minloc1s.m4: Likewise.
* m4/maxloc1.m4: Include assert.h, #define HAVE_BACK_ARG.
* m4/minloc1.m4: Likewise.
* m4/maxloc2s.m4: Add assert.h, add back_arg, assert that
back is non-true.
* m4/minloc2s.m4: Likewise.
* generated/iall_i1.c: Regenerated.
* generated/iall_i16.c: Regenerated.
* generated/iall_i2.c: Regenerated.
* generated/iall_i4.c: Regenerated.
* generated/iall_i8.c: Regenerated.
* generated/iany_i1.c: Regenerated.
* generated/iany_i16.c: Regenerated.
* generated/iany_i2.c: Regenerated.
* generated/iany_i4.c: Regenerated.
* generated/iany_i8.c: Regenerated.
* generated/iparity_i1.c: Regenerated.
* generated/iparity_i16.c: Regenerated.
* generated/iparity_i2.c: Regenerated.
* generated/iparity_i4.c: Regenerated.
* generated/iparity_i8.c: Regenerated.
* generated/maxloc0_16_i1.c: Regenerated.
* generated/maxloc0_16_i16.c: Regenerated.
* generated/maxloc0_16_i2.c: Regenerated.
* generated/maxloc0_16_i4.c: Regenerated.
* generated/maxloc0_16_i8.c: Regenerated.
* generated/maxloc0_16_r10.c: Regenerated.
* generated/maxloc0_16_r16.c: Regenerated.
* generated/maxloc0_16_r4.c: Regenerated.
* generated/maxloc0_16_r8.c: Regenerated.
* generated/maxloc0_16_s1.c: Regenerated.
* generated/maxloc0_16_s4.c: Regenerated.
* generated/maxloc0_4_i1.c: Regenerated.
* generated/maxloc0_4_i16.c: Regenerated.
* generated/maxloc0_4_i2.c: Regenerated.
* generated/maxloc0_4_i4.c: Regenerated.
* generated/maxloc0_4_i8.c: Regenerated.
* generated/maxloc0_4_r10.c: Regenerated.
* generated/maxloc0_4_r16.c: Regenerated.
* generated/maxloc0_4_r4.c: Regenerated.
* generated/maxloc0_4_r8.c: Regenerated.
* generated/maxloc0_4_s1.c: Regenerated.
* generated/maxloc0_4_s4.c: Regenerated.
* generated/maxloc0_8_i1.c: Regenerated.
* generated/maxloc0_8_i16.c: Regenerated.
* generated/maxloc0_8_i2.c: Regenerated.
* generated/maxloc0_8_i4.c: Regenerated.
* generated/maxloc0_8_i8.c: Regenerated.
* generated/maxloc0_8_r10.c: Regenerated.
* generated/maxloc0_8_r16.c: Regenerated.
* generated/maxloc0_8_r4.c: Regenerated.
* generated/maxloc0_8_r8.c: Regenerated.
* generated/maxloc0_8_s1.c: Regenerated.
* generated/maxloc0_8_s4.c: Regenerated.
* generated/maxloc1_16_i1.c: Regenerated.
* generated/maxloc1_16_i16.c: Regenerated.
* generated/maxloc1_16_i2.c: Regenerated.
* generated/maxloc1_16_i4.c: Regenerated.
* generated/maxloc1_16_i8.c: Regenerated.
* generated/maxloc1_16_r10.c: Regenerated.
* generated/maxloc1_16_r16.c: Regenerated.
* generated/maxloc1_16_r4.c: Regenerated.
* generated/maxloc1_16_r8.c: Regenerated.
* generated/maxloc1_16_s1.c: Regenerated.
* generated/maxloc1_16_s4.c: Regenerated.
* generated/maxloc1_4_i1.c: Regenerated.
* generated/maxloc1_4_i16.c: Regenerated.
* generated/maxloc1_4_i2.c: Regenerated.
* generated/maxloc1_4_i4.c: Regenerated.
* generated/maxloc1_4_i8.c: Regenerated.
* generated/maxloc1_4_r10.c: Regenerated.
* generated/maxloc1_4_r16.c: Regenerated.
* generated/maxloc1_4_r4.c: Regenerated.
* generated/maxloc1_4_r8.c: Regenerated.
* generated/maxloc1_4_s1.c: Regenerated.
* generated/maxloc1_4_s4.c: Regenerated.
* generated/maxloc1_8_i1.c: Regenerated.
* generated/maxloc1_8_i16.c: Regenerated.
* generated/maxloc1_8_i2.c: Regenerated.
* generated/maxloc1_8_i4.c: Regenerated.
* generated/maxloc1_8_i8.c: Regenerated.
* generated/maxloc1_8_r10.c: Regenerated.
* generated/maxloc1_8_r16.c: Regenerated.
* generated/maxloc1_8_r4.c: Regenerated.
* generated/maxloc1_8_r8.c: Regenerated.
* generated/maxloc1_8_s1.c: Regenerated.
* generated/maxloc1_8_s4.c: Regenerated.
* generated/maxval_i1.c: Regenerated.
* generated/maxval_i16.c: Regenerated.
* generated/maxval_i2.c: Regenerated.
* generated/maxval_i4.c: Regenerated.
* generated/maxval_i8.c: Regenerated.
* generated/maxval_r10.c: Regenerated.
* generated/maxval_r16.c: Regenerated.
* generated/maxval_r4.c: Regenerated.
* generated/maxval_r8.c: Regenerated.
* generated/minloc0_16_i1.c: Regenerated.
* generated/minloc0_16_i16.c: Regenerated.
* generated/minloc0_16_i2.c: Regenerated.
* generated/minloc0_16_i4.c: Regenerated.
* generated/minloc0_16_i8.c: Regenerated.
* generated/minloc0_16_r10.c: Regenerated.
* generated/minloc0_16_r16.c: Regenerated.
* generated/minloc0_16_r4.c: Regenerated.
* generated/minloc0_16_r8.c: Regenerated.
* generated/minloc0_16_s1.c: Regenerated.
* generated/minloc0_16_s4.c: Regenerated.
* generated/minloc0_4_i1.c: Regenerated.
* generated/minloc0_4_i16.c: Regenerated.
* generated/minloc0_4_i2.c: Regenerated.
* generated/minloc0_4_i4.c: Regenerated.
* generated/minloc0_4_i8.c: Regenerated.
* generated/minloc0_4_r10.c: Regenerated.
* generated/minloc0_4_r16.c: Regenerated.
* generated/minloc0_4_r4.c: Regenerated.
* generated/minloc0_4_r8.c: Regenerated.
* generated/minloc0_4_s1.c: Regenerated.
* generated/minloc0_4_s4.c: Regenerated.
* generated/minloc0_8_i1.c: Regenerated.
* generated/minloc0_8_i16.c: Regenerated.
* generated/minloc0_8_i2.c: Regenerated.
* generated/minloc0_8_i4.c: Regenerated.
* generated/minloc0_8_i8.c: Regenerated.
* generated/minloc0_8_r10.c: Regenerated.
* generated/minloc0_8_r16.c: Regenerated.
* generated/minloc0_8_r4.c: Regenerated.
* generated/minloc0_8_r8.c: Regenerated.
* generated/minloc0_8_s1.c: Regenerated.
* generated/minloc0_8_s4.c: Regenerated.
* generated/minloc1_16_i1.c: Regenerated.
* generated/minloc1_16_i16.c: Regenerated.
* generated/minloc1_16_i2.c: Regenerated.
* generated/minloc1_16_i4.c: Regenerated.
* generated/minloc1_16_i8.c: Regenerated.
* generated/minloc1_16_r10.c: Regenerated.
* generated/minloc1_16_r16.c: Regenerated.
* generated/minloc1_16_r4.c: Regenerated.
* generated/minloc1_16_r8.c: Regenerated.
* generated/minloc1_16_s1.c: Regenerated.
* generated/minloc1_16_s4.c: Regenerated.
* generated/minloc1_4_i1.c: Regenerated.
* generated/minloc1_4_i16.c: Regenerated.
* generated/minloc1_4_i2.c: Regenerated.
* generated/minloc1_4_i4.c: Regenerated.
* generated/minloc1_4_i8.c: Regenerated.
* generated/minloc1_4_r10.c: Regenerated.
* generated/minloc1_4_r16.c: Regenerated.
* generated/minloc1_4_r4.c: Regenerated.
* generated/minloc1_4_r8.c: Regenerated.
* generated/minloc1_4_s1.c: Regenerated.
* generated/minloc1_4_s4.c: Regenerated.
* generated/minloc1_8_i1.c: Regenerated.
* generated/minloc1_8_i16.c: Regenerated.
* generated/minloc1_8_i2.c: Regenerated.
* generated/minloc1_8_i4.c: Regenerated.
* generated/minloc1_8_i8.c: Regenerated.
* generated/minloc1_8_r10.c: Regenerated.
* generated/minloc1_8_r16.c: Regenerated.
* generated/minloc1_8_r4.c: Regenerated.
* generated/minloc1_8_r8.c: Regenerated.
* generated/minloc1_8_s1.c: Regenerated.
* generated/minloc1_8_s4.c: Regenerated.
* generated/minval_i1.c: Regenerated.
* generated/minval_i16.c: Regenerated.
* generated/minval_i2.c: Regenerated.
* generated/minval_i4.c: Regenerated.
* generated/minval_i8.c: Regenerated.
* generated/minval_r10.c: Regenerated.
* generated/minval_r16.c: Regenerated.
* generated/minval_r4.c: Regenerated.
* generated/minval_r8.c: Regenerated.
* generated/norm2_r10.c: Regenerated.
* generated/norm2_r16.c: Regenerated.
* generated/norm2_r4.c: Regenerated.
* generated/norm2_r8.c: Regenerated.
* generated/parity_l1.c: Regenerated.
* generated/parity_l16.c: Regenerated.
* generated/parity_l2.c: Regenerated.
* generated/parity_l4.c: Regenerated.
* generated/parity_l8.c: Regenerated.
* generated/product_c10.c: Regenerated.
* generated/product_c16.c: Regenerated.
* generated/product_c4.c: Regenerated.
* generated/product_c8.c: Regenerated.
* generated/product_i1.c: Regenerated.
* generated/product_i16.c: Regenerated.
* generated/product_i2.c: Regenerated.
* generated/product_i4.c: Regenerated.
* generated/product_i8.c: Regenerated.
* generated/product_r10.c: Regenerated.
* generated/product_r16.c: Regenerated.
* generated/product_r4.c: Regenerated.
* generated/product_r8.c: Regenerated.
* generated/sum_c10.c: Regenerated.
* generated/sum_c16.c: Regenerated.
* generated/sum_c4.c: Regenerated.
* generated/sum_c8.c: Regenerated.
* generated/sum_i1.c: Regenerated.
* generated/sum_i16.c: Regenerated.
* generated/sum_i2.c: Regenerated.
* generated/sum_i4.c: Regenerated.
* generated/sum_i8.c: Regenerated.
* generated/sum_r10.c: Regenerated.
* generated/sum_r16.c: Regenerated.
* generated/sum_r4.c: Regenerated.
* generated/sum_r8.c: Regenerated.
2018-01-15 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/54613
* gfortran.dg/minmaxloc_9.f90: New test.
* gfortran.dg/minmaxloc_10.f90: New test.
* gfortran.dg/minmaxloc_11.f90: New test.
From-SVN: r256705
Diffstat (limited to 'gcc/fortran')
-rw-r--r-- | gcc/fortran/ChangeLog | 28 | ||||
-rw-r--r-- | gcc/fortran/check.c | 25 | ||||
-rw-r--r-- | gcc/fortran/gfortran.h | 4 | ||||
-rw-r--r-- | gcc/fortran/intrinsic.c | 34 | ||||
-rw-r--r-- | gcc/fortran/intrinsic.h | 10 | ||||
-rw-r--r-- | gcc/fortran/iresolve.c | 22 | ||||
-rw-r--r-- | gcc/fortran/simplify.c | 6 | ||||
-rw-r--r-- | gcc/fortran/trans-intrinsic.c | 46 |
8 files changed, 133 insertions, 42 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 7533171..453dc74 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,29 @@ +2018-01-15 Thomas Koenig <tkoenig@gcc.gnu.org> + + PR fortran/54613 + * gfortran.h (gfc_check_f): Rename f4ml to f5ml. + (gfc_logical_4_kind): New macro + * intrinsic.h (gfc_simplify_minloc): Add a gfc_expr *argument. + (gfc_simplify_maxloc): Likewise. + (gfc_resolve_maxloc): Likewise. + (gfc_resolve_minloc): Likewise. + * check.c (gfc_check_minloc_maxloc): Add checking for "back" + argument; also raise error if it is used (for now). Add it + if it isn't present. + * intrinsic.c (add_sym_4ml): Rename to + (add_sym_5ml), adjust for extra argument. + (add_functions): Add "back" constant. Adjust maxloc and minloc + for back argument. + * iresolve.c (gfc_resolve_maxloc): Add back argument. If back is + not of gfc_logical_4_kind, convert. + (gfc_resolve_minloc): Likewise. + * simplify.c (gfc_simplify_minloc): Add back argument. + (gfc_simplify_maxloc): Likewise. + * trans-intinsic.c (gfc_conv_intrinsic_minmaxloc): Rename last + argument to %VAL to ensure passing by value. + (gfc_conv_intrinsic_function): Call gfc_conv_intrinsic_minmaxloc + also for library calls. + 2018-01-13 Jerry DeLisle <jvdelisle@gcc.gnu.org> PR fortran/82007 @@ -6,7 +32,7 @@ format string or format label is present. * trans-io.c (get_dtio_proc): Likewise. (transfer_expr): Fix whitespace. - + 2018-01-13 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/83744 diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index fccb927..a2c8b52 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -3265,12 +3265,13 @@ gfc_check_matmul (gfc_expr *matrix_a, gfc_expr *matrix_b) DIM MASK I.e. in the case of minloc(array,mask), mask will be in the second - position of the argument list and we'll have to fix that up. */ + position of the argument list and we'll have to fix that up. Also, + add the BACK argument if that isn't present. */ bool gfc_check_minloc_maxloc (gfc_actual_arglist *ap) { - gfc_expr *a, *m, *d, *k; + gfc_expr *a, *m, *d, *k, *b; a = ap->expr; if (!int_or_real_or_char_check_f2003 (a, 0) || !array_check (a, 0)) @@ -3279,6 +3280,26 @@ gfc_check_minloc_maxloc (gfc_actual_arglist *ap) d = ap->next->expr; m = ap->next->next->expr; k = ap->next->next->next->expr; + b = ap->next->next->next->next->expr; + + if (b) + { + if (!type_check (b, 4, BT_LOGICAL) || !scalar_check (b,4)) + return false; + + /* TODO: Remove this once BACK is actually implemented. */ + if (b->expr_type != EXPR_CONSTANT || b->value.logical != 0) + { + gfc_error ("BACK argument to %qs intrinsic not yet " + "implemented", gfc_current_intrinsic); + return false; + } + } + else + { + b = gfc_get_logical_expr (gfc_default_logical_kind, NULL, 0); + ap->next->next->next->next->expr = b; + } if (m == NULL && d != NULL && d->ts.type == BT_LOGICAL && ap->next->name == NULL) diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index b3f8e42..6ddf450 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -1999,7 +1999,7 @@ typedef union bool (*f1m)(gfc_actual_arglist *); bool (*f2)(struct gfc_expr *, struct gfc_expr *); bool (*f3)(struct gfc_expr *, struct gfc_expr *, struct gfc_expr *); - bool (*f4ml)(gfc_actual_arglist *); + bool (*f5ml)(gfc_actual_arglist *); bool (*f3red)(gfc_actual_arglist *); bool (*f4)(struct gfc_expr *, struct gfc_expr *, struct gfc_expr *, struct gfc_expr *); @@ -2915,6 +2915,8 @@ extern int gfc_size_kind; extern int gfc_numeric_storage_size; extern int gfc_character_storage_size; +#define gfc_logical_4_kind 4 + /* symbol.c */ void gfc_clear_new_implicit (void); bool gfc_add_new_implicit_range (int, int); diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c index ed732aa..4844cee 100644 --- a/gcc/fortran/intrinsic.c +++ b/gcc/fortran/intrinsic.c @@ -687,29 +687,33 @@ add_sym_3 (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt ty might have to be reordered. */ static void -add_sym_4ml (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type, +add_sym_5ml (const char *name, gfc_isym_id id, enum klass cl, int actual_ok, bt type, int kind, int standard, bool (*check) (gfc_actual_arglist *), - gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *), - void (*resolve) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *), + gfc_expr *(*simplify) (gfc_expr *, gfc_expr *, gfc_expr *, + gfc_expr *, gfc_expr *), + void (*resolve) (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *, + gfc_expr *, gfc_expr *), const char *a1, bt type1, int kind1, int optional1, const char *a2, bt type2, int kind2, int optional2, const char *a3, bt type3, int kind3, int optional3, - const char *a4, bt type4, int kind4, int optional4) + const char *a4, bt type4, int kind4, int optional4, + const char *a5, bt type5, int kind5, int optional5) { gfc_check_f cf; gfc_simplify_f sf; gfc_resolve_f rf; - cf.f4ml = check; - sf.f4 = simplify; - rf.f4 = resolve; + cf.f5ml = check; + sf.f5 = simplify; + rf.f5 = resolve; add_sym (name, id, cl, actual_ok, type, kind, standard, cf, sf, rf, a1, type1, kind1, optional1, INTENT_IN, a2, type2, kind2, optional2, INTENT_IN, a3, type3, kind3, optional3, INTENT_IN, a4, type4, kind4, optional4, INTENT_IN, + a5, type5, kind5, optional5, INTENT_IN, (void *) 0); } @@ -1242,7 +1246,7 @@ add_functions (void) *num = "number", *tm = "time", *nm = "name", *md = "mode", *vl = "values", *p1 = "path1", *p2 = "path2", *com = "command", *ca = "coarray", *sub = "sub", *dist = "distance", *failed="failed", - *c_ptr_1 = "c_ptr_1", *c_ptr_2 = "c_ptr_2"; + *c_ptr_1 = "c_ptr_1", *c_ptr_2 = "c_ptr_2", *back = "back"; int di, dr, dd, dl, dc, dz, ii; @@ -2457,10 +2461,11 @@ add_functions (void) make_generic ("maxexponent", GFC_ISYM_MAXEXPONENT, GFC_STD_F95); - add_sym_4ml ("maxloc", GFC_ISYM_MAXLOC, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95, + add_sym_5ml ("maxloc", GFC_ISYM_MAXLOC, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95, gfc_check_minloc_maxloc, gfc_simplify_maxloc, gfc_resolve_maxloc, ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL, - msk, BT_LOGICAL, dl, OPTIONAL, kind, BT_INTEGER, di, OPTIONAL); + msk, BT_LOGICAL, dl, OPTIONAL, kind, BT_INTEGER, di, OPTIONAL, + back, BT_LOGICAL, dl, OPTIONAL); make_generic ("maxloc", GFC_ISYM_MAXLOC, GFC_STD_F95); @@ -2533,11 +2538,12 @@ add_functions (void) make_generic ("minexponent", GFC_ISYM_MINEXPONENT, GFC_STD_F95); - add_sym_4ml ("minloc", GFC_ISYM_MINLOC, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95, + add_sym_5ml ("minloc", GFC_ISYM_MINLOC, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_INTEGER, di, GFC_STD_F95, gfc_check_minloc_maxloc, gfc_simplify_minloc, gfc_resolve_minloc, ar, BT_REAL, dr, REQUIRED, dm, BT_INTEGER, ii, OPTIONAL, - msk, BT_LOGICAL, dl, OPTIONAL, kind, BT_INTEGER, di, OPTIONAL); - + msk, BT_LOGICAL, dl, OPTIONAL, kind, BT_INTEGER, di, OPTIONAL, + back, BT_LOGICAL, dl, OPTIONAL); + make_generic ("minloc", GFC_ISYM_MINLOC, GFC_STD_F95); add_sym_3red ("minval", GFC_ISYM_MINVAL, CLASS_TRANSFORMATIONAL, ACTUAL_NO, BT_REAL, dr, GFC_STD_F95, @@ -4500,7 +4506,7 @@ check_specific (gfc_intrinsic_sym *specific, gfc_expr *expr, int error_flag) if (!do_ts29113_check (specific, *ap)) return false; - if (specific->check.f4ml == gfc_check_minloc_maxloc) + if (specific->check.f5ml == gfc_check_minloc_maxloc) /* This is special because we might have to reorder the argument list. */ t = gfc_check_minloc_maxloc (*ap); else if (specific->check.f3red == gfc_check_minval_maxval) diff --git a/gcc/fortran/intrinsic.h b/gcc/fortran/intrinsic.h index a7db830..7615dd1 100644 --- a/gcc/fortran/intrinsic.h +++ b/gcc/fortran/intrinsic.h @@ -348,10 +348,12 @@ gfc_expr *gfc_simplify_maskr (gfc_expr *, gfc_expr *); gfc_expr *gfc_simplify_merge (gfc_expr *, gfc_expr *, gfc_expr *); gfc_expr *gfc_simplify_merge_bits (gfc_expr *, gfc_expr *, gfc_expr *); gfc_expr *gfc_simplify_min (gfc_expr *); -gfc_expr *gfc_simplify_minloc (gfc_expr*, gfc_expr *, gfc_expr *, gfc_expr *); +gfc_expr *gfc_simplify_minloc (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *, + gfc_expr *); gfc_expr *gfc_simplify_minval (gfc_expr *, gfc_expr*, gfc_expr*); gfc_expr *gfc_simplify_max (gfc_expr *); -gfc_expr *gfc_simplify_maxloc (gfc_expr*, gfc_expr *, gfc_expr *, gfc_expr *); +gfc_expr *gfc_simplify_maxloc (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *, + gfc_expr *); gfc_expr *gfc_simplify_maxval (gfc_expr *, gfc_expr*, gfc_expr*); gfc_expr *gfc_simplify_maxexponent (gfc_expr *); gfc_expr *gfc_simplify_minexponent (gfc_expr *); @@ -540,7 +542,7 @@ void gfc_resolve_logical (gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_lstat (gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_matmul (gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_max (gfc_expr *, gfc_actual_arglist *); -void gfc_resolve_maxloc (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); +void gfc_resolve_maxloc (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_maxval (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_mclock (gfc_expr *); void gfc_resolve_mclock8 (gfc_expr *); @@ -548,7 +550,7 @@ void gfc_resolve_mask (gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_merge (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_merge_bits (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_min (gfc_expr *, gfc_actual_arglist *); -void gfc_resolve_minloc (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); +void gfc_resolve_minloc (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_minval (gfc_expr *, gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_mod (gfc_expr *, gfc_expr *, gfc_expr *); void gfc_resolve_modulo (gfc_expr *, gfc_expr *, gfc_expr *); diff --git a/gcc/fortran/iresolve.c b/gcc/fortran/iresolve.c index 11f2569..9a4e199 100644 --- a/gcc/fortran/iresolve.c +++ b/gcc/fortran/iresolve.c @@ -1697,7 +1697,7 @@ gfc_resolve_max (gfc_expr *f, gfc_actual_arglist *args) void gfc_resolve_maxloc (gfc_expr *f, gfc_expr *array, gfc_expr *dim, - gfc_expr *mask, gfc_expr *kind) + gfc_expr *mask, gfc_expr *kind, gfc_expr *back) { const char *name; int i, j, idim; @@ -1781,6 +1781,15 @@ gfc_resolve_maxloc (gfc_expr *f, gfc_expr *array, gfc_expr *dim, ts.kind = fkind; gfc_convert_type_warn (f, &ts, 2, 0); } + + if (back->ts.kind != gfc_logical_4_kind) + { + gfc_typespec ts; + gfc_clear_ts (&ts); + ts.type = BT_LOGICAL; + ts.kind = gfc_logical_4_kind; + gfc_convert_type_warn (back, &ts, 2, 0); + } } @@ -1907,7 +1916,7 @@ gfc_resolve_min (gfc_expr *f, gfc_actual_arglist *args) void gfc_resolve_minloc (gfc_expr *f, gfc_expr *array, gfc_expr *dim, - gfc_expr *mask, gfc_expr *kind) + gfc_expr *mask, gfc_expr *kind, gfc_expr *back) { const char *name; int i, j, idim; @@ -1986,6 +1995,15 @@ gfc_resolve_minloc (gfc_expr *f, gfc_expr *array, gfc_expr *dim, ts.kind = fkind; gfc_convert_type_warn (f, &ts, 2, 0); } + + if (back->ts.kind != gfc_logical_4_kind) + { + gfc_typespec ts; + gfc_clear_ts (&ts); + ts.type = BT_LOGICAL; + ts.kind = gfc_logical_4_kind; + gfc_convert_type_warn (back, &ts, 2, 0); + } } diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 3e5abd4..b7c6b02 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -5343,13 +5343,15 @@ gfc_simplify_minmaxloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, } gfc_expr * -gfc_simplify_minloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, gfc_expr *kind) +gfc_simplify_minloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, gfc_expr *kind, + gfc_expr *back ATTRIBUTE_UNUSED) { return gfc_simplify_minmaxloc (array, dim, mask, kind, -1); } gfc_expr * -gfc_simplify_maxloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, gfc_expr *kind) +gfc_simplify_maxloc (gfc_expr *array, gfc_expr *dim, gfc_expr *mask, gfc_expr *kind, + gfc_expr *back ATTRIBUTE_UNUSED) { return gfc_simplify_minmaxloc (array, dim, mask, kind, 1); } diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c index 7fe8286..f4defb0 100644 --- a/gcc/fortran/trans-intrinsic.c +++ b/gcc/fortran/trans-intrinsic.c @@ -4562,13 +4562,22 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op) tree pos; int n; + actual = expr->value.function.actual; + + /* The last argument, BACK, is passed by value. Ensure that + by setting its name to %VAL. */ + for (gfc_actual_arglist *a = actual; a; a = a->next) + { + if (a->next == NULL) + a->name = "%VAL"; + } + if (se->ss) { gfc_conv_intrinsic_funcall (se, expr); return; } - actual = expr->value.function.actual; arrayexpr = actual->expr; /* Special case for character maxloc. Remove unneeded actual @@ -4576,22 +4585,19 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op) if (arrayexpr->ts.type == BT_CHARACTER) { - gfc_actual_arglist *a2, *a3, *a4; - a2 = actual->next; - a3 = a2->next; - a4 = a3->next; - a4->next = NULL; - if (a3->expr == NULL) - { - actual->next = NULL; - gfc_free_actual_arglist (a2); - } - else + gfc_actual_arglist *a, *b; + a = actual; + while (a->next) { - actual->next = a3; /* dim */ - a3->next = NULL; - a2->next = a4; - gfc_free_actual_arglist (a4); + b = a->next; + if (b->expr == NULL || strcmp (b->name, "dim") == 0) + { + a->next = b->next; + b->next = NULL; + gfc_free_actual_arglist (b); + } + else + a = b; } gfc_conv_intrinsic_funcall (se, expr); return; @@ -8647,6 +8653,14 @@ gfc_conv_intrinsic_function (gfc_se * se, gfc_expr * expr) conv_generic_with_optional_char_arg (se, expr, 1, 3); break; + case GFC_ISYM_MINLOC: + gfc_conv_intrinsic_minmaxloc (se, expr, LT_EXPR); + break; + + case GFC_ISYM_MAXLOC: + gfc_conv_intrinsic_minmaxloc (se, expr, GT_EXPR); + break; + default: gfc_conv_intrinsic_funcall (se, expr); break; |