]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
d: Add TARGET_D_TEMPLATES_ALWAYS_COMDAT
authorIain Buclaw <ibuclaw@gdcproject.org>
Tue, 13 Apr 2021 20:28:55 +0000 (22:28 +0200)
committerIain Buclaw <ibuclaw@gdcproject.org>
Sat, 17 Apr 2021 10:50:25 +0000 (12:50 +0200)
Following up on the fix for PR99914, when testing on MinGW, it was found
not to support weak in the same way as on ELF or Mach-O targets.

So the linkage has been reverted back to COMDAT for that target, however
in order to properly support overriding functions and variables, all
declarations with external linkage must be put on COMDAT.  For this a
new target hook has been added to control the behavior.

gcc/ChangeLog:

PR d/99914
* config/i386/winnt-d.c (TARGET_D_TEMPLATES_ALWAYS_COMDAT): Define.
* doc/tm.texi: Regenerate.
* doc/tm.texi.in (D language and ABI): Add @hook for
TARGET_D_TEMPLATES_ALWAYS_COMDAT.

gcc/d/ChangeLog:

PR d/99914
* d-target.def (d_templates_always_comdat): New hook.
* d-tree.h (mark_needed): Remove prototype.
* decl.cc: Include d-target.h.
(mark_needed): Rename to...
(d_mark_needed): ...this.  Make static.
(set_linkage_for_decl): Put variables in comdat if
d_templates_always_comdat.

gcc/config/i386/winnt-d.c
gcc/d/d-target.def
gcc/d/d-tree.h
gcc/d/decl.cc
gcc/doc/tm.texi
gcc/doc/tm.texi.in

index b9780258549076c64c9679b1dcacbfd057f9eb17..ea4cd13d0bf6463eb2be145c3548b5d2462b8814 100644 (file)
@@ -78,4 +78,9 @@ winnt_d_register_target_info (void)
 #undef TARGET_D_MINFO_END_NAME
 #define TARGET_D_MINFO_END_NAME "__stop_minfo"
 
+/* Define TARGET_D_TEMPLATES_ALWAYS_COMDAT for Windows targets.  */
+
+#undef TARGET_D_TEMPLATES_ALWAYS_COMDAT
+#define TARGET_D_TEMPLATES_ALWAYS_COMDAT true
+
 struct gcc_targetdm targetdm = TARGETDM_INITIALIZER;
index aa6bf55e6e691b45dc510f3ea5383479e8f920fe..67647515cf274975e788e9110ec58f126b47096e 100644 (file)
@@ -104,5 +104,13 @@ and @var{link_windows} to @code{1} to apply @code{stdcall} to functions with\n\
  bool, (unsigned int *link_system, unsigned int *link_windows),
  hook_bool_uintp_uintp_false)
 
+/* True if instantiations are always COMDAT if they have external linkage.  */
+DEFHOOKPOD
+(d_templates_always_comdat,
+ "This flag is true if instantiated functions and variables are always COMDAT\n\
+if they have external linkage.  If this flag is false, then instantiated\n\
+decls will be emitted as weak symbols.  The default is @code{false}.",
+ bool, false)
+
 /* Close the 'struct gcc_targetdm' definition.  */
 HOOK_VECTOR_END (C90_EMPTY_HACK)
index c1b6f27514936d5aa0ca016df54f4d014325ae15..bb731a60541dbd92e16019abbc32d1e38072e0d0 100644 (file)
@@ -631,7 +631,6 @@ extern void d_finish_decl (tree);
 extern tree make_thunk (FuncDeclaration *, int);
 extern tree start_function (FuncDeclaration *);
 extern void finish_function (tree);
-extern void mark_needed (tree);
 extern tree get_vtable_decl (ClassDeclaration *);
 extern tree build_new_class_expr (ClassReferenceExp *);
 extern tree aggregate_initializer_decl (AggregateDeclaration *);
index 8948e40e9027e8fb010d10c32ebfdafa49881474..7d1378255bd7b92b282ee49c80a3f81ef210d0cd 100644 (file)
@@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "symtab-thunks.h"
 
 #include "d-tree.h"
+#include "d-target.h"
 
 
 /* Return identifier for the external mangled name of DECL.  */
@@ -1960,8 +1961,8 @@ finish_function (tree old_context)
 /* Mark DECL, which is a VAR_DECL or FUNCTION_DECL as a symbol that
    must be emitted in this, output module.  */
 
-void
-mark_needed (tree decl)
+static void
+d_mark_needed (tree decl)
 {
   TREE_USED (decl) = 1;
 
@@ -2380,6 +2381,18 @@ set_linkage_for_decl (tree decl)
   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (decl))
     return d_comdat_linkage (decl);
 
+  /* If all instantiations must go in COMDAT, give them that linkage.
+     This also applies to other extern declarations, so that it is possible
+     for them to override template declarations.  */
+  if (targetdm.d_templates_always_comdat)
+    {
+      /* Make sure that instantiations are not removed.  */
+      if (flag_weak_templates && DECL_INSTANTIATED (decl))
+       d_mark_needed (decl);
+
+      return d_comdat_linkage (decl);
+    }
+
   /* Instantiated variables and functions need to be overridable by any other
      symbol with the same name, so give them weak linkage.  */
   if (DECL_INSTANTIATED (decl))
index 97c8eebcd6f71ce6bae33407a35699d16a612c02..823f85ba9abbaf360b5964e9294801eb72ccf689 100644 (file)
@@ -10850,6 +10850,12 @@ and @var{link_windows} to @code{1} to apply @code{stdcall} to functions with
 @code{extern(Windows)} linkage.
 @end deftypefn
 
+@deftypevr {D Target Hook} bool TARGET_D_TEMPLATES_ALWAYS_COMDAT
+This flag is true if instantiated functions and variables are always COMDAT
+if they have external linkage.  If this flag is false, then instantiated
+decls will be emitted as weak symbols.  The default is @code{false}.
+@end deftypevr
+
 @node Named Address Spaces
 @section Adding support for named address spaces
 @cindex named address spaces
index e2d49ee9f5788dd0dfce1147a63b615f2788eabd..2321a5fc4e02562b6a55e6f3f1afa2e3aee3f4e8 100644 (file)
@@ -7369,6 +7369,8 @@ floating-point support; they are not included in this mechanism.
 
 @hook TARGET_D_HAS_STDCALL_CONVENTION
 
+@hook TARGET_D_TEMPLATES_ALWAYS_COMDAT
+
 @node Named Address Spaces
 @section Adding support for named address spaces
 @cindex named address spaces