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;

Reply via email to