> 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?
