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.