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;