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
