From: Jason Merrill Date: Wed, 28 Jan 2026 06:17:13 +0000 (+0800) Subject: c++: defer DECL_ONE_ONLY vs consteval-only [PR122785] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=35b17c7713d4bd7a675ee8908724325e957d1482;p=thirdparty%2Fgcc.git c++: defer DECL_ONE_ONLY vs consteval-only [PR122785] 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 --- diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 270158510df..c24bbc889ed 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -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 index 00000000000..025f2e27ea1 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/reflect-1_a.H @@ -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 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 index 00000000000..a3c5b67d09a --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/reflect-1_b.C @@ -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;