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

--- Comment #11 from Jonathan Wakely <redi at gcc dot gnu.org> ---
Reduced:

extern "C" int puts(const char*);

struct A
{
  constexpr A()  { }
  ~A() { puts("bye"); }
};

namespace
{
  struct constant_init
  {
    union {
      A obj;
    };
    constexpr constant_init() : obj() { }

    ~constant_init() { /* do nothing, union member is not destroyed */ }
  };


  // Single-threaded fallback buffer.
  constinit constant_init global;
}

extern "C" A* get() { return &global.obj; }

With -std=c++20 -Os GCC emits a call to atexit:

(anonymous namespace)::constant_init::~constant_init() [base object
destructor]:
        ret
get:
        mov     eax, OFFSET FLAT:_ZN12_GLOBAL__N_16globalE
        ret
_GLOBAL__sub_I_get:
        mov     edx, OFFSET FLAT:__dso_handle
        mov     esi, OFFSET FLAT:_ZN12_GLOBAL__N_16globalE
        mov     edi, OFFSET FLAT:_ZN12_GLOBAL__N_113constant_initD1Ev
        jmp     __cxa_atexit


With the same options, Clang doesn't:

get:                                    # @get
        lea     rax, [rip + (anonymous namespace)::global]
        ret

Reply via email to