]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ipa-free-lang-data: Don't walk into DECL_CHAIN when finding decls/types [PR121865]
authorNathaniel Shead <nathanieloshead@gmail.com>
Wed, 10 Sep 2025 04:25:22 +0000 (14:25 +1000)
committerNathaniel Shead <nathanieloshead@gmail.com>
Fri, 12 Sep 2025 11:58:09 +0000 (21:58 +1000)
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 DECL_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
DECL_CHAIN for any DECL.

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/lto/pr101396_1.C: Add message.
* g++.dg/modules/lto-4_a.C: New test.
* g++.dg/modules/lto-4_b.C: New test.

Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Richard Biener <rguenther@suse.de>
gcc/ipa-free-lang-data.cc
gcc/testsuite/g++.dg/lto/pr101396_0.C
gcc/testsuite/g++.dg/lto/pr101396_1.C
gcc/testsuite/g++.dg/modules/lto-4_a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/lto-4_b.C [new file with mode: 0644]

index 8c4fb3c6b64373da80795c5b459efd2e51c02a11..41afc6ec82fc8c72d29a98ba3d983ced7ae351e6 100644 (file)
@@ -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))
index b7a2947a8809146df1ff5edb417305c3c6a5a962..f195b270b64006ef65dfb7823f0875c59c5baab7 100644 (file)
@@ -6,7 +6,9 @@ enum A : __UINT32_TYPE__ { // { dg-lto-warning "6: type 'A' violates the C\\+\\+
   c
 };
 
-int main()
+int g(enum A x)
 {
-  return (int) A::a;
+  return (int) x;
 }
+
+int main() {}
index a6d032d694d99258ab4d0e1d4bd57a45c39ce591..782026e03ba5dbdfe4405b932f42a9764d687c0e 100644 (file)
@@ -1,4 +1,5 @@
 enum A : __UINT64_TYPE__ { // { dg-lto-note "6: an enum with different value name is defined in another translation unit" }
+  // { dg-lto-note "6: a type with different precision is defined in another translation unit" "" { target *-*-* } .-1 }
   a, // { dg-lto-note "3: mismatching definition" }
   b,
   c
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 (file)
index 0000000..1662915
--- /dev/null
@@ -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 (file)
index 0000000..0322855
--- /dev/null
@@ -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() {}