aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/modules.cc
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2021-03-14 22:51:56 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2021-04-05 13:40:36 +0200
commit76a7e7e706ac4c01cead3c6514322aaad88f9a63 (patch)
treeb373e3d40f0e988db5f8e5de72b5c91a7e3d0508 /gcc/d/modules.cc
parent3cb9e3aee98a206b786d7414ad28e67fbcceba5c (diff)
downloadgcc-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.cc20
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);