See attached....... --- Fritz Reese
On Tue, Nov 1, 2016 at 11:24 AM, Fritz Reese <fritzore...@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
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