From d7cef070bf43bfb3f3d77bac42eadea06c4b0281 Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Thu, 1 Apr 2021 07:49:32 +0200 Subject: PR fortran/99840 - ICE in gfc_simplify_matmul, at fortran/simplify.c:4777 The simplification of the transposition of a constant array shall properly initialize and set the shape of the result. gcc/fortran/ChangeLog: PR fortran/99840 * simplify.c (gfc_simplify_transpose): Properly initialize resulting shape. gcc/testsuite/ChangeLog: PR fortran/99840 * gfortran.dg/transpose_5.f90: New test. --- gcc/fortran/simplify.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'gcc/fortran/simplify.c') diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 388aca7..c27b47a 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -8123,8 +8123,8 @@ gfc_simplify_transpose (gfc_expr *matrix) &matrix->where); result->rank = 2; result->shape = gfc_get_shape (result->rank); - mpz_set (result->shape[0], matrix->shape[1]); - mpz_set (result->shape[1], matrix->shape[0]); + mpz_init_set (result->shape[0], matrix->shape[1]); + mpz_init_set (result->shape[1], matrix->shape[0]); if (matrix->ts.type == BT_CHARACTER) result->ts.u.cl = matrix->ts.u.cl; -- cgit v1.1 From d881460deb1f0bdfc3e8fa2d391a03a9763cbff4 Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Thu, 19 Aug 2021 21:00:45 +0200 Subject: Fortran - simplify length of substring with constant bounds gcc/fortran/ChangeLog: PR fortran/100950 * simplify.c (substring_has_constant_len): New. (gfc_simplify_len): Handle case of substrings with constant bounds. gcc/testsuite/ChangeLog: PR fortran/100950 * gfortran.dg/pr100950.f90: New test. --- gcc/fortran/simplify.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) (limited to 'gcc/fortran/simplify.c') diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index c27b47a..492867e 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -4512,6 +4512,78 @@ gfc_simplify_leadz (gfc_expr *e) } +/* Check for constant length of a substring. */ + +static bool +substring_has_constant_len (gfc_expr *e) +{ + gfc_ref *ref; + HOST_WIDE_INT istart, iend, length; + bool equal_length = false; + + if (e->ts.type != BT_CHARACTER) + return false; + + for (ref = e->ref; ref; ref = ref->next) + if (ref->type != REF_COMPONENT && ref->type != REF_ARRAY) + break; + + if (!ref + || ref->type != REF_SUBSTRING + || !ref->u.ss.start + || ref->u.ss.start->expr_type != EXPR_CONSTANT + || !ref->u.ss.end + || ref->u.ss.end->expr_type != EXPR_CONSTANT + || !ref->u.ss.length) + return false; + + /* For non-deferred strings the given length shall be constant. */ + if (!e->ts.deferred + && (!ref->u.ss.length->length + || ref->u.ss.length->length->expr_type != EXPR_CONSTANT)) + return false; + + /* Basic checks on substring starting and ending indices. */ + if (!gfc_resolve_substring (ref, &equal_length)) + return false; + + istart = gfc_mpz_get_hwi (ref->u.ss.start->value.integer); + iend = gfc_mpz_get_hwi (ref->u.ss.end->value.integer); + + if (istart <= iend) + { + if (istart < 1) + { + gfc_error ("Substring start index (" HOST_WIDE_INT_PRINT_DEC + ") at %L below 1", + istart, &ref->u.ss.start->where); + return false; + } + + /* For deferred strings use end index as proxy for length. */ + if (e->ts.deferred) + length = iend; + else + length = gfc_mpz_get_hwi (ref->u.ss.length->length->value.integer); + if (iend > length) + { + gfc_error ("Substring end index (" HOST_WIDE_INT_PRINT_DEC + ") at %L exceeds string length", + iend, &ref->u.ss.end->where); + return false; + } + length = iend - istart + 1; + } + else + length = 0; + + /* Fix substring length. */ + e->value.character.length = length; + + return true; +} + + gfc_expr * gfc_simplify_len (gfc_expr *e, gfc_expr *kind) { @@ -4521,7 +4593,8 @@ gfc_simplify_len (gfc_expr *e, gfc_expr *kind) if (k == -1) return &gfc_bad_expr; - if (e->expr_type == EXPR_CONSTANT) + if (e->expr_type == EXPR_CONSTANT + || substring_has_constant_len (e)) { result = gfc_get_constant_expr (BT_INTEGER, k, &e->where); mpz_set_si (result->value.integer, e->value.character.length); -- cgit v1.1 From 12f22906d3c025e7edb60e3264dc9cd27a49e3e1 Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Fri, 20 Aug 2021 13:38:00 +0200 Subject: Fortran - use temporary char buffer for passing HOST_WIDE_INT to gfc_error gcc/fortran/ChangeLog: PR fortran/100950 * simplify.c (substring_has_constant_len): Fix format string of gfc_error, pass HOST_WIDE_INT bounds values via char buffer. --- gcc/fortran/simplify.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'gcc/fortran/simplify.c') diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 492867e..eaabbff 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -4552,11 +4552,12 @@ substring_has_constant_len (gfc_expr *e) if (istart <= iend) { + char buffer[21]; if (istart < 1) { - gfc_error ("Substring start index (" HOST_WIDE_INT_PRINT_DEC - ") at %L below 1", - istart, &ref->u.ss.start->where); + sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, istart); + gfc_error ("Substring start index (%s) at %L below 1", + buffer, &ref->u.ss.start->where); return false; } @@ -4567,9 +4568,9 @@ substring_has_constant_len (gfc_expr *e) length = gfc_mpz_get_hwi (ref->u.ss.length->length->value.integer); if (iend > length) { - gfc_error ("Substring end index (" HOST_WIDE_INT_PRINT_DEC - ") at %L exceeds string length", - iend, &ref->u.ss.end->where); + sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, iend); + gfc_error ("Substring end index (%s) at %L exceeds string length", + buffer, &ref->u.ss.end->where); return false; } length = iend - istart + 1; -- cgit v1.1 From 1b507b1e3c58c063b9cf803dff80c28d4626cb5d Mon Sep 17 00:00:00 2001 From: Tobias Burnus Date: Fri, 20 Aug 2021 15:43:32 +0200 Subject: c-format.c/Fortran: Support %wd / host-wide integer in gfc_error This patch adds support for the 'll' (long double) and 'w' (HOST_WIDE_INT) length modifiers to the Fortran FE diagnostic function (gfc_error, gfc_warning, ...) gcc/c-family/ChangeLog: * c-format.c (gcc_gfc_length_specs): Add 'll' and 'w'. (gcc_gfc_char_table): Add T9L_LL and T9L_ULL to "di" and "u", respecitively; fill with BADLEN to match size of 'types'. (get_init_dynamic_hwi): Split off from ... (init_dynamic_diag_info): ... here. Call it. (init_dynamic_gfc_info): Call it. gcc/fortran/ChangeLog: * error.c (error_uinteger): Take 'long long unsigned' instead of 'long unsigned' as argumpent. (error_integer): Take 'long long' instead of 'long'. (error_hwuint, error_hwint): New. (error_print): Update to handle 'll' and 'w' length modifiers. * simplify.c (substring_has_constant_len): Use '%wd' in gfc_error. --- gcc/fortran/simplify.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'gcc/fortran/simplify.c') diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index eaabbff..4cb73e8 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -4552,12 +4552,10 @@ substring_has_constant_len (gfc_expr *e) if (istart <= iend) { - char buffer[21]; if (istart < 1) { - sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, istart); - gfc_error ("Substring start index (%s) at %L below 1", - buffer, &ref->u.ss.start->where); + gfc_error ("Substring start index (%wd) at %L below 1", + istart, &ref->u.ss.start->where); return false; } @@ -4568,9 +4566,8 @@ substring_has_constant_len (gfc_expr *e) length = gfc_mpz_get_hwi (ref->u.ss.length->length->value.integer); if (iend > length) { - sprintf (buffer, HOST_WIDE_INT_PRINT_DEC, iend); - gfc_error ("Substring end index (%s) at %L exceeds string length", - buffer, &ref->u.ss.end->where); + gfc_error ("Substring end index (%wd) at %L exceeds string length", + iend, &ref->u.ss.end->where); return false; } length = iend - istart + 1; -- cgit v1.1 From e4cb3bb9ac11b4126ffa718287dd509a4b10a658 Mon Sep 17 00:00:00 2001 From: Harald Anlauf Date: Tue, 31 Aug 2021 21:00:53 +0200 Subject: Fortran - extend set of substring expressions handled in length simplification gcc/fortran/ChangeLog: PR fortran/100950 * simplify.c (substring_has_constant_len): Minimize checks for substring expressions being allowed. gcc/testsuite/ChangeLog: PR fortran/100950 * gfortran.dg/pr100950.f90: Extend coverage. --- gcc/fortran/simplify.c | 31 ++----------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) (limited to 'gcc/fortran/simplify.c') diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c index 4cb73e8..b46cbfa 100644 --- a/gcc/fortran/simplify.c +++ b/gcc/fortran/simplify.c @@ -4533,14 +4533,7 @@ substring_has_constant_len (gfc_expr *e) || !ref->u.ss.start || ref->u.ss.start->expr_type != EXPR_CONSTANT || !ref->u.ss.end - || ref->u.ss.end->expr_type != EXPR_CONSTANT - || !ref->u.ss.length) - return false; - - /* For non-deferred strings the given length shall be constant. */ - if (!e->ts.deferred - && (!ref->u.ss.length->length - || ref->u.ss.length->length->expr_type != EXPR_CONSTANT)) + || ref->u.ss.end->expr_type != EXPR_CONSTANT) return false; /* Basic checks on substring starting and ending indices. */ @@ -4551,27 +4544,7 @@ substring_has_constant_len (gfc_expr *e) iend = gfc_mpz_get_hwi (ref->u.ss.end->value.integer); if (istart <= iend) - { - if (istart < 1) - { - gfc_error ("Substring start index (%wd) at %L below 1", - istart, &ref->u.ss.start->where); - return false; - } - - /* For deferred strings use end index as proxy for length. */ - if (e->ts.deferred) - length = iend; - else - length = gfc_mpz_get_hwi (ref->u.ss.length->length->value.integer); - if (iend > length) - { - gfc_error ("Substring end index (%wd) at %L exceeds string length", - iend, &ref->u.ss.end->where); - return false; - } - length = iend - istart + 1; - } + length = iend - istart + 1; else length = 0; -- cgit v1.1