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.