diff options
author | Sandra Loosemore <sandra@codesourcery.com> | 2021-11-04 15:43:29 -0700 |
---|---|---|
committer | Sandra Loosemore <sandra@codesourcery.com> | 2021-11-07 09:35:04 -0800 |
commit | ee11be7f2d788e6055ebed9746a8d8ac3cb04b8e (patch) | |
tree | a96c18c77e62872d69d6c8ba6d96f7278ce9a88c /gcc/fortran/interface.c | |
parent | f6f704fd104b79fc88914978772737cd05423059 (diff) | |
download | gcc-ee11be7f2d788e6055ebed9746a8d8ac3cb04b8e.zip gcc-ee11be7f2d788e6055ebed9746a8d8ac3cb04b8e.tar.gz gcc-ee11be7f2d788e6055ebed9746a8d8ac3cb04b8e.tar.bz2 |
Fortran: Diagnose all operands/arguments with constraint violations
04-Nov-2021 Sandra Loosemore <sandra@codesourcery.com>
Bernhard Reutner-Fischer <aldot@gcc.gnu.org>
PR fortran/101337
gcc/fortran/ChangeLog:
* interface.c (gfc_compare_actual_formal): Continue checking
all arguments after encountering an error.
* intrinsic.c (do_ts29113_check): Likewise.
* resolve.c (resolve_operator): Continue resolving on op2 error.
gcc/testsuite/ChangeLog:
* gfortran.dg/bessel_3.f90: Expect additional diagnostics from
multiple bad arguments in the call.
* gfortran.dg/pr24823.f: Likewise.
* gfortran.dg/pr39937.f: Likewise.
* gfortran.dg/pr41011.f: Likewise.
* gfortran.dg/pr61318.f90: Likewise.
* gfortran.dg/c-interop/c407b-2.f90: Remove xfails.
* gfortran.dg/c-interop/c535b-2.f90: Likewise.
Diffstat (limited to 'gcc/fortran/interface.c')
-rw-r--r-- | gcc/fortran/interface.c | 86 |
1 files changed, 60 insertions, 26 deletions
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c index 24698be..30c99ef 100644 --- a/gcc/fortran/interface.c +++ b/gcc/fortran/interface.c @@ -3064,6 +3064,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, gfc_array_spec *fas, *aas; bool pointer_dummy, pointer_arg, allocatable_arg; + bool ok = true; + actual = *ap; if (actual == NULL && formal == NULL) @@ -3134,7 +3136,6 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, if (where) gfc_error ("More actual than formal arguments in procedure " "call at %L", where); - return false; } @@ -3192,13 +3193,16 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, else if (where) gfc_error ("Fortran 2008: Null pointer at %L to non-pointer " "dummy %qs", where, f->sym->name); - - return false; + ok = false; + goto match; } if (!compare_parameter (f->sym, a->expr, ranks_must_agree, is_elemental, where)) - return false; + { + ok = false; + goto match; + } /* TS 29113, 6.3p2; F2018 15.5.2.4. */ if (f->sym->ts.type == BT_ASSUMED @@ -3217,7 +3221,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, "has type parameters or is of " "derived type with type-bound or FINAL procedures", &a->expr->where); - return false; + ok = false; + goto match; } } @@ -3249,7 +3254,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, 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); - return false; + ok = false; + goto match; } if ((f->sym->attr.pointer || f->sym->attr.allocatable) @@ -3261,7 +3267,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, "pointer dummy argument %qs must have a deferred " "length type parameter if and only if the dummy has one", &a->expr->where, f->sym->name); - return false; + ok = false; + goto match; } if (f->sym->ts.type == BT_CLASS) @@ -3295,7 +3302,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, "at %L", f->sym->name, actual_size, formal_size, &a->expr->where); } - return false; + ok = false; + goto match; } skip_size_check: @@ -3312,7 +3320,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, if (where) gfc_error ("Expected a procedure pointer for argument %qs at %L", f->sym->name, &a->expr->where); - return false; + ok = false; + goto match; } /* Satisfy F03:12.4.1.3 by ensuring that a procedure actual argument is @@ -3328,7 +3337,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, if (where) gfc_error ("Expected a procedure for argument %qs at %L", f->sym->name, &a->expr->where); - return false; + ok = false; + goto match; } /* Class array variables and expressions store array info in a @@ -3392,7 +3402,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, if (where) gfc_error ("Actual argument for %qs cannot be an assumed-size" " array at %L", f->sym->name, where); - return false; + ok = false; + goto match; } /* Diagnose F2018 C839 (TS29113 C535c). Here the problem is @@ -3421,7 +3432,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, gfc_error ("Actual argument to assumed-rank INTENT(OUT) " "dummy %qs at %L cannot be of unknown size", f->sym->name, where); - return false; + ok = false; + goto match; } if (a->expr->expr_type != EXPR_NULL @@ -3430,7 +3442,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, if (where) gfc_error ("Actual argument for %qs must be a pointer at %L", f->sym->name, &a->expr->where); - return false; + ok = false; + goto match; } if (a->expr->expr_type != EXPR_NULL @@ -3440,7 +3453,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, if (where) gfc_error ("Fortran 2008: Non-pointer actual argument at %L to " "pointer dummy %qs", &a->expr->where,f->sym->name); - return false; + ok = false; + goto match; } @@ -3451,7 +3465,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, gfc_error ("Coindexed actual argument at %L to pointer " "dummy %qs", &a->expr->where, f->sym->name); - return false; + ok = false; + goto match; } /* Fortran 2008, 12.5.2.5 (no constraint). */ @@ -3464,7 +3479,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, gfc_error ("Coindexed actual argument at %L to allocatable " "dummy %qs requires INTENT(IN)", &a->expr->where, f->sym->name); - return false; + ok = false; + goto match; } /* Fortran 2008, C1237. */ @@ -3479,7 +3495,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, "%L requires that dummy %qs has neither " "ASYNCHRONOUS nor VOLATILE", &a->expr->where, f->sym->name); - return false; + ok = false; + goto match; } /* Fortran 2008, 12.5.2.4 (no constraint). */ @@ -3492,7 +3509,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, gfc_error ("Coindexed actual argument at %L with allocatable " "ultimate component to dummy %qs requires either VALUE " "or INTENT(IN)", &a->expr->where, f->sym->name); - return false; + ok = false; + goto match; } if (f->sym->ts.type == BT_CLASS @@ -3503,7 +3521,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, if (where) gfc_error ("Actual CLASS array argument for %qs must be a full " "array at %L", f->sym->name, &a->expr->where); - return false; + ok = false; + goto match; } @@ -3513,7 +3532,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, if (where) gfc_error ("Actual argument for %qs must be ALLOCATABLE at %L", f->sym->name, &a->expr->where); - return false; + ok = false; + goto match; } /* Check intent = OUT/INOUT for definable actual argument. */ @@ -3529,9 +3549,15 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, && CLASS_DATA (f->sym)->attr.class_pointer) || (f->sym->ts.type != BT_CLASS && f->sym->attr.pointer)) && !gfc_check_vardef_context (a->expr, true, false, false, context)) - return false; + { + ok = false; + goto match; + } if (!gfc_check_vardef_context (a->expr, false, false, false, context)) - return false; + { + ok = false; + goto match; + } } if ((f->sym->attr.intent == INTENT_OUT @@ -3546,7 +3572,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, "INTENT(INOUT), VOLATILE or ASYNCHRONOUS attribute " "of the dummy argument %qs", &a->expr->where, f->sym->name); - return false; + ok = false; + goto match; } /* C1232 (R1221) For an actual argument which is an array section or @@ -3564,7 +3591,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, "incompatible with the non-assumed-shape " "dummy argument %qs due to VOLATILE attribute", &a->expr->where,f->sym->name); - return false; + ok = false; + goto match; } /* Find the last array_ref. */ @@ -3581,7 +3609,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, "incompatible with the non-assumed-shape " "dummy argument %qs due to VOLATILE attribute", &a->expr->where, f->sym->name); - return false; + ok = false; + goto match; } /* C1233 (R1221) For an actual argument which is a pointer array, the @@ -3601,7 +3630,8 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, "an assumed-shape or pointer-array dummy " "argument %qs due to VOLATILE attribute", &a->expr->where,f->sym->name); - return false; + ok = false; + goto match; } match: @@ -3611,6 +3641,10 @@ gfc_compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal, new_arg[i++] = a; } + /* Give up now if we saw any bad argument. */ + if (!ok) + return false; + /* Make sure missing actual arguments are optional. */ i = 0; for (f = formal; f; f = f->next, i++) |