]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: defer DECL_ONE_ONLY vs consteval-only [PR122785]
authorJason Merrill <jason@redhat.com>
Wed, 28 Jan 2026 06:17:13 +0000 (14:17 +0800)
committerJason Merrill <jason@redhat.com>
Sat, 31 Jan 2026 02:16:08 +0000 (10:16 +0800)
The failure in the given PR occurs because when setting up an
imported vague-linkage variable, we currently call 'maybe_commonize_var'
which for -freflection checks 'consteval_only_p'.  Unfortunately this
latter function needs to call 'complete_type_p' which can perform
recursive loading of the (possibly yet-to-be-streamed) class type,
breaking modules assumptions.

If we just remove the consteval_only_p early exit from maybe_commonize_var,
we end up crashing at EOF while trying to mangle its comdat group, so we
need to undo maybe_commonize_var along with setting DECL_EXTERN.

PR c++/122785

gcc/cp/ChangeLog:

* decl.cc (maybe_commonize_var): Don't check consteval_only_p.
(make_rtl_for_nonlocal_decl): Undo make_decl_one_only for
consteval-only variables.

gcc/testsuite/ChangeLog:

* g++.dg/modules/reflect-1_a.H: New test.
* g++.dg/modules/reflect-1_b.C: New test.

Co-authored-by: Nathaniel Shead <nathanieloshead@gmail.com>
gcc/cp/decl.cc
gcc/testsuite/g++.dg/modules/reflect-1_a.H [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/reflect-1_b.C [new file with mode: 0644]

index 270158510dff4867c276e082c53c7bc5fce1508a..c24bbc889ed71bd53d29a9f0ecb9e5208a763e32 100644 (file)
@@ -7263,10 +7263,6 @@ maybe_commonize_var (tree decl)
   if (DECL_ARTIFICIAL (decl) && !DECL_DECOMPOSITION_P (decl))
     return;
 
-  /* These are not output at all.  */
-  if (consteval_only_p (decl))
-    return;
-
   /* Static data in a function with comdat linkage also has comdat
      linkage.  */
   if ((TREE_STATIC (decl)
@@ -8758,6 +8754,13 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const char* asmspec)
     {
       /* Disable assemble_variable.  */
       DECL_EXTERNAL (decl) = true;
+      /* Undo make_decl_one_only.  */
+      if (DECL_COMDAT_GROUP (decl))
+       {
+         symtab_node *node = symtab_node::get (decl);
+         node->set_comdat_group (NULL);
+         node->dissolve_same_comdat_group_list ();
+       }
       return;
     }
 
diff --git a/gcc/testsuite/g++.dg/modules/reflect-1_a.H b/gcc/testsuite/g++.dg/modules/reflect-1_a.H
new file mode 100644 (file)
index 0000000..025f2e2
--- /dev/null
@@ -0,0 +1,11 @@
+// PR c++/122785
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-fmodule-header -freflection" }
+// { dg-module-cmi {} }
+
+struct S {
+  friend S foo();
+  S bar(int);
+};
+inline S s;
+template <typename T> decltype(s.bar(T{})) foo(T);
diff --git a/gcc/testsuite/g++.dg/modules/reflect-1_b.C b/gcc/testsuite/g++.dg/modules/reflect-1_b.C
new file mode 100644 (file)
index 0000000..a3c5b67
--- /dev/null
@@ -0,0 +1,6 @@
+// PR c++/122785
+// { dg-do compile { target c++26 } }
+// { dg-additional-options "-fmodules -freflection" }
+
+import "reflect-1_a.H";
+using ::S;