aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/interface.c
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2019-09-14 20:40:55 +0000
committerThomas Koenig <tkoenig@gcc.gnu.org>2019-09-14 20:40:55 +0000
commite0b9e5f9e3c90a55e643ea850cf828e3e6480fb5 (patch)
treec4fc497adf886895316602a7aceb79dea87dd956 /gcc/fortran/interface.c
parentdf19f4717db02943c2ddee1e9f632581537f6c78 (diff)
downloadgcc-e0b9e5f9e3c90a55e643ea850cf828e3e6480fb5.zip
gcc-e0b9e5f9e3c90a55e643ea850cf828e3e6480fb5.tar.gz
gcc-e0b9e5f9e3c90a55e643ea850cf828e3e6480fb5.tar.bz2
re PR fortran/91557 (Bogus warning about unused dummy argument _formal_*)
2019-09-14 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/91557 PR fortran/91556 * frontend-passes.c (check_externals_procedure): Reformat argument list. Use gfc_compare_actual_formal instead of gfc_procedure_use. * gfortran.h (gfc_symbol): Add flag error. * interface.c (gfc_compare_interfaces): Reformat. (argument_rank_mismatch): Add where_formal argument. If it is present, note that the error is between different calls. (compare_parameter): Change warnings that previously dependended on -Wargument-mismatch to unconditional. Issue an error / warning on type mismatch only once. Pass where_formal to argument_rank_mismatch for artificial variables. (compare_actual_formal): Change warnings that previously dependeded on -Wargument-mismatch to unconditional. (gfc_check_typebound_override): Likewise. (gfc_get_formal_from_actual_arglist): Set declared_at for artificial symbol. * invoke.texi: Extend description of -fallow-argument-mismatch. Delete -Wargument-mismatch. * lang.opt: Change -Wargument-mismatch to do-nothing option. * resolve.c (resolve_structure_cons): Change warnings that previously depended on -Wargument-mismatch to unconditional. * trans-decl.c (generate_local_decl): Do not warn if the symbol is artificial. 2019-09-14 Thomas Koenig <tkoenig@gcc.gnu.org> PR fortran/91557 PR fortran/91556 * gfortran.dg/argument_checking_20.f90: New test. * gfortran.dg/argument_checking_21.f90: New test. * gfortran.dg/argument_checking_22.f90: New test. * gfortran.dg/argument_checking_23.f90: New test. * gfortran.dg/warn_unused_dummy_argument_5.f90: New test. * gfortran.dg/bessel_3.f90: Add pattern for type mismatch. * gfortran.dg/g77/20010519-1.f: Adjust dg-warning messages to new handling. * gfortran.dg/pr24823.f: Likewise. * gfortran.dg/pr39937.f: Likewise. From-SVN: r275719
Diffstat (limited to 'gcc/fortran/interface.c')
-rw-r--r--gcc/fortran/interface.c120
1 files changed, 83 insertions, 37 deletions
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 43d7cd5..08e4f06 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -1807,9 +1807,9 @@ gfc_compare_interfaces (gfc_symbol *s1, gfc_symbol *s2, const char *name2,
if (!compare_rank (f2->sym, f1->sym))
{
if (errmsg != NULL)
- snprintf (errmsg, err_len, "Rank mismatch in argument '%s' "
- "(%i/%i)", f1->sym->name, symbol_rank (f1->sym),
- symbol_rank (f2->sym));
+ snprintf (errmsg, err_len, "Rank mismatch in argument "
+ "'%s' (%i/%i)", f1->sym->name,
+ symbol_rank (f1->sym), symbol_rank (f2->sym));
return false;
}
if ((gfc_option.allow_std & GFC_STD_F2008)
@@ -2189,22 +2189,42 @@ compare_pointer (gfc_symbol *formal, gfc_expr *actual)
static void
argument_rank_mismatch (const char *name, locus *where,
- int rank1, int rank2)
+ int rank1, int rank2, locus *where_formal)
{
/* TS 29113, C407b. */
- if (rank2 == -1)
- gfc_error ("The assumed-rank array at %L requires that the dummy argument"
- " %qs has assumed-rank", where, name);
- else if (rank1 == 0)
- gfc_error_opt (OPT_Wargument_mismatch, "Rank mismatch in argument %qs "
- "at %L (scalar and rank-%d)", name, where, rank2);
- else if (rank2 == 0)
- gfc_error_opt (OPT_Wargument_mismatch, "Rank mismatch in argument %qs "
- "at %L (rank-%d and scalar)", name, where, rank1);
+ if (where_formal == NULL)
+ {
+ if (rank2 == -1)
+ gfc_error ("The assumed-rank array at %L requires that the dummy "
+ "argument %qs has assumed-rank", where, name);
+ else if (rank1 == 0)
+ gfc_error_opt (0, "Rank mismatch in argument %qs "
+ "at %L (scalar and rank-%d)", name, where, rank2);
+ else if (rank2 == 0)
+ gfc_error_opt (0, "Rank mismatch in argument %qs "
+ "at %L (rank-%d and scalar)", name, where, rank1);
+ else
+ gfc_error_opt (0, "Rank mismatch in argument %qs "
+ "at %L (rank-%d and rank-%d)", name, where, rank1,
+ rank2);
+ }
else
- gfc_error_opt (OPT_Wargument_mismatch, "Rank mismatch in argument %qs "
- "at %L (rank-%d and rank-%d)", name, where, rank1, rank2);
+ {
+ gcc_assert (rank2 != -1);
+ if (rank1 == 0)
+ gfc_error_opt (0, "Rank mismatch between actual argument at %L "
+ "and actual argument at %L (scalar and rank-%d)",
+ where, where_formal, rank2);
+ else if (rank2 == 0)
+ gfc_error_opt (0, "Rank mismatch between actual argument at %L "
+ "and actual argument at %L (rank-%d and scalar)",
+ where, where_formal, rank1);
+ else
+ gfc_error_opt (0, "Rank mismatch between actual argument at %L "
+ "and actual argument at %L (rank-%d and rank-%d", where,
+ where_formal, rank1, rank2);
+ }
}
@@ -2253,8 +2273,7 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
sizeof(err), NULL, NULL))
{
if (where)
- gfc_error_opt (OPT_Wargument_mismatch,
- "Interface mismatch in dummy procedure %qs at %L:"
+ gfc_error_opt (0, "Interface mismatch in dummy procedure %qs at %L:"
" %s", formal->name, &actual->where, err);
return false;
}
@@ -2281,8 +2300,7 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
err, sizeof(err), NULL, NULL))
{
if (where)
- gfc_error_opt (OPT_Wargument_mismatch,
- "Interface mismatch in dummy procedure %qs at %L:"
+ gfc_error_opt (0, "Interface mismatch in dummy procedure %qs at %L:"
" %s", formal->name, &actual->where, err);
return false;
}
@@ -2312,10 +2330,24 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
CLASS_DATA (actual)->ts.u.derived)))
{
if (where)
- gfc_error_opt (OPT_Wargument_mismatch,
- "Type mismatch in argument %qs at %L; passed %s to %s",
- formal->name, where, gfc_typename (&actual->ts),
- gfc_typename (&formal->ts));
+ {
+ if (formal->attr.artificial)
+ {
+ if (!flag_allow_argument_mismatch || !formal->error)
+ gfc_error_opt (0, "Type mismatch between actual argument at %L "
+ "and actual argument at %L (%s/%s).",
+ &actual->where,
+ &formal->declared_at,
+ gfc_typename (&actual->ts),
+ gfc_typename (&formal->ts));
+
+ formal->error = 1;
+ }
+ else
+ gfc_error_opt (0, "Type mismatch in argument %qs at %L; passed %s "
+ "to %s", formal->name, where, gfc_typename (&actual->ts),
+ gfc_typename (&formal->ts));
+ }
return false;
}
@@ -2512,8 +2544,17 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
&& gfc_is_coindexed (actual)))
{
if (where)
- argument_rank_mismatch (formal->name, &actual->where,
- symbol_rank (formal), actual->rank);
+ {
+ locus *where_formal;
+ if (formal->attr.artificial)
+ where_formal = &formal->declared_at;
+ else
+ where_formal = NULL;
+
+ argument_rank_mismatch (formal->name, &actual->where,
+ symbol_rank (formal), actual->rank,
+ where_formal);
+ }
return false;
}
else if (actual->rank != 0 && (is_elemental || formal->attr.dimension))
@@ -2584,8 +2625,17 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
if (ref == NULL && actual->expr_type != EXPR_NULL)
{
if (where)
- argument_rank_mismatch (formal->name, &actual->where,
- symbol_rank (formal), actual->rank);
+ {
+ locus *where_formal;
+ if (formal->attr.artificial)
+ where_formal = &formal->declared_at;
+ else
+ where_formal = NULL;
+
+ argument_rank_mismatch (formal->name, &actual->where,
+ symbol_rank (formal), actual->rank,
+ where_formal);
+ }
return false;
}
@@ -3062,16 +3112,14 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
f->sym->ts.u.cl->length->value.integer) != 0))
{
if (where && (f->sym->attr.pointer || f->sym->attr.allocatable))
- gfc_warning (OPT_Wargument_mismatch,
- "Character length mismatch (%ld/%ld) between actual "
+ gfc_warning (0, "Character length mismatch (%ld/%ld) between actual "
"argument and pointer or allocatable dummy argument "
"%qs at %L",
mpz_get_si (a->expr->ts.u.cl->length->value.integer),
mpz_get_si (f->sym->ts.u.cl->length->value.integer),
f->sym->name, &a->expr->where);
else if (where)
- gfc_warning (OPT_Wargument_mismatch,
- "Character length mismatch (%ld/%ld) between actual "
+ gfc_warning (0, "Character length mismatch (%ld/%ld) between actual "
"argument and assumed-shape dummy argument %qs "
"at %L",
mpz_get_si (a->expr->ts.u.cl->length->value.integer),
@@ -3102,8 +3150,7 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
&& f->sym->attr.flavor != FL_PROCEDURE)
{
if (a->expr->ts.type == BT_CHARACTER && !f->sym->as && where)
- gfc_warning (OPT_Wargument_mismatch,
- "Character length of actual argument shorter "
+ gfc_warning (0, "Character length of actual argument shorter "
"than of dummy argument %qs (%lu/%lu) at %L",
f->sym->name, actual_size, formal_size,
&a->expr->where);
@@ -3111,8 +3158,7 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
{
/* Emit a warning for -std=legacy and an error otherwise. */
if (gfc_option.warn_std == 0)
- gfc_warning (OPT_Wargument_mismatch,
- "Actual argument contains too few "
+ gfc_warning (0, "Actual argument contains too few "
"elements for dummy argument %qs (%lu/%lu) "
"at %L", f->sym->name, actual_size,
formal_size, &a->expr->where);
@@ -4706,8 +4752,7 @@ gfc_check_typebound_override (gfc_symtree* proc, gfc_symtree* old)
if (!gfc_check_dummy_characteristics (proc_formal->sym, old_formal->sym,
check_type, err, sizeof(err)))
{
- gfc_error_opt (OPT_Wargument_mismatch,
- "Argument mismatch for the overriding procedure "
+ gfc_error_opt (0, "Argument mismatch for the overriding procedure "
"%qs at %L: %s", proc->name, &where, err);
return false;
}
@@ -5184,6 +5229,7 @@ gfc_get_formal_from_actual_arglist (gfc_symbol *sym,
}
}
s->attr.dummy = 1;
+ s->declared_at = a->expr->where;
s->attr.intent = INTENT_UNKNOWN;
(*f)->sym = s;
}