Fix regression with -Wexternal-argument-mismatch.
The attached patch fixes an ICE regresseion where undo state was not handled properly when generating formal from actual arguments, which occurred under certain conditions with the newly introduced -Wexternal-argument-mismatch option. The fix is simple: When we are generating these symbols, we no longer need to undo anything, so we can just remove them. I had considered adding an extra optional argument, but decided against it on code clarity grounds. While looking at the code, I also saw that a member of gfc_symbol introduced with my patch should be a bitfield of width 1. gcc/fortran/ChangeLog: PR fortran/119157 * gfortran.h (gfc_symbol): Make ext_dummy_arglist_mismatch a one-bit bitfield (gfc_pop_undo_symbol): Declare prototype. * symbol.cc (gfc_pop_undo_symbol): New function. * interface.cc (gfc_get_formal_from_actual_arglist): Call it for artificially introduced formal variables. gcc/testsuite/ChangeLog: PR fortran/119157 * gfortran.dg/interface_57.f90: New test.
This commit is contained in:
parent
613f8ddbe3
commit
90d9cdfa82
4 changed files with 23 additions and 1 deletions
|
@ -2026,7 +2026,7 @@ typedef struct gfc_symbol
|
|||
/* Set if an external dummy argument is called with different argument lists.
|
||||
This is legal in Fortran, but can cause problems with autogenerated
|
||||
C prototypes for C23. */
|
||||
unsigned ext_dummy_arglist_mismatch;
|
||||
unsigned ext_dummy_arglist_mismatch:1;
|
||||
|
||||
/* Reference counter, used for memory management.
|
||||
|
||||
|
@ -3736,6 +3736,7 @@ void gfc_traverse_user_op (gfc_namespace *, void (*)(gfc_user_op *));
|
|||
void gfc_save_all (gfc_namespace *);
|
||||
|
||||
void gfc_enforce_clean_symbol_state (void);
|
||||
void gfc_pop_undo_symbol (void);
|
||||
|
||||
gfc_gsymbol *gfc_get_gsymbol (const char *, bool bind_c);
|
||||
gfc_gsymbol *gfc_find_gsymbol (gfc_gsymbol *, const char *);
|
||||
|
|
|
@ -5836,6 +5836,8 @@ gfc_get_formal_from_actual_arglist (gfc_symbol *sym,
|
|||
{
|
||||
snprintf (name, GFC_MAX_SYMBOL_LEN, "_formal_%d", var_num ++);
|
||||
gfc_get_symbol (name, gfc_current_ns, &s);
|
||||
/* We do not need this in an undo table. */
|
||||
gfc_pop_undo_symbol();
|
||||
if (a->expr->ts.type == BT_PROCEDURE)
|
||||
{
|
||||
gfc_symbol *asym = a->expr->symtree->n.sym;
|
||||
|
|
|
@ -3898,6 +3898,11 @@ enforce_single_undo_checkpoint (void)
|
|||
gcc_checking_assert (single_undo_checkpoint_p ());
|
||||
}
|
||||
|
||||
void
|
||||
gfc_pop_undo_symbol ()
|
||||
{
|
||||
latest_undo_chgset->syms.pop();
|
||||
}
|
||||
|
||||
/* Undoes all the changes made to symbols in the current statement. */
|
||||
|
||||
|
|
14
gcc/testsuite/gfortran.dg/interface_57.f90
Normal file
14
gcc/testsuite/gfortran.dg/interface_57.f90
Normal file
|
@ -0,0 +1,14 @@
|
|||
! { dg-do compile }
|
||||
! { dg-options "-Wexternal-argument-mismatch" }
|
||||
! PR 119157 - this used to ICE because undo state was not
|
||||
! correctly handled.
|
||||
|
||||
MODULE lmdif_module
|
||||
implicit none
|
||||
CONTAINS
|
||||
SUBROUTINE lmdif (fcn, m)
|
||||
EXTERNAL fcn
|
||||
integer m
|
||||
call fcn (m)
|
||||
END SUBROUTINE lmdif
|
||||
END MODULE
|
Loading…
Add table
Reference in a new issue