aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorThomas Koenig <tkoenig@gcc.gnu.org>2025-03-08 16:13:41 +0100
committerThomas Koenig <tkoenig@gcc.gnu.org>2025-03-08 22:47:18 +0100
commit90d9cdfa82d9a8d63e35d928e335719a495c79e3 (patch)
treed745bffa75e7300b3bc058577b5f31ac71532f91 /gcc
parent613f8ddbe3d7da63d827e588bf0333813c184b8a (diff)
downloadgcc-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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fortran/gfortran.h3
-rw-r--r--gcc/fortran/interface.cc2
-rw-r--r--gcc/fortran/symbol.cc5
-rw-r--r--gcc/testsuite/gfortran.dg/interface_57.f9014
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