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

Andrew Pinski <pinskia at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|---                         |INVALID

--- Comment #1 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
It is easier to understand the code this way:
  <bb 2>:
  _1 = __atomic_load_1 (&_ZGVZ4testvE1x, 2);
  _2 = (int) _1;
  _3 = _2 & 1;
  retval.0_8 = _3 == 0;
  if (retval.0_8 != 0)
    goto <bb 3>;
  else
    goto <bb 5>;

  <bb 3>:
  _4 = __cxa_guard_acquire (&_ZGVZ4testvE1x);
  retval.1_10 = _4 != 0;
  if (retval.1_10 != 0)
    goto <bb 4>;
  else
    goto <bb 5>;

  <bb 4>:
  _11 = 0;
  std::__cxx11::basic_string<char>::basic_string (&x);
  _13 = 1;
  __cxa_guard_release (&_ZGVZ4testvE1x);
  __cxa_atexit (__comp_dtor , &x, &__dso_handle);


---- CUT ----

So if the variable was initialized, __cxa_atexit is never called.

__cxa_guard_acquire is not exactly a lock.  it is rather a check to see if the
variable has been initialized, if not then see if someone is initializing it
right now.  If someone is  initializing, then wait for the initializing to be
finished before return.
Return nonzero if this thread is going to be the thread which initializes the
variable.

So the cxa_atexit is done after the release which is fine as if someone decides
to do exit right after the __cxa_guard_acquire on another thread, you might
leak some memory but the decl will never be destructed multiple times.

Reply via email to