diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2021-03-14 22:51:56 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2021-04-05 13:40:36 +0200 |
commit | 76a7e7e706ac4c01cead3c6514322aaad88f9a63 (patch) | |
tree | b373e3d40f0e988db5f8e5de72b5c91a7e3d0508 /gcc/d/modules.cc | |
parent | 3cb9e3aee98a206b786d7414ad28e67fbcceba5c (diff) | |
download | gcc-76a7e7e706ac4c01cead3c6514322aaad88f9a63.zip gcc-76a7e7e706ac4c01cead3c6514322aaad88f9a63.tar.gz gcc-76a7e7e706ac4c01cead3c6514322aaad88f9a63.tar.bz2 |
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.
Diffstat (limited to 'gcc/d/modules.cc')
-rw-r--r-- | gcc/d/modules.cc | 20 |
1 files changed, 8 insertions, 12 deletions
diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc index af69815..8786344 100644 --- a/gcc/d/modules.cc +++ b/gcc/d/modules.cc @@ -125,7 +125,7 @@ static Module *current_module_decl; by both module initialization and dso handlers. */ static FuncDeclaration * -get_internal_fn (tree ident) +get_internal_fn (tree ident, const Prot &prot) { Module *mod = current_module_decl; const char *name = IDENTIFIER_POINTER (ident); @@ -141,9 +141,10 @@ get_internal_fn (tree ident) FuncDeclaration *fd = FuncDeclaration::genCfunc (NULL, Type::tvoid, Identifier::idPool (name)); + fd->generated = true; fd->loc = Loc (mod->srcfile->toChars (), 1, 0); fd->parent = mod; - fd->protection.kind = Prot::private_; + fd->protection = prot; fd->semanticRun = PASSsemantic3done; return fd; @@ -155,7 +156,7 @@ get_internal_fn (tree ident) static tree build_internal_fn (tree ident, tree expr) { - FuncDeclaration *fd = get_internal_fn (ident); + FuncDeclaration *fd = get_internal_fn (ident, Prot (Prot::private_)); tree decl = get_symbol_decl (fd); tree old_context = start_function (fd); @@ -337,7 +338,8 @@ build_dso_cdtor_fn (bool ctor_p) } } */ - FuncDeclaration *fd = get_internal_fn (get_identifier (name)); + FuncDeclaration *fd = get_internal_fn (get_identifier (name), + Prot (Prot::public_)); tree decl = get_symbol_decl (fd); TREE_PUBLIC (decl) = 1; @@ -345,8 +347,6 @@ build_dso_cdtor_fn (bool ctor_p) DECL_VISIBILITY (decl) = VISIBILITY_HIDDEN; DECL_VISIBILITY_SPECIFIED (decl) = 1; - d_comdat_linkage (decl); - /* Start laying out the body. */ tree old_context = start_function (fd); rest_of_decl_compilation (decl, 1, 0); @@ -443,15 +443,11 @@ register_moduleinfo (Module *decl, tree minfo) /* Declare dso_slot and dso_initialized. */ dso_slot_node = build_dso_registry_var (GDC_PREFIX ("dso_slot"), ptr_type_node); - DECL_EXTERNAL (dso_slot_node) = 0; - d_comdat_linkage (dso_slot_node); - rest_of_decl_compilation (dso_slot_node, 1, 0); + d_finish_decl (dso_slot_node); dso_initialized_node = build_dso_registry_var (GDC_PREFIX ("dso_initialized"), boolean_type_node); - DECL_EXTERNAL (dso_initialized_node) = 0; - d_comdat_linkage (dso_initialized_node); - rest_of_decl_compilation (dso_initialized_node, 1, 0); + d_finish_decl (dso_initialized_node); /* Declare dso_ctor() and dso_dtor(). */ tree dso_ctor = build_dso_cdtor_fn (true); |