https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107873

            Bug ID: 107873
           Summary: C++ without SUPPORTS_ONE_ONLY
           Product: gcc
           Version: 13.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: aoliva at gcc dot gnu.org
  Target Milestone: ---

Created attachment 53967
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=53967&action=edit
working patch with SUPPORTS_ONE_ONLY, incomplete fix for !SUPPORTS_ONE_ONLY

I've attempted disabling SUPPORTS_ONE_ONLY to use a linker that supported weak
symbols but had some issues with comdat, and that didn't go well.

Several symbols with vague linkage, and that thus should be output as weak
definitions, were issued as strong definitions instead.  The scenarios involved
make_decl_one_only's checking of DECL_INITIAL before it was set, such as when
deciding between .common or .weak for typeinfo objects and for static variables
in inlined functions.  The attached patch fixes that, and bootstraps on
x86_64-linux-gnu with SUPPORTS_ONE_ONLY, and also on another non-pthreads
target without SUPPORTS_ONE_ONLY.

Without SUPPORTS_ONE_ONLY, the GNU/Linux bootstrap fails because pthread_once
is not weakref'ed in libstdc++: flag_weak is set to false, so we define
__GXX_WEAK__=0.  According to my reading of the documentation, __GXX_WEAK__
means whether symbols with vague linkage can be output as unifiable definitions
in multiple translation units (so SUPPORTS_ONE_ONLY could have it enabled
through comdat even with -fno-weak), so I tried this patchlet:

diff --git a/gcc/c-family/c-cppbuiltin.cc b/gcc/c-family/c-cppbuiltin.cc
index 333f3e138d611..15ef47c0c04f5 100644
--- a/gcc/c-family/c-cppbuiltin.cc
+++ b/gcc/c-family/c-cppbuiltin.cc
@@ -939,7 +939,15 @@ c_cpp_builtins (cpp_reader *pfile)

   if (c_dialect_cxx ())
     {
-      if (flag_weak && SUPPORTS_ONE_ONLY)
+      /* __GXX_WEAK__'s name is misleading, the documentation says it
+        tests for one-only spuport, but SUPPORTS_ONE_ONLY is also
+        slightly misleading, because weak symbols can be used for
+        one-only support even if !SUPPORtS_ONE_ONLY.  Here we
+        approximate the supprots_one_only() test that may clear
+        flag_weak, but we use the flag_weak result instead of
+        TARGET_SUPPORTS_WEAK, because the user may have disabled weak
+        symbols with -fno-weak.  */
+      if (flag_weak || SUPPORTS_ONE_ONLY)
        cpp_define (pfile, "__GXX_WEAK__=1");
       else
        cpp_define (pfile, "__GXX_WEAK__=0");


However, libstdc++ also uses it as telling whether weak undef / weakref is
available at all, a significant latent ambiguity that seems tricky and risky to
resolve without introducing two new macros, one for each independent meaning. 
(there are tests in g++.dg and libstdc++ testsuites that use it in one meaning
or the other)

Without SUPPORTS_ONE_ONLY, despite the availability of weak symbols, and
regardless of arranging for flag_weak to remain enabled, some symbols with
vague linkage fail to be output.  I have not investigated further, but one
example of simple test that fails in this configuration is g++.dg/abi/vtt1.C.

So the attached patch, though fixing some latent problems and not introducing
any to comdat-enabled C++, doesn't go all the way in making a comdat-less C++
compiler possible, so I'm not planning on submitting it for inclusion at this
point.  However, since I don't have plans to pursue this further, I hereby
contribute it as a starting point for anyone who might be interested in taking
it towards completion.

Reply via email to