The constructor for an immediately-owned unique_lock initializes the
ownership flag to false and then calls the checked lock() modifier,
which sets the flag to true.  The constructor then sets it to true
again.  The destructor similarly calls the checked unlock() modifier
after already testing ownership.

Match the implementation pattern used by shared_lock: construct the
object directly in its final ownership state, call the mutex operations
directly during construction and destruction, and remove unlock()'s
redundant mutex pointer check after ownership has been established.
Assert that an owned unique_lock or shared_lock retains a non-null mutex
before dereferencing it.  This avoids duplicated checks and exception
paths without changing the behavior of a correct program, while
assertion-enabled builds diagnose a broken lock invariant.

No new test is needed because no supported operation can produce the
invalid state checked by the assertions.  The existing tests cover
construction, destruction, explicit unlocking, and
condition_variable_any waits.

Tested on x86_64-pc-linux-gnu with no regressions.

libstdc++-v3/ChangeLog:

        * include/bits/unique_lock.h (unique_lock::unique_lock): Construct
        directly in the owned state and call the mutex directly.
        (unique_lock::~unique_lock): Assert the mutex pointer is non-null and
        unlock the mutex directly.
        (unique_lock::unlock): Replace the redundant runtime mutex pointer
        check with an assertion.
        * include/std/shared_mutex (shared_lock::~shared_lock): Assert the
        mutex pointer is non-null before unlocking it.
        (shared_lock::unlock): Likewise.

Assisted-by: OpenAI Codex

Changes since v1:
- Assert mutex pointers before dereferencing them in unique_lock.
- Add the corresponding invariant assertions to shared_lock.
---
 libstdc++-v3/include/bits/unique_lock.h | 20 +++++++++-----------
 libstdc++-v3/include/std/shared_mutex   |  6 +++++-
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/libstdc++-v3/include/bits/unique_lock.h 
b/libstdc++-v3/include/bits/unique_lock.h
index 51596ef31..ffda18dd6 100644
--- a/libstdc++-v3/include/bits/unique_lock.h
+++ b/libstdc++-v3/include/bits/unique_lock.h
@@ -70,11 +70,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       [[__nodiscard__]]
       explicit unique_lock(mutex_type& __m)
-      : _M_device(std::__addressof(__m)), _M_owns(false)
-      {
-       lock();
-       _M_owns = true;
-      }
+      : _M_device(std::__addressof(__m)), _M_owns(true)
+      { __m.lock(); }
 
       unique_lock(mutex_type& __m, defer_lock_t) noexcept
       : _M_device(std::__addressof(__m)), _M_owns(false)
@@ -111,7 +108,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       ~unique_lock()
       {
        if (_M_owns)
-         unlock();
+         {
+           __glibcxx_assert(_M_device);
+           _M_device->unlock();
+         }
       }
 
       unique_lock(const unique_lock&) = delete;
@@ -198,11 +198,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
        if (!_M_owns)
          __throw_system_error(int(errc::operation_not_permitted));
-       else if (_M_device)
-         {
-           _M_device->unlock();
-           _M_owns = false;
-         }
+       __glibcxx_assert(_M_device);
+       _M_device->unlock();
+       _M_owns = false;
       }
 
       void
diff --git a/libstdc++-v3/include/std/shared_mutex 
b/libstdc++-v3/include/std/shared_mutex
index 1bc949515..57a5796a1 100644
--- a/libstdc++-v3/include/std/shared_mutex
+++ b/libstdc++-v3/include/std/shared_mutex
@@ -743,7 +743,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       ~shared_lock()
       {
        if (_M_owns)
-         _M_pm->unlock_shared();
+         {
+           __glibcxx_assert(_M_pm);
+           _M_pm->unlock_shared();
+         }
       }
 
       shared_lock(shared_lock const&) = delete;
@@ -800,6 +803,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
        if (!_M_owns)
          __throw_system_error(int(errc::operation_not_permitted));
+       __glibcxx_assert(_M_pm);
        _M_pm->unlock_shared();
        _M_owns = false;
       }
-- 
2.43.0


Reply via email to