Add an ar-link LTO test with three slim members: main needs f1 and f3, and f3 needs f2, whose member precedes it in the archive. On targets whose archive index does not carry the IR symbols, the linker learns what a member defines by probing it through the plugin while scanning the archive; a linker that does not keep the result of that probe for a later pass drops f2 and the link fails with an undefined reference. On ELF the archive index lists the IR symbols and the test passes.
Seen on m68k-amigaos with binutils 2.46, whose HUNK_LIB index carries only the __gnu_lto_slim marker for slim members; the generic archive element check in bfd/linker.c ignored bfd_plugin_yes_unused, unlike elf_link_add_archive_symbols: https://github.com/AmigaPorts/m68k-amigaos-gcc/issues/93 Assisted-by: Claude Fable 5.1 (Anthropic) Signed-off-by: Bernie Innocenti <[email protected]> gcc/testsuite/ChangeLog: * gcc.dg/lto/slim-archive-order_0.c: New test. * gcc.dg/lto/slim-archive-order_1.c: Likewise. * gcc.dg/lto/slim-archive-order_2.c: Likewise. * gcc.dg/lto/slim-archive-order_3.c: Likewise. --- .../gcc.dg/lto/slim-archive-order_0.c | 18 ++++++++++++++++++ .../gcc.dg/lto/slim-archive-order_1.c | 6 ++++++ .../gcc.dg/lto/slim-archive-order_2.c | 6 ++++++ .../gcc.dg/lto/slim-archive-order_3.c | 8 ++++++++ 4 files changed, 38 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/lto/slim-archive-order_0.c create mode 100644 gcc/testsuite/gcc.dg/lto/slim-archive-order_1.c create mode 100644 gcc/testsuite/gcc.dg/lto/slim-archive-order_2.c create mode 100644 gcc/testsuite/gcc.dg/lto/slim-archive-order_3.c diff --git a/gcc/testsuite/gcc.dg/lto/slim-archive-order_0.c b/gcc/testsuite/gcc.dg/lto/slim-archive-order_0.c new file mode 100644 index 00000000000..3d0f6bc48a2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/slim-archive-order_0.c @@ -0,0 +1,18 @@ +/* Slim LTO members of a static library must be pulled in when they are + needed only by a later member of the same library. The harness puts + _1, _2 and _3 into the archive in that order: main needs f1 and f3, + and f3 needs f2, so f2's member sits before the only member that + references it. A linker whose archive index does not carry the IR + symbols has to probe each member through the plugin, and one that + forgets the result of that probe on a later pass drops f2. */ +/* { dg-lto-do ar-link } */ +/* { dg-lto-options { { -O2 -flto -fno-fat-lto-objects } } } */ + +extern int f1 (int); +extern int f3 (int); + +int +main (int argc, char **argv) +{ + return f1 (argc) + f3 (argc); +} diff --git a/gcc/testsuite/gcc.dg/lto/slim-archive-order_1.c b/gcc/testsuite/gcc.dg/lto/slim-archive-order_1.c new file mode 100644 index 00000000000..58811c5f94c --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/slim-archive-order_1.c @@ -0,0 +1,6 @@ +/* first archive member, needed by main */ +int +f1 (int a) +{ + return a * 31; +} diff --git a/gcc/testsuite/gcc.dg/lto/slim-archive-order_2.c b/gcc/testsuite/gcc.dg/lto/slim-archive-order_2.c new file mode 100644 index 00000000000..17c5ffcc503 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/slim-archive-order_2.c @@ -0,0 +1,6 @@ +/* second archive member, needed only by the third one */ +int +f2 (int a) +{ + return a + 7; +} diff --git a/gcc/testsuite/gcc.dg/lto/slim-archive-order_3.c b/gcc/testsuite/gcc.dg/lto/slim-archive-order_3.c new file mode 100644 index 00000000000..3d107378a15 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/slim-archive-order_3.c @@ -0,0 +1,8 @@ +/* third archive member, needed by main, references the second one */ +extern int f2 (int); + +int +f3 (int a) +{ + return f2 (a) * 3; +} -- 2.55.0
