https://gcc.gnu.org/g:90d9cdfa82d9a8d63e35d928e335719a495c79e3

commit r15-7909-g90d9cdfa82d9a8d63e35d928e335719a495c79e3
Author: Thomas Koenig <tkoe...@gcc.gnu.org>
Date:   Sat Mar 8 16:13:41 2025 +0100

    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.

Diff:
---
 gcc/fortran/gfortran.h                     |  3 ++-
 gcc/fortran/interface.cc                   |  2 ++
 gcc/fortran/symbol.cc                      |  5 +++++
 gcc/testsuite/gfortran.dg/interface_57.f90 | 14 ++++++++++++++
 4 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 927f22cffd17..f81be1d984c5 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 edec907d33a3..e3bc22f25e58 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 81aa81df2eec..92cba4187842 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 000000000000..8c99864c0fbd
--- /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

Reply via email to