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

Jakub Jelinek <jakub at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |jakub at gcc dot gnu.org

--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
(In reply to Jonathan Wakely from comment #2)
> Maybe we need to make the definitions in the library weak

Does MinGW support weak at all?

I think this boils down to:
a.h:
struct bad_alloc {
#if __cplusplus >= 202400L
  constexpr virtual ~bad_alloc() noexcept {}
  constexpr virtual const char* what() const noexcept { return
"std::bad_alloc"; }
#else
  virtual ~bad_alloc() throw();
  virtual const char* what() const throw();
#endif
};
a.C:
#include "a.h"
void
foo ()
{
  throw bad_alloc ();
}
b.C:
#include "a.h"
bad_alloc::~bad_alloc() throw () { }

const char*
bad_alloc::what() const throw ()
{
  return "std::bad_alloc";
}
g++ -c -std=c++26 a.C
g++ -c -std=c++98 b.C
Seems nothing here is weak on MinGW, but for inline functions there is
        .section        .text$_ZN9bad_allocD1Ev,"x"
        .linkonce discard
and
        .section        .text$_ZNK9bad_alloc4whatEv,"x"
        .linkonce discard
etc. extra (how does that work across multiple shared libraries no idea).
What seems to help I think is mark the out of line definitions in b.C inline:
#include "a.h"
inline bad_alloc::~bad_alloc() throw () { }

inline const char*
bad_alloc::what() const throw ()
{
  return "std::bad_alloc";
}
Except that one of those is a key method, and
  /* The key method is the first non-pure virtual function that is not
     inline at the point of class definition.  On some targets the
     key function may not be inline; those targets should not call
     this function until the end of the translation unit.  */
and
/* The EABI says that an inline function may never be the key
   method.  */

static bool
arm_cxx_key_method_may_be_inline (void)
{
  return !TARGET_AAPCS_BASED;
}
with the hook_bool_void_true default for all non-ARM targets.
Though, hopefully on the other side arm TARGET_AAPCS_BASED is ELF and supports
weak.

On the other side I see
/* GNU as supports weak symbols on PECOFF. */
#ifdef HAVE_GAS_WEAK
#define ASM_WEAKEN_LABEL(FILE, NAME)  \
  do                                  \
    {                                 \
      fputs ("\t.weak\t", (FILE));    \
      assemble_name ((FILE), (NAME)); \
      fputc ('\n', (FILE));           \
    }                                 \
  while (0)
for MinGW, so maybe it sometimes does support that, but there are targets which
don't support it.
Unfortunately, __GXX_WEAK__ macro is not whether [[gnu::weak]] can be
successfully used on function definition, but weather it is a SUPPORTS_ONE_ONLY
target (i.e. has the linkonce support in some way).
So, maybe we need a new macro which will be defined to inline for MinGW and
perhaps some other targets and nothing by default and use it in bad_alloc.cc
etc.?

Reply via email to