[PATCH, Fortran] New warning flag -Wargument-mismatch to control argument mismatch warnings
Fritz Reese
fritzoreese@gmail.com
Tue Nov 1 19:38:00 GMT 2016
See attached.......
---
Fritz Reese
On Tue, Nov 1, 2016 at 11:24 AM, Fritz Reese <fritzoreese@gmail.com> wrote:
> All,
>
> Here I propose a new warning flag -Wargument-mismatch to control
> warnings emitted when the type, rank, or some other property of actual
> arguments does not match that of a function's formal parameters
> according to its declaration or interface specification. The warnings
> are of course enabled by default, as they should be. Note also with
> -Wno-argument-mismatch, only _warnings_ are suppressed. In such cases
> where an argument mismatch is an error, the error is still properly
> emitted.
>
> This simple patch depends on the recently-submitted patch [1] "Allow
> warnings given through gfc_error to associate with warning flags".
> Since the argument mismatch warnings are sometimes errors, they are
> currently emitted through gfc_error with `warnings_not_errors` set.
> Without the solution in [1], awkward code changes may be required to
> work around this fact.
>
> The new flag is supplied for the benefit of those users which believe
> that suppression of any given warning generated by a compiler should
> be possible. Such users may be frustrated with the current GNU Fortran
> front-end, in which there is no way to suppress this class of
> warnings, even if the user "knows what he is doing" and refuses to
> change his/her code.
>
> [1] https://gcc.gnu.org/ml/fortran/2016-11/msg00003.html
>
> Bootstraps and regtests on x86_64-redhat-linux.
>
> if (gfc_accepted ([1]))
> {
> gfc_ask_ok_for_trunk ($0);
> }
>
> ---
> Fritz Reese
-------------- next part --------------
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index b851d5a..4dd432e 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -2139,17 +2139,17 @@ argument_rank_mismatch (const char *name, locus *where,
}
else if (rank1 == 0)
{
- gfc_error ("Rank mismatch in argument %qs at %L "
+ gfc_error (OPT_Wargument_mismatch, "Rank mismatch in argument %qs at %L "
"(scalar and rank-%d)", name, where, rank2);
}
else if (rank2 == 0)
{
- gfc_error ("Rank mismatch in argument %qs at %L "
+ gfc_error (OPT_Wargument_mismatch, "Rank mismatch in argument %qs at %L "
"(rank-%d and scalar)", name, where, rank1);
}
else
{
- gfc_error ("Rank mismatch in argument %qs at %L "
+ gfc_error (OPT_Wargument_mismatch, "Rank mismatch in argument %qs at %L "
"(rank-%d and rank-%d)", name, where, rank1, rank2);
}
}
@@ -2200,7 +2200,8 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
sizeof(err), NULL, NULL))
{
if (where)
- gfc_error ("Interface mismatch in dummy procedure %qs at %L: %s",
+ gfc_error (OPT_Wargument_mismatch,
+ "Interface mismatch in dummy procedure %qs at %L: %s",
formal->name, &actual->where, err);
return 0;
}
@@ -2227,7 +2228,8 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
err, sizeof(err), NULL, NULL))
{
if (where)
- gfc_error ("Interface mismatch in dummy procedure %qs at %L: %s",
+ gfc_error (OPT_Wargument_mismatch,
+ "Interface mismatch in dummy procedure %qs at %L: %s",
formal->name, &actual->where, err);
return 0;
}
@@ -2253,7 +2255,8 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
CLASS_DATA (actual)->ts.u.derived)))
{
if (where)
- gfc_error ("Type mismatch in argument %qs at %L; passed %s to %s",
+ gfc_error (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));
return 0;
@@ -2957,7 +2960,7 @@ 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 (0,
+ gfc_warning (OPT_Wargument_mismatch,
"Character length mismatch (%ld/%ld) between actual "
"argument and pointer or allocatable dummy argument "
"%qs at %L",
@@ -2965,7 +2968,7 @@ compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
mpz_get_si (f->sym->ts.u.cl->length->value.integer),
f->sym->name, &a->expr->where);
else if (where)
- gfc_warning (0,
+ gfc_warning (OPT_Wargument_mismatch,
"Character length mismatch (%ld/%ld) between actual "
"argument and assumed-shape dummy argument %qs "
"at %L",
@@ -2997,12 +3000,14 @@ 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 (0, "Character length of actual argument shorter "
+ gfc_warning (OPT_Wargument_mismatch,
+ "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);
else if (where)
- gfc_warning (0, "Actual argument contains too few "
+ gfc_warning (OPT_Wargument_mismatch,
+ "Actual argument contains too few "
"elements for dummy argument %qs (%lu/%lu) at %L",
f->sym->name, actual_size, formal_size,
&a->expr->where);
@@ -4547,7 +4552,8 @@ 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 ("Argument mismatch for the overriding procedure "
+ gfc_error (OPT_Wargument_mismatch,
+ "Argument mismatch for the overriding procedure "
"%qs at %L: %s", proc->name, &where, err);
return false;
}
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index ebf3aba..83fdf01 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -141,7 +141,7 @@ by type. Explanations are in the following sections.
@item Error and Warning Options
@xref{Error and Warning Options,,Options to request or suppress errors
and warnings}.
-@gccoptlist{-Waliasing -Wall -Wampersand -Warray-bounds
+@gccoptlist{-Waliasing -Wall -Wampersand -Wargument-mismatch -Warray-bounds
-Wc-binding-type -Wcharacter-truncation @gol
-Wconversion -Wfunction-elimination -Wimplicit-interface @gol
-Wimplicit-procedure -Wintrinsic-shadow -Wuse-without-only -Wintrinsics-std @gol
@@ -821,6 +821,15 @@ given in a continued character constant, GNU Fortran assumes continuation
at the first non-comment, non-whitespace character after the ampersand
that initiated the continuation.
+@item -Wargument-mismatch
+@opindex @code{Wargument-mismatch}
+@cindex warnings, argument mismatch
+@cindex warnings, parameter mismatch
+@cindex warnings, interface mismatch
+Warn about type, rank, and other mismatches between formal parameters and actual
+arguments to functions and subroutines. These warnings are recommended and
+thus enabled by default.
+
@item -Warray-temporaries
@opindex @code{Warray-temporaries}
@cindex warnings, array temporaries
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index 2e76403..e39e555 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -209,6 +209,10 @@ Warray-temporaries
Fortran Warning Var(warn_array_temporaries)
Warn about creation of array temporaries.
+Wargument-mismatch
+Fortran Warning Var(warn_argument_mismatch) Init(1)
+Warn about type and rank mismatches between arguments and parameters.
+
Wc-binding-type
Fortran Var(warn_c_binding_type) Warning LangEnabledBy(Fortran,Wall)
Warn if the type of a variable might be not interoperable with C.
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index f9d11be..14685d2 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -1317,7 +1317,8 @@ resolve_structure_cons (gfc_expr *expr, int init)
if (s2 && !gfc_compare_interfaces (comp->ts.interface, s2, name, 0, 1,
err, sizeof (err), NULL, NULL))
{
- gfc_error ("Interface mismatch for procedure-pointer component "
+ gfc_error (OPT_Wargument_mismatch,
+ "Interface mismatch for procedure-pointer component "
"%qs in structure constructor at %L: %s",
comp->name, &cons->expr->where, err);
return false;
@@ -2469,7 +2470,8 @@ resolve_global_procedure (gfc_symbol *sym, locus *where,
if (!gfc_compare_interfaces (sym, def_sym, sym->name, 0, 1,
reason, sizeof(reason), NULL, NULL))
{
- gfc_error ("Interface mismatch in global procedure %qs at %L: %s ",
+ gfc_error (OPT_Wargument_mismatch,
+ "Interface mismatch in global procedure %qs at %L: %s ",
sym->name, &sym->declared_at, reason);
goto done;
}
diff --git a/gcc/testsuite/gfortran.dg/warn_argument_mismatch_1.f90 b/gcc/testsuite/gfortran.dg/warn_argument_mismatch_1.f90
new file mode 100644
index 0000000..6a663e6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/warn_argument_mismatch_1.f90
@@ -0,0 +1,34 @@
+! { dg-do compile }
+! { dg-options "-Wno-argument-mismatch" }
+!
+! No warnings should be output here with -Wno-argument-mismatch.
+!
+
+subroutine s1(x)
+ implicit none
+ integer, intent(in) :: x
+ print *, x
+end subroutine
+
+subroutine s2(x)
+ implicit none
+ integer, intent(in) :: x(1)
+ print *, x
+end subroutine
+
+subroutine s3(x)
+ implicit none
+ integer, intent(in) :: x(2)
+ print *, x
+end subroutine
+
+implicit none
+integer :: x, y(1)
+real :: r
+
+call s1(r)
+call s1(y)
+call s2(x)
+call s3(y)
+
+end
More information about the Fortran
mailing list