d: Use weak linkage for template symbols instead of gnu.linkonce (PR99914)
authorIain Buclaw <ibuclaw@gdcproject.org>
Sun, 14 Mar 2021 21:51:56 +0000 (22:51 +0100)
committerIain Buclaw <ibuclaw@gdcproject.org>
Mon, 5 Apr 2021 11:40:36 +0000 (13:40 +0200)
commit76a7e7e706ac4c01cead3c6514322aaad88f9a63
treeb373e3d40f0e988db5f8e5de72b5c91a7e3d0508
parent3cb9e3aee98a206b786d7414ad28e67fbcceba5c
d: Use weak linkage for template symbols instead of gnu.linkonce (PR99914)

The default linkage of templates in the D language is now DECL_WEAK
instead of  DECL_ONE_ONLY, if supported.  This better matches the
expected override semantics of template symbols compiled to object code.

For example:

 module rt.config;
 template rt_flag()
 {
   pragma(mangle, "rt_flag") __gshared bool rt_flag = true;
 }

 module main;
 extern(C) __gshared bool rt_flag = false;

The above currently does not succeed in linking due to there being
multiple definitions of `rt_flag' in different sections that aren't
considered mergeable.

The compiler flag enabling toggling of this has been given a clearer
named `-fweak-templates', which distinguishes itself from G++ `-fweak',
which is intended only for testing.

gcc/d/ChangeLog:

PR d/99914
* d-lang.cc (d_init): Disable flag_weak_templates if no support for
weak or one-only symbols.
* d-tree.h (VAR_OR_FUNCTION_DECL_CHECK): New macro.
(DECL_INSTANTIATED): New macro.
(d_comdat_linkage): Remove declaration.
(d_linkonce_linkage): Remove declaration.
(set_linkage_for_decl): New declaration.
* decl.cc (DeclVisitor::visit (StructDeclaration *)): Replace call to
d_linkonce_linkage with setting DECL_INSTANTIATED.
(DeclVisitor::visit (ClassDeclaration *)): Likewise.
(DeclVisitor::visit (EnumDeclaration *)): Likewise.
(DeclVisitor::visit (InterfaceDeclaration *)): Remove call to
d_linkonce_linkage.
(get_symbol_decl): Call set_linkage_for_decl instead of
d_linkonce_linkage.
(d_finish_decl): Call set_linkage_for_decl.
(d_comdat_linkage): Made function static.  Only set DECL_COMDAT for
DECL_INSTANTIATED decls.
(d_linkonce_linkage): Remove function.
(d_weak_linkage): New function.
(set_linkage_for_decl): New function.
* gdc.texi (Runtime Options): Rename -fno-weak to -fno-weak-templates,
update documentation of option.
* lang.opt (fweak): Rename option to ...
(fweak-templates): ... this.  Update help string.
* modules.cc (get_internal_fn): Add Prot parameter.  Set generated
function flag.
(build_internal_fn): Update call to get_internal_fn.
(build_dso_cdtor_fn): Likewise.
(register_moduleinfo): Call d_finish_decl on dso_slot_node and
dso_initialized_node.
* typeinfo.cc (TypeInfoVisitor::internal_reference): Call
set_linkage_for_decl instead of d_comdat_linkage.
(TypeInfoDeclVisitor::visit (TypeInfoDeclaration *)): Remove calls to
d_linkonce_linkage and d_comdat_linkage.
(get_cpp_typeinfo_decl): Likewise.

gcc/testsuite/ChangeLog:

PR d/99914
* gdc.dg/pr99914.d: New test.
gcc/d/d-lang.cc
gcc/d/d-tree.h
gcc/d/decl.cc
gcc/d/gdc.texi
gcc/d/lang.opt
gcc/d/modules.cc
gcc/d/typeinfo.cc
gcc/testsuite/gdc.dg/pr99914.d [new file with mode: 0644]