diff options
author | Thomas Koenig <tkoenig@gcc.gnu.org> | 2025-03-08 16:13:41 +0100 |
---|---|---|
committer | Thomas Koenig <tkoenig@gcc.gnu.org> | 2025-03-08 22:47:18 +0100 |
commit | 90d9cdfa82d9a8d63e35d928e335719a495c79e3 (patch) | |
tree | d745bffa75e7300b3bc058577b5f31ac71532f91 | |
parent | 613f8ddbe3d7da63d827e588bf0333813c184b8a (diff) | |
download | gcc-90d9cdfa82d9a8d63e35d928e335719a495c79e3.zip gcc-90d9cdfa82d9a8d63e35d928e335719a495c79e3.tar.gz gcc-90d9cdfa82d9a8d63e35d928e335719a495c79e3.tar.bz2 |
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.
-rw-r--r-- | gcc/fortran/gfortran.h | 3 | ||||
-rw-r--r-- | gcc/fortran/interface.cc | 2 | ||||
-rw-r--r-- | gcc/fortran/symbol.cc | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/interface_57.f90 | 14 |
4 files changed, 23 insertions, 1 deletions
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 927f22c..f81be1d 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -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 *); diff --git a/gcc/fortran/interface.cc b/gcc/fortran/interface.cc index edec907..e3bc22f 100644 --- a/gcc/fortran/interface.cc +++ b/gcc/fortran/interface.cc @@ -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; diff --git a/gcc/fortran/symbol.cc b/gcc/fortran/symbol.cc index 81aa81d..92cba41 100644 --- a/gcc/fortran/symbol.cc +++ b/gcc/fortran/symbol.cc @@ -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. */ diff --git a/gcc/testsuite/gfortran.dg/interface_57.f90 b/gcc/testsuite/gfortran.dg/interface_57.f90 new file mode 100644 index 0000000..8c99864 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/interface_57.f90 @@ -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 |