> From: Jonathan Wakely <[email protected]>
> Sent: 12 November 2026 20:24
> And this does the same. Again, this should be fine in a correct program, but 
> it
> could change the behaviour for a program which has somehow broken the
> unique_lock invariants. The technically redundant check for _M_device avoids
> a segfault, or optimizations that assume _M_device must be non-null because
> it's dereferenced.
> 
> How much would it hurt the codegen to do `if (!_M_owns || !_M_device)` in
> the condition for the throwing path?
> 
> And similarly, check `if (_M_owns && _M_device)` in the destructor.
> 
> Or just add __glibcxx_assert(_M_device) immediately before the
> _M_device->unlock() calls.

I compared the alternatives with ARM GCC trunk at -Os.

Combining _M_owns and _M_device in the runtime condition retains an
extra branch in the optimized unlock() path. The destructor check is
optimized away in the simple construction/destruction case, although that
will not necessarily be true when the object’s state is not locally known.

Adding __glibcxx_assert(_M_device) seems like the best compromise, so
I’ll revise the patch to use assertions.

shared_lock already relies on the equivalent invariant that _M_owns
implies _M_pm is non-null. Would you be happy for me to add
__glibcxx_assert(_M_pm) immediately before the dereferences in its
destructor and unlock() as well?

Reply via email to