Does this fix seem reasonable, or is there something I've missed?

My change to g++.dg/lto/pr101396_0.C also causes it to fail link with
some flags on my machine, with:

FAIL: g++.dg/lto/pr101396 cp_lto_pr101396_0.o-cp_lto_pr101396_1.o link, -O0 
-flto -flto-partition=none -fuse-linker-plugin
FAIL: g++.dg/lto/pr101396 cp_lto_pr101396_0.o-cp_lto_pr101396_1.o link, -O0 
-flto -flto-partition=1to1 -fno-use-linker-plugin
FAIL: g++.dg/lto/pr101396 cp_lto_pr101396_0.o-cp_lto_pr101396_1.o link, -O0 
-flto -fuse-linker-plugin -fno-fat-lto-objects

But the logs doesn't indicate exactly what failed with the link, and
when I try running the commands from the log myself it works fine (exit
status 0, executable generated and can be ran, etc.).  This seems to
happen also on a clean tree without my changes, so not sure if this is a
bug or I've misconfigured something or what; any hints?

Other than that failure, successfully bootstrapped and regtested on
x86_64-pc-linux-gnu.

-- >8 --

On a DECL, TREE_CHAIN will find any other declarations in the same
binding level.  This caused an ICE in PR121865 because the next entity
in the binding level was the uninstantiated unique friend 'foo', for
which after being found the compiler tries to generate a mangled name
for it and crashes.

This didn't happen in non-modules testcases only because normally the
unique friend function would have been chained after its template_decl,
and find_decl_types_r bails on lang-specific nodes so it never saw the
uninstantiated decl.  With modules however the order of chaining
changed, causing the error.

I don't think it's ever necessary to walk into the TREE_CHAIN, from what
I can see; other cases where it might be useful (block vars or type
fields) are already handled explicitly elsewhere, and only one test
fails because of the change, due to accidentally relying on this "walk
into the next in-scope declaration" behaviour.

        PR c++/121865

gcc/ChangeLog:

        * ipa-free-lang-data.cc (find_decls_types_r): Don't walk into
        TREE_CHAINs of DECLs.

gcc/testsuite/ChangeLog:

        * g++.dg/lto/pr101396_0.C: Ensure A will be walked into (and
        isn't constant-folded out of the GIMPLE for the function).
        * g++.dg/modules/lto-4_a.C: New test.
        * g++.dg/modules/lto-4_b.C: New test.

Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
---
 gcc/ipa-free-lang-data.cc              |  3 ---
 gcc/testsuite/g++.dg/lto/pr101396_0.C  |  3 ++-
 gcc/testsuite/g++.dg/modules/lto-4_a.C | 10 ++++++++++
 gcc/testsuite/g++.dg/modules/lto-4_b.C |  8 ++++++++
 4 files changed, 20 insertions(+), 4 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/lto-4_a.C
 create mode 100644 gcc/testsuite/g++.dg/modules/lto-4_b.C

diff --git a/gcc/ipa-free-lang-data.cc b/gcc/ipa-free-lang-data.cc
index 8c4fb3c6b64..41afc6ec82f 100644
--- a/gcc/ipa-free-lang-data.cc
+++ b/gcc/ipa-free-lang-data.cc
@@ -750,9 +750,6 @@ find_decls_types_r (tree *tp, int *ws, void *data)
          && DECL_HAS_VALUE_EXPR_P (t))
        fld_worklist_push (DECL_VALUE_EXPR (t), fld);
 
-      if (TREE_CODE (t) != FIELD_DECL
-         && TREE_CODE (t) != TYPE_DECL)
-       fld_worklist_push (TREE_CHAIN (t), fld);
       *ws = 0;
     }
   else if (TYPE_P (t))
diff --git a/gcc/testsuite/g++.dg/lto/pr101396_0.C 
b/gcc/testsuite/g++.dg/lto/pr101396_0.C
index b7a2947a880..d26174df8e0 100644
--- a/gcc/testsuite/g++.dg/lto/pr101396_0.C
+++ b/gcc/testsuite/g++.dg/lto/pr101396_0.C
@@ -8,5 +8,6 @@ enum A : __UINT32_TYPE__ { // { dg-lto-warning "6: type 'A' 
violates the C\\+\\+
 
 int main()
 {
-  return (int) A::a;
+  enum A x = A::a;
+  return (int) x;
 }
diff --git a/gcc/testsuite/g++.dg/modules/lto-4_a.C 
b/gcc/testsuite/g++.dg/modules/lto-4_a.C
new file mode 100644
index 00000000000..16629158dc2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/lto-4_a.C
@@ -0,0 +1,10 @@
+// PR c++/121865
+// { dg-require-effective-target lto }
+// { dg-additional-options "-fmodules -flto" }
+
+export module M;
+export template <typename T> struct S;
+export template <typename T> void foo(S<T>) {}
+template <typename T> struct S {
+  friend void foo<>(S);
+};
diff --git a/gcc/testsuite/g++.dg/modules/lto-4_b.C 
b/gcc/testsuite/g++.dg/modules/lto-4_b.C
new file mode 100644
index 00000000000..0322855caf4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/lto-4_b.C
@@ -0,0 +1,8 @@
+// PR c++/121865
+// { dg-module-do link }
+// { dg-require-effective-target lto }
+// { dg-additional-options "-fmodules -flto" }
+
+import M;
+template struct S<int>;
+int main() {}
-- 
2.51.0

Reply via email to