In principle all the modes emitted by the module exporter are
deduplicated.  However, in certain cases in which the same unions
result from unraveling, duplicates may occur.

This patch makes a68_open_packet to deduplicate duplicated modes from
the same moif.

Signed-off-by: Jose E. Marchesi <[email protected]>

gcc/algol68/ChangeLog

        * a68-imports.cc (INCLUDE_VECTOR): Define.
        (a68_open_packet): Deduplicate within-moif modes while importing.

gcc/testsuite/ChangeLog

        * algol68/execute/modules/module26.a68: New file.
        * algol68/execute/modules/program-26.a68: New test.
---
 gcc/algol68/a68-imports.cc                    | 24 ++++++++++++++++---
 .../algol68/execute/modules/module26.a68      | 15 ++++++++++++
 .../algol68/execute/modules/program-26.a68    |  6 +++++
 3 files changed, 42 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/algol68/execute/modules/module26.a68
 create mode 100644 gcc/testsuite/algol68/execute/modules/program-26.a68

diff --git a/gcc/algol68/a68-imports.cc b/gcc/algol68/a68-imports.cc
index 394c0543ec9..e7b5580eec5 100644
--- a/gcc/algol68/a68-imports.cc
+++ b/gcc/algol68/a68-imports.cc
@@ -29,6 +29,7 @@
 
 #define INCLUDE_MEMORY
 #define INCLUDE_STRING
+#define INCLUDE_VECTOR
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
@@ -1470,15 +1471,32 @@ a68_open_packet (const char *module, const char 
*basename)
     }
 
   /* 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.  */
+     that are equivalent to any mode in the compiler's mode list, nor modes
+     that are equivalent to other modes introduced in this same moif.  If it
+     does, we replace the mode everywhere in the moif. */
 
   if (moif != NO_MOIF)
     {
+      std::vector<MOID_T *> known_moids;
+
       for (MOID_T *m : MODES (moif))
        {
          MOID_T *r = a68_search_equivalent_mode (m);
-         if (r != NO_MOID)
+         if (r == NO_MOID)
+           {
+             for (size_t i = 0; i < known_moids.size (); ++i)
+               {
+                 if (a68_prove_moid_equivalence (m, known_moids[i]))
+                   {
+                     r =  m;
+                     break;
+                   }
+               }
+           }
+
+         if (r == NO_MOID)
+           known_moids.push_back (m);
+         else
            {
              a68_replace_equivalent_mode (MODES (moif), m, r);
 
diff --git a/gcc/testsuite/algol68/execute/modules/module26.a68 
b/gcc/testsuite/algol68/execute/modules/module26.a68
new file mode 100644
index 00000000000..2ca24d9c794
--- /dev/null
+++ b/gcc/testsuite/algol68/execute/modules/module26.a68
@@ -0,0 +1,15 @@
+{ The way union unraveling works in parser-modes, the union(Foo,Bar)
+  below triggers the emission of two entries with the same modes in
+  the resulting module interface. }
+
+module Module_26 =
+def
+    pub int public;
+    int private;
+    pub mode Baz = union(Foo,Bar);
+    pub mode Foo = union (int,bool,real);
+    mode Bar = union (int,bool);
+    mode Je = struct (int lele);
+
+    skip
+fed
diff --git a/gcc/testsuite/algol68/execute/modules/program-26.a68 
b/gcc/testsuite/algol68/execute/modules/program-26.a68
new file mode 100644
index 00000000000..0e189fb770b
--- /dev/null
+++ b/gcc/testsuite/algol68/execute/modules/program-26.a68
@@ -0,0 +1,6 @@
+{ dg-modules "module26" }
+access Module_26
+begin
+      Baz x = 10, y = false, z = 3.14;
+      skip
+end
-- 
2.39.5

Reply via email to