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

Jonathan Wakely <redi at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|WAITING                     |ASSIGNED
           Assignee|unassigned at gcc dot gnu.org      |hp at gcc dot gnu.org

--- Comment #30 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to Hans-Peter Nilsson from comment #26)
> I went by the documentation, which says at r264855 for __atomic_is_lock_free
> that "If the built-in function is not known to be lock-free, a call is made
> to a runtime routine named @code{__atomic_is_lock_free}."  It certainly
> seems to be that way too (builtins.c):
> 
> static tree
> fold_builtin_atomic_is_lock_free (tree arg0, tree arg1)
> {
>   if (!flag_inline_atomics)
>     return NULL_TREE;
>   
>   /* If it isn't always lock free, don't generate a result.  */
>   if (fold_builtin_atomic_always_lock_free (arg0, arg1) == boolean_true_node)
>     return boolean_true_node;
> 
>   return NULL_TREE;
> }
> 
> ISTM that this will not "inline" a return of "false".

Indeed. This fails to link without -latomic:

#include <atomic>

struct X {
  alignas(64) char x;
};

int main()
{
  std::atomic<X> ax;
  return ax.is_lock_free();
}

So even if the call in libatomic would give the right answer, depending on
libatomic is unnecessary. The result should be the same as
ax.is_always_lock_free which is a constant.

So let's go with your patch to <bits/atomic_base.h> to change to:

        return __atomic_always_lock_free(sizeof(_M_i),
            reinterpret_cast<void *>(-_S_alignment));

Please also add some tests to the libstdc++ testsuite confirming that
a.is_lock_free() is consistent with a.is_always_lock_free for a variety of
types with different sizes and alignments.

Reply via email to