https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118513
Nathaniel Shead <nshead at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |NEW Last reconfirmed| |2025-01-16 Ever confirmed|0 |1 --- Comment #4 from Nathaniel Shead <nshead at gcc dot gnu.org> --- Confirmed. Without having looked into it too much I think maybe doing `varpool_node::finalize_decl` might be the way to go to cover this and any other related issues that may be cropping up by not having done so? On a possibly-related note I discovered that 'decl_linkage' doesn't correctly work for structured bindings (it always gives lk_none), and we don't check for violation of https://eel.is/c++draft/module.import#6 when removing the anonymous namespace. Here's a quick untested patch that seemingly fixes most of these issues (though I admit I copied conditions for finalize_decl somewhat at random from make_rtl_for_nonlocal_decl; I would need to spend more time analysing the logic to know what is actually needed here). diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 61116fe7669..b4117d353a2 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -12467,6 +12467,13 @@ trees_in::read_var_def (tree decl, tree maybe_template) note_vague_linkage_variable (decl); } DECL_INITIAL (decl) = init; + if (VAR_P (maybe_template) + && !DECL_IMPLICIT_INSTANTIATION (decl) + && (!DECL_FUNCTION_SCOPE_P (decl) || TREE_STATIC (decl)) + && (!DECL_DEFER_OUTPUT (decl) || DECL_INITIAL (decl)) + && !DECL_EXTERNAL (decl) + && !DECL_HAS_VALUE_EXPR_P (decl)) + varpool_node::finalize_decl (decl); if (!dyn_init) ; else if (CP_DECL_THREAD_LOCAL_P (decl)) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 9600b140916..643be09528f 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -16675,6 +16675,7 @@ cp_parser_decomposition_declaration (cp_parser *parser, cp_finish_decl (decl, initializer, non_constant_p, NULL_TREE, (is_direct_init ? LOOKUP_NORMAL : LOOKUP_IMPLICIT), &decomp); + check_module_decl_linkage (decl); } } else if (decl != error_mark_node) diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index dd6e872e4e7..b06d8a6b7fb 100644 --- a/gcc/cp/tree.cc +++ b/gcc/cp/tree.cc @@ -5998,6 +5998,8 @@ decl_linkage (tree decl) { if (TREE_CODE (decl) == TYPE_DECL && !TYPE_ANON_P (TREE_TYPE (decl))) /* This entity has a typedef name for linkage purposes. */; + else if (DECL_DECOMPOSITION_P (decl) && DECL_DECOMP_IS_BASE (decl)) + /* Structured binding declarations can have linkage. */; else if (TREE_CODE (decl) == NAMESPACE_DECL && cxx_dialect >= cxx11) /* An anonymous namespace has internal linkage since C++11. */ return lk_internal;