[libcxx-commits] [libcxx] 5e807c3 - [libc++] add basic runtime assertions to <latch>

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Wed Jul 5 14:35:19 PDT 2023


Author: Edoardo Sanguineti
Date: 2023-07-05T17:34:23-04:00
New Revision: 5e807c38bf9b5c1528012ec9003953b352f99c79

URL: https://github.com/llvm/llvm-project/commit/5e807c38bf9b5c1528012ec9003953b352f99c79
DIFF: https://github.com/llvm/llvm-project/commit/5e807c38bf9b5c1528012ec9003953b352f99c79.diff

LOG: [libc++] add basic runtime assertions to <latch>

Adding assertions will aid users that have bugs in their code to
receive better error messages.

Differential Revision: https://reviews.llvm.org/D154425

Added: 
    libcxx/test/libcxx/thread/thread.latch/assert.arrive_and_wait.pass.cpp
    libcxx/test/libcxx/thread/thread.latch/assert.count_down.pass.cpp
    libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp

Modified: 
    libcxx/include/latch

Removed: 
    


################################################################################
diff  --git a/libcxx/include/latch b/libcxx/include/latch
index cb3366663f21f3..47538060eeca78 100644
--- a/libcxx/include/latch
+++ b/libcxx/include/latch
@@ -75,7 +75,15 @@ public:
     }
 
     inline _LIBCPP_INLINE_VISIBILITY
-    constexpr explicit latch(ptr
diff _t __expected) : __a_(__expected) { }
+    constexpr explicit latch(ptr
diff _t __expected) : __a_(__expected)
+    {
+        _LIBCPP_ASSERT_UNCATEGORIZED(__expected >= 0,
+                                     "latch::latch(ptr
diff _t): latch cannot be "
+                                     "initialized with a negative value");
+        _LIBCPP_ASSERT_UNCATEGORIZED(__expected <= max(),
+                                     "latch::latch(ptr
diff _t): latch cannot be "
+                                     "initialized with a value greater than max()");
+    }
 
     _LIBCPP_HIDE_FROM_ABI ~latch() = default;
     latch(const latch&) = delete;
@@ -84,8 +92,13 @@ public:
     inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
     void count_down(ptr
diff _t __update = 1)
     {
+        _LIBCPP_ASSERT_UNCATEGORIZED(
+            __update >= 0, "latch::count_down called with a negative value");
         auto const __old = __a_.fetch_sub(__update, memory_order_release);
-        if(__old == __update)
+        _LIBCPP_ASSERT_UNCATEGORIZED(
+            __update <= __old, "latch::count_down called with a value greater "
+                               "than the internal counter");
+        if (__old == __update)
             __a_.notify_all();
     }
     inline _LIBCPP_INLINE_VISIBILITY
@@ -103,6 +116,10 @@ public:
     inline _LIBCPP_AVAILABILITY_SYNC _LIBCPP_INLINE_VISIBILITY
     void arrive_and_wait(ptr
diff _t __update = 1)
     {
+        _LIBCPP_ASSERT_UNCATEGORIZED(
+            __update >= 0, "latch::arrive_and_wait called with a negative value");
+        // other preconditions on __update are checked in count_down()
+
         count_down(__update);
         wait();
     }

diff  --git a/libcxx/test/libcxx/thread/thread.latch/assert.arrive_and_wait.pass.cpp b/libcxx/test/libcxx/thread/thread.latch/assert.arrive_and_wait.pass.cpp
new file mode 100644
index 00000000000000..d00540cb9cdab7
--- /dev/null
+++ b/libcxx/test/libcxx/thread/thread.latch/assert.arrive_and_wait.pass.cpp
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <latch>
+
+// class latch;
+
+// void arrive_and_wait(ptr
diff _t __update = 1);
+
+// Make sure that calling arrive_and_wait with a negative value triggers an assertion.
+
+// REQUIRES: has-unix-headers
+// XFAIL: availability-verbose_abort-missing
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
+
+#include <latch>
+
+#include "check_assertion.h"
+
+int main(int, char **) {
+  {
+    std::latch l(5);
+
+    TEST_LIBCPP_ASSERT_FAILURE(
+        l.arrive_and_wait(-10),
+        "latch::arrive_and_wait called with a negative value");
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/libcxx/thread/thread.latch/assert.count_down.pass.cpp b/libcxx/test/libcxx/thread/thread.latch/assert.count_down.pass.cpp
new file mode 100644
index 00000000000000..abd16017983eb4
--- /dev/null
+++ b/libcxx/test/libcxx/thread/thread.latch/assert.count_down.pass.cpp
@@ -0,0 +1,45 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <latch>
+
+// class latch;
+
+// void count_down(ptr
diff _t __update = 1);
+
+// Make sure that calling count_down with a negative value or a value
+// higher than the internal counter triggers an assertion.
+
+// REQUIRES: has-unix-headers
+// XFAIL: availability-verbose_abort-missing
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
+
+#include <latch>
+
+#include "check_assertion.h"
+
+int main(int, char **) {
+  {
+    std::latch l(5);
+
+    TEST_LIBCPP_ASSERT_FAILURE(
+        l.count_down(-10), "latch::count_down called with a negative value");
+  }
+
+  {
+    std::latch l(5);
+
+    TEST_LIBCPP_ASSERT_FAILURE(l.count_down(10),
+                               "latch::count_down called with a value greater "
+                               "than the internal counter");
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp b/libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp
new file mode 100644
index 00000000000000..dbd582f6e36d87
--- /dev/null
+++ b/libcxx/test/libcxx/thread/thread.latch/assert.ctor.pass.cpp
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+// UNSUPPORTED: no-threads
+// UNSUPPORTED: c++03, c++11, c++14, c++17
+
+// <latch>
+
+// class latch;
+
+// constexpr explicit latch(ptr
diff _t __expected);
+
+// Make sure that calling latch with a negative value triggers an assertion
+
+// REQUIRES: has-unix-headers
+// XFAIL: availability-verbose_abort-missing
+// ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_ENABLE_ASSERTIONS=1
+
+#include <latch>
+
+#include "check_assertion.h"
+
+int main(int, char **) {
+  {
+    TEST_LIBCPP_ASSERT_FAILURE([]{ std::latch l(-1); }(),
+                               "latch::latch(ptr
diff _t): latch cannot be "
+                               "initialized with a negative value");
+  }
+
+  // We can't check the precondition for max() because there's no value
+  // that would violate the precondition (in our implementation)
+
+  return 0;
+}


        


More information about the libcxx-commits mailing list