aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas König <tkoenig@gcc.gnu.org>2020-04-17 19:53:45 +0200
committerThomas König <tkoenig@gcc.gnu.org>2020-04-17 19:53:45 +0200
commit2298af0800b292f028298c1eaec42fd3033c4b9b (patch)
tree95882dce57ad39ffb743d2e56ce95d694cae9cec /gcc
parentaf557050fd011a03d21dc26b31959033061a0443 (diff)
downloadgcc-2298af0800b292f028298c1eaec42fd3033c4b9b.zip
gcc-2298af0800b292f028298c1eaec42fd3033c4b9b.tar.gz
gcc-2298af0800b292f028298c1eaec42fd3033c4b9b.tar.bz2
Fix ICE on invalid, PR94090.
The attached patch fixes an ICE on invalid: When the return type of a function was misdeclared with a wrong rank, we issued a warning, but not an error (unless with -pedantic); later on, an ICE ensued. Nothing good can come from wrongly declaring a function type (considering the ABI), so I changed that into a hard error. 2020-04-17 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/94090 * gfortran.dg (gfc_compare_interfaces): Add optional argument bad_result_characteristics. * interface.c (gfc_check_result_characteristics): Fix whitespace. (gfc_compare_interfaces): Handle new argument; return true if function return values are wrong. * resolve.c (resolve_global_procedure): Hard error if the return value of a function is wrong. 2020-04-17 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/94090 * gfortran.dg/interface_46.f90: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/ChangeLog12
-rw-r--r--gcc/fortran/gfortran.h3
-rw-r--r--gcc/fortran/interface.c14
-rw-r--r--gcc/fortran/resolve.c22
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gfortran.dg/interface_46.f9036
6 files changed, 80 insertions, 12 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 515b912..2f99ce2 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,15 @@
+2020-04-17 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/94090
+ * gfortran.dg (gfc_compare_interfaces): Add
+ optional argument bad_result_characteristics.
+ * interface.c (gfc_check_result_characteristics): Fix
+ whitespace.
+ (gfc_compare_interfaces): Handle new argument; return
+ true if function return values are wrong.
+ * resolve.c (resolve_global_procedure): Hard error if
+ the return value of a function is wrong.
+
2020-04-15 Fritz Reese <foreese@gcc.gnu.org>
Linus Koenig <link@sig-st.de>
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 0d77386..4e1da8c 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3445,7 +3445,8 @@ bool gfc_check_dummy_characteristics (gfc_symbol *, gfc_symbol *,
bool gfc_check_result_characteristics (gfc_symbol *, gfc_symbol *,
char *, int);
bool gfc_compare_interfaces (gfc_symbol*, gfc_symbol*, const char *, int, int,
- char *, int, const char *, const char *);
+ char *, int, const char *, const char *,
+ bool *bad_result_characteristics = NULL);
void gfc_check_interfaces (gfc_namespace *);
bool gfc_procedure_use (gfc_symbol *, gfc_actual_arglist **, locus *);
void gfc_ppc_use (gfc_component *, gfc_actual_arglist **, locus *);
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 8f041f0..ba1c8bc 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -1529,7 +1529,7 @@ gfc_check_dummy_characteristics (gfc_symbol *s1, gfc_symbol *s2,
bool
gfc_check_result_characteristics (gfc_symbol *s1, gfc_symbol *s2,
- char *errmsg, int err_len)
+ char *errmsg, int err_len)
{
gfc_symbol *r1, *r2;
@@ -1695,12 +1695,16 @@ bool
gfc_compare_interfaces (gfc_symbol *s1, gfc_symbol *s2, const char *name2,
int generic_flag, int strict_flag,
char *errmsg, int err_len,
- const char *p1, const char *p2)
+ const char *p1, const char *p2,
+ bool *bad_result_characteristics)
{
gfc_formal_arglist *f1, *f2;
gcc_assert (name2 != NULL);
+ if (bad_result_characteristics)
+ *bad_result_characteristics = false;
+
if (s1->attr.function && (s2->attr.subroutine
|| (!s2->attr.function && s2->ts.type == BT_UNKNOWN
&& gfc_get_default_type (name2, s2->ns)->type == BT_UNKNOWN)))
@@ -1726,7 +1730,11 @@ gfc_compare_interfaces (gfc_symbol *s1, gfc_symbol *s2, const char *name2,
/* If both are functions, check result characteristics. */
if (!gfc_check_result_characteristics (s1, s2, errmsg, err_len)
|| !gfc_check_result_characteristics (s2, s1, errmsg, err_len))
- return false;
+ {
+ if (bad_result_characteristics)
+ *bad_result_characteristics = true;
+ return false;
+ }
}
if (s1->attr.pure && !s2->attr.pure)
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 9b95200..2371ab2 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -2601,21 +2601,27 @@ resolve_global_procedure (gfc_symbol *sym, locus *where, int sub)
goto done;
}
- if (!pedantic && (gfc_option.allow_std & GFC_STD_GNU))
- /* Turn erros into warnings with -std=gnu and -std=legacy. */
- gfc_errors_to_warnings (true);
-
+ bool bad_result_characteristics;
if (!gfc_compare_interfaces (sym, def_sym, sym->name, 0, 1,
- reason, sizeof(reason), NULL, NULL))
+ reason, sizeof(reason), NULL, NULL,
+ &bad_result_characteristics))
{
- gfc_error_opt (0, "Interface mismatch in global procedure %qs at %L:"
- " %s", sym->name, &sym->declared_at, reason);
+ /* Turn erros into warnings with -std=gnu and -std=legacy,
+ unless a function returns a wrong type, which can lead
+ to all kinds of ICEs and wrong code. */
+
+ if (!pedantic && (gfc_option.allow_std & GFC_STD_GNU)
+ && !bad_result_characteristics)
+ gfc_errors_to_warnings (true);
+
+ gfc_error ("Interface mismatch in global procedure %qs at %L: %s",
+ sym->name, &sym->declared_at, reason);
+ gfc_errors_to_warnings (false);
goto done;
}
}
done:
- gfc_errors_to_warnings (false);
if (gsym->type == GSYM_UNKNOWN)
{
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 6c96253..15f5cb2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2020-04-17 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/94090
+ * gfortran.dg/interface_46.f90: New test.
+
2020-04-17 Richard Sandiford <richard.sandiford@arm.com>
* gcc.target/aarch64/sve/cost_model_2.c: New test.
diff --git a/gcc/testsuite/gfortran.dg/interface_46.f90 b/gcc/testsuite/gfortran.dg/interface_46.f90
new file mode 100644
index 0000000..c1d8763
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/interface_46.f90
@@ -0,0 +1,36 @@
+! { dg-do compile }
+! PR 94090 - this used to cause an ICE.
+! Test case by José Rui Faustino de Sousa.
+function cntf(a) result(s)
+ implicit none
+
+ integer, intent(in) :: a(:)
+
+ integer :: s(3)
+
+ s = [1, 2, 3]
+ return
+end function cntf
+
+program ice_p
+
+ implicit none
+
+ interface
+ function cntf(a) result(s) ! { dg-error "Rank mismatch in function result" }
+ implicit none
+ integer, intent(in) :: a(:)
+ integer :: s ! (3) <- Ups!
+ end function cntf
+ end interface
+
+ integer, parameter :: n = 9
+
+ integer :: arr(n)
+
+ integer :: s(3)
+
+ s = cntf(arr)
+ stop
+
+end program ice_p