PING! ---
Dear Fortranners, Gerhard found a case where the mismatch of actual and formal argument lead to an ICE instead of the relevant warning. Furthermore, the special case of character argument avoided the check that the actual argument must be definable if the formal one is INTENT-OUT or -INOUT. The check was already there, it just did not get triggered here. The patch is close to obvious, trivial and self-explaining. I chose to continue doing the argument checking after emitting the warning. Regtested on x86_64-pc-linux-gnu. OK for mainline? OK for backports to the affected branches? Thanks, Harald PR fortran/100274 - ICE in gfc_conv_procedure_call, at fortran/trans-expr.c:6131 When the check for the length of formal and actual character arguments found a mismatch and emitted a warning, it would skip further checks like that could lead to errors. Fix that by continuing the checking. Also catch a NULL pointer dereference. gcc/fortran/ChangeLog: PR fortran/100274 * interface.c (gfc_compare_actual_formal): Continue checks after emitting warning for argument length mismatch. * trans-expr.c (gfc_conv_procedure_call): Check for NULL pointer dereference. gcc/testsuite/ChangeLog: PR fortran/100274 * gfortran.dg/argument_checking_25.f90: New test.
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index 60736123550..9e3e8aa9da9 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -3255,10 +3255,13 @@ 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 (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); + { + 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); + goto skip_size_check; + } else if (where) { /* Emit a warning for -std=legacy and an error otherwise. */ diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 213f32b0a67..a10170c7dff 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -6128,6 +6128,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym, bool add_clobber; add_clobber = fsym && fsym->attr.intent == INTENT_OUT && !fsym->attr.allocatable && !fsym->attr.pointer + && e->symtree && e->symtree->n.sym && !e->symtree->n.sym->attr.dimension && !e->symtree->n.sym->attr.pointer && !e->symtree->n.sym->attr.allocatable diff --git a/gcc/testsuite/gfortran.dg/argument_checking_25.f90 b/gcc/testsuite/gfortran.dg/argument_checking_25.f90 new file mode 100644 index 00000000000..e699160fee1 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/argument_checking_25.f90 @@ -0,0 +1,12 @@ +! { dg-do compile } +! PR fortran/100274 - ICE in gfc_conv_procedure_call, at fortran/trans-expr.c:6131 + +program p + call s('y') ! { dg-warning "Character length of actual argument" } +contains + subroutine s(x) + character(8), intent(out) :: x + end +end + +! { dg-error "in variable definition context" " " { target *-*-* } 5 }