https://gcc.gnu.org/g:eb5da48dd4f854f8607dfa95e20467529a15c606

commit r16-6420-geb5da48dd4f854f8607dfa95e20467529a15c606
Author: Jose E. Marchesi <[email protected]>
Date:   Sun Dec 28 01:35:35 2025 +0100

    a68: fix deduplication of imported modes
    
    The internal global list of modes maintained by the compiler should
    not contain two modes that are equivalent.  When importing module
    interfaces, the modes in these interfaces should get deduplicated
    before being "interned" in the compiler's modes list.  This commit
    fixes the deduplication to accommodate the fact that more than one
    module interface may be read from a given packet (compilation unit)
    and also that multiple interfaces may be imported indirectly via
    publicized modules.
    
    Signed-off-by: Jose E. Marchesi <[email protected]>
    
    gcc/algol68/ChangeLog
    
            * a68-imports.cc (a68_decode_modes): Do not deduplicate imported
            modes here.
            (a68_open_packet): Do it here.
            * a68-parser-extract.cc (extract_revelation): Recurse into
            publicized modules after interning modes in the current module,
            not before.
    
    gcc/testsuite/ChangeLog
    
            * algol68/execute/modules/module23bar.a68: New test.
            * algol68/execute/modules/module23foo.a68: Likewise.
            * algol68/execute/modules/program-23.a68: Likewise.

Diff:
---
 gcc/algol68/a68-imports.cc                         | 56 ++++++++++++++--------
 gcc/algol68/a68-parser-extract.cc                  | 21 +++++---
 .../algol68/execute/modules/module23bar.a68        |  7 +++
 .../algol68/execute/modules/module23foo.a68        |  5 ++
 .../algol68/execute/modules/program-23.a68         |  6 +++
 5 files changed, 68 insertions(+), 27 deletions(-)

diff --git a/gcc/algol68/a68-imports.cc b/gcc/algol68/a68-imports.cc
index ff117163e155..a13e05940e0f 100644
--- a/gcc/algol68/a68-imports.cc
+++ b/gcc/algol68/a68-imports.cc
@@ -1110,26 +1110,6 @@ a68_decode_modes (MOIF_T *moif, encoded_modes_map_t 
&encoded_modes,
       vec_safe_push (MODES (moif), em->moid);
     }
 
-  /* Next step is to see if equivalent modes the any of the modes in the moif
-      DIM already exist in the compiler's mode list.  In that case, replace the
-      DIM moif's mode with the existing mode anywhere in the moif.  */
-  for (MOID_T *m : MODES (moif))
-    {
-      MOID_T *r = a68_search_equivalent_mode (m);
-      if (r != NO_MOID)
-       {
-         a68_replace_equivalent_mode (MODES (moif), m, r);
-
-         /* Update encoded_modes to reflect the replacement.  */
-         for (auto entry : encoded_modes)
-           {
-             struct encoded_mode *em = entry.second;
-             if (em->moid == m)
-               em->moid = r;
-           }
-       }
-    }
-
   *errstr = NULL;
   *ppos = pos;
   return true;
@@ -1419,5 +1399,41 @@ a68_open_packet (const char *module)
   MOIF_T *moif = TOP_MOIF (&A68_JOB);
   while (moif != NO_MOIF && strcmp (NAME (moif), module) != 0)
     FORWARD (moif);
+
+  /* If we got a moif, we need to make sure that it doesn't introduce new modes
+     that are equivalent to any mode in the compiler's mode list.  If it does,
+     we replace the mode everywhere in the moif.  */
+
+  if (moif != NO_MOIF)
+    {
+      for (MOID_T *m : MODES (moif))
+       {
+         MOID_T *r = a68_search_equivalent_mode (m);
+         if (r != NO_MOID)
+           {
+             a68_replace_equivalent_mode (MODES (moif), m, r);
+
+             /* Update extracts to reflect the replacement.  */
+             for (EXTRACT_T *e : INDICANTS (moif))
+               {
+                 if (EXTRACT_MODE (e) == m)
+                   EXTRACT_MODE (e) = r;
+               }
+
+             for (EXTRACT_T *e : IDENTIFIERS (moif))
+               {
+                 if (EXTRACT_MODE (e) == m)
+                   EXTRACT_MODE (e) = r;
+               }
+
+             for (EXTRACT_T *e : OPERATORS (moif))
+               {
+                 if (EXTRACT_MODE (e) == m)
+                   EXTRACT_MODE (e) = r;
+               }
+           }
+       }
+    }
+
   return moif;
 }
diff --git a/gcc/algol68/a68-parser-extract.cc 
b/gcc/algol68/a68-parser-extract.cc
index f02ae6db322c..70c0dd74cac8 100644
--- a/gcc/algol68/a68-parser-extract.cc
+++ b/gcc/algol68/a68-parser-extract.cc
@@ -204,12 +204,6 @@ extract_revelation (NODE_T *q, const char *module, TAG_T 
*tag)
   if (tag != NO_TAG)
     MOIF (tag) = moif;
 
-  /* First thing to do is to extract the revelations of publicized modules in
-     this moif.  This leads to recursive calls of this function.  */
-
-  for (EXTRACT_T *e : MODULES (moif))
-    extract_revelation (q, EXTRACT_SYMBOL (e), NO_TAG);
-
   /* Store all the modes from the MOIF in the moid list.
 
      The front-end depends on being able to compare any two modes by pointer
@@ -225,10 +219,23 @@ extract_revelation (NODE_T *q, const char *module, TAG_T 
*tag)
        {
          MOID_T *r = a68_register_extra_mode (&TOP_MOID (&A68_JOB), m);
          if (r != m)
-           gcc_unreachable ();
+           {
+             printf ("r: %s\n", a68_moid_to_string (r, 80, NO_NODE, false));
+             printf ("m: %s\n", a68_moid_to_string (m, 80, NO_NODE, false));
+             gcc_unreachable ();
+           }
        }
     }
 
+  /* Second thing to do is to extract the revelations of publicized modules in
+     this moif.  This leads to recursive calls of this function.  Note that
+     this should be done _after_ the modes get added to the global list of
+     modes so mode deduplication in a68_open_packet in the recursive
+     extract_revelation calls is properly done.  */
+
+  for (EXTRACT_T *e : MODULES (moif))
+    extract_revelation (q, EXTRACT_SYMBOL (e), NO_TAG);
+
   /* Store mode indicants from the MOIF in the symbol table,
      and also in the moid list.  */
   for (EXTRACT_T *e : INDICANTS (moif))
diff --git a/gcc/testsuite/algol68/execute/modules/module23bar.a68 
b/gcc/testsuite/algol68/execute/modules/module23bar.a68
new file mode 100644
index 000000000000..bc7933004df9
--- /dev/null
+++ b/gcc/testsuite/algol68/execute/modules/module23bar.a68
@@ -0,0 +1,7 @@
+module Module23Bar = access pub Module23Foo
+def
+    pub mode BarMode = ref FooMode;
+    pub int bar = foo + 10;
+    skip
+fed
+
diff --git a/gcc/testsuite/algol68/execute/modules/module23foo.a68 
b/gcc/testsuite/algol68/execute/modules/module23foo.a68
new file mode 100644
index 000000000000..574c92cb5be8
--- /dev/null
+++ b/gcc/testsuite/algol68/execute/modules/module23foo.a68
@@ -0,0 +1,5 @@
+module Module23Foo =
+def pub mode FooMode = struct (string name, doc);
+    pub int foo = 10;
+    skip
+fed
diff --git a/gcc/testsuite/algol68/execute/modules/program-23.a68 
b/gcc/testsuite/algol68/execute/modules/program-23.a68
new file mode 100644
index 000000000000..d1b6fc4c5979
--- /dev/null
+++ b/gcc/testsuite/algol68/execute/modules/program-23.a68
@@ -0,0 +1,6 @@
+{ dg-modules "module23foo module23bar" }
+
+access Module23Bar
+begin assert (foo = 10);
+      assert (bar = 20)
+end

Reply via email to