[libcxx-commits] [libcxx] e280407 - [libc++] Add test coverage for our implementation of LWG4031 (#87508)

via libcxx-commits libcxx-commits at lists.llvm.org
Tue Apr 9 08:27:43 PDT 2024


Author: Louis Dionne
Date: 2024-04-09T11:27:40-04:00
New Revision: e280407a4865542c4bb6cfa148edbe1ea67023d6

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

LOG: [libc++] Add test coverage for our implementation of LWG4031 (#87508)

This was actually already implemented in the initial version of
std::expected, but this patch adds test coverage and makes it more
explicit that we intend to make these functions noexcept.

Added: 
    libcxx/test/std/utilities/expected/expected.bad/base.compile.pass.cpp
    libcxx/test/std/utilities/expected/expected.bad/void-specialization.pass.cpp
    libcxx/test/std/utilities/expected/expected.bad/what.pass.cpp

Modified: 
    libcxx/docs/Status/Cxx2cIssues.csv
    libcxx/include/__expected/bad_expected_access.h

Removed: 
    libcxx/test/std/utilities/expected/expected.bad/what.noexcept.compile.pass.cpp


################################################################################
diff  --git a/libcxx/docs/Status/Cxx2cIssues.csv b/libcxx/docs/Status/Cxx2cIssues.csv
index 8a4bf2ef62162a..b402fb835bc19f 100644
--- a/libcxx/docs/Status/Cxx2cIssues.csv
+++ b/libcxx/docs/Status/Cxx2cIssues.csv
@@ -52,7 +52,7 @@
 "`4023 <https://wg21.link/LWG4023>`__","Preconditions of ``std::basic_streambuf::setg/setp``","Tokyo March 2024","","",""
 "`4025 <https://wg21.link/LWG4025>`__","Move assignment operator of ``std::expected<cv void, E>`` should not be conditionally deleted","Tokyo March 2024","","",""
 "`4030 <https://wg21.link/LWG4030>`__","Clarify whether arithmetic expressions in ``[numeric.sat.func]`` are mathematical or C++","Tokyo March 2024","|Nothing To Do|","",""
-"`4031 <https://wg21.link/LWG4031>`__","``bad_expected_access<void>`` member functions should be ``noexcept``","Tokyo March 2024","","",""
+"`4031 <https://wg21.link/LWG4031>`__","``bad_expected_access<void>`` member functions should be ``noexcept``","Tokyo March 2024","|Complete|","16.0",""
 "`4035 <https://wg21.link/LWG4035>`__","``single_view`` should provide ``empty``","Tokyo March 2024","","","|ranges|"
 "`4036 <https://wg21.link/LWG4036>`__","``__alignof_is_defined`` is only implicitly specified in C++ and not yet deprecated","Tokyo March 2024","","",""
 "`4037 <https://wg21.link/LWG4037>`__","Static data members of ``ctype_base`` are not yet required to be usable in constant expressions","Tokyo March 2024","","",""

diff  --git a/libcxx/include/__expected/bad_expected_access.h b/libcxx/include/__expected/bad_expected_access.h
index 585b4ec9a053bb..9d490307b68081 100644
--- a/libcxx/include/__expected/bad_expected_access.h
+++ b/libcxx/include/__expected/bad_expected_access.h
@@ -32,12 +32,12 @@ _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wweak-vtables")
 template <>
 class bad_expected_access<void> : public exception {
 protected:
-  _LIBCPP_HIDE_FROM_ABI bad_expected_access() noexcept                             = default;
-  _LIBCPP_HIDE_FROM_ABI bad_expected_access(const bad_expected_access&)            = default;
-  _LIBCPP_HIDE_FROM_ABI bad_expected_access(bad_expected_access&&)                 = default;
-  _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(const bad_expected_access&) = default;
-  _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(bad_expected_access&&)      = default;
-  _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_expected_access() override                    = default;
+  _LIBCPP_HIDE_FROM_ABI bad_expected_access() noexcept                                      = default;
+  _LIBCPP_HIDE_FROM_ABI bad_expected_access(const bad_expected_access&) noexcept            = default;
+  _LIBCPP_HIDE_FROM_ABI bad_expected_access(bad_expected_access&&) noexcept                 = default;
+  _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(const bad_expected_access&) noexcept = default;
+  _LIBCPP_HIDE_FROM_ABI bad_expected_access& operator=(bad_expected_access&&) noexcept      = default;
+  _LIBCPP_HIDE_FROM_ABI_VIRTUAL ~bad_expected_access() override                             = default;
 
 public:
   // The way this has been designed (by using a class template below) means that we'll already

diff  --git a/libcxx/test/std/utilities/expected/expected.bad/what.noexcept.compile.pass.cpp b/libcxx/test/std/utilities/expected/expected.bad/base.compile.pass.cpp
similarity index 56%
rename from libcxx/test/std/utilities/expected/expected.bad/what.noexcept.compile.pass.cpp
rename to libcxx/test/std/utilities/expected/expected.bad/base.compile.pass.cpp
index e6d050b2129d62..545215a3b16130 100644
--- a/libcxx/test/std/utilities/expected/expected.bad/what.noexcept.compile.pass.cpp
+++ b/libcxx/test/std/utilities/expected/expected.bad/base.compile.pass.cpp
@@ -7,19 +7,12 @@
 
 // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
 
-// const char* what() const noexcept override;
+// Make sure std::bad_expected_access<E> inherits from std::bad_expected_access<void>.
 
 #include <expected>
-#include <utility>
+#include <type_traits>
 
-template <class T>
-concept WhatNoexcept =
-    requires(const T& t) {
-      { t.what() } noexcept;
-    };
+struct Foo {};
 
-struct foo{};
-
-static_assert(!WhatNoexcept<foo>);
-static_assert(WhatNoexcept<std::bad_expected_access<int>>);
-static_assert(WhatNoexcept<std::bad_expected_access<foo>>);
+static_assert(std::is_base_of_v<std::bad_expected_access<void>, std::bad_expected_access<int>>);
+static_assert(std::is_base_of_v<std::bad_expected_access<void>, std::bad_expected_access<Foo>>);

diff  --git a/libcxx/test/std/utilities/expected/expected.bad/void-specialization.pass.cpp b/libcxx/test/std/utilities/expected/expected.bad/void-specialization.pass.cpp
new file mode 100644
index 00000000000000..092e1153103c85
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.bad/void-specialization.pass.cpp
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+// 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: c++03, c++11, c++14, c++17, c++20
+
+// template<>
+// class bad_expected_access<void> : public exception {
+// protected:
+//   bad_expected_access() noexcept;
+//   bad_expected_access(const bad_expected_access&) noexcept;
+//   bad_expected_access(bad_expected_access&&) noexcept;
+//   bad_expected_access& operator=(const bad_expected_access&) noexcept;
+//   bad_expected_access& operator=(bad_expected_access&&) noexcept;
+//   ~bad_expected_access();
+//
+// public:
+//   const char* what() const noexcept override;
+// };
+
+#include <cassert>
+#include <exception>
+#include <expected>
+#include <type_traits>
+#include <utility>
+
+#include "test_macros.h"
+
+struct Inherit : std::bad_expected_access<void> {};
+
+int main(int, char**) {
+  // base class
+  static_assert(std::is_base_of_v<std::exception, std::bad_expected_access<void>>);
+
+  // default constructor
+  {
+    Inherit exc;
+    ASSERT_NOEXCEPT(Inherit());
+  }
+
+  // copy constructor
+  {
+    Inherit exc;
+    Inherit copy(exc);
+    ASSERT_NOEXCEPT(Inherit(exc));
+  }
+
+  // move constructor
+  {
+    Inherit exc;
+    Inherit copy(std::move(exc));
+    ASSERT_NOEXCEPT(Inherit(std::move(exc)));
+  }
+
+  // copy assignment
+  {
+    Inherit exc;
+    Inherit copy;
+    [[maybe_unused]] Inherit& result = (copy = exc);
+    ASSERT_NOEXCEPT(copy = exc);
+  }
+
+  // move assignment
+  {
+    Inherit exc;
+    Inherit copy;
+    [[maybe_unused]] Inherit& result = (copy = std::move(exc));
+    ASSERT_NOEXCEPT(copy = std::move(exc));
+  }
+
+  // what()
+  {
+    Inherit exc;
+    char const* what = exc.what();
+    assert(what != nullptr);
+    ASSERT_NOEXCEPT(exc.what());
+  }
+
+  return 0;
+}

diff  --git a/libcxx/test/std/utilities/expected/expected.bad/what.pass.cpp b/libcxx/test/std/utilities/expected/expected.bad/what.pass.cpp
new file mode 100644
index 00000000000000..bc5e356161a740
--- /dev/null
+++ b/libcxx/test/std/utilities/expected/expected.bad/what.pass.cpp
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+// 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: c++03, c++11, c++14, c++17, c++20
+
+// const char* what() const noexcept override;
+
+#include <expected>
+#include <cassert>
+#include <utility>
+
+#include "test_macros.h"
+
+struct Foo {};
+
+int main(int, char**) {
+  {
+    std::bad_expected_access<int> const exc(99);
+    char const* what = exc.what();
+    assert(what != nullptr);
+    ASSERT_NOEXCEPT(exc.what());
+  }
+  {
+    std::bad_expected_access<Foo> const exc(Foo{});
+    char const* what = exc.what();
+    assert(what != nullptr);
+    ASSERT_NOEXCEPT(exc.what());
+  }
+
+  return 0;
+}


        


More information about the libcxx-commits mailing list