Implement LWG 3013 - some filesystem members should not be noexcept.
authorEric Fiselier <eric@efcs.ca>
Mon, 30 Oct 2017 18:59:59 +0000 (18:59 +0000)
committerEric Fiselier <eric@efcs.ca>
Mon, 30 Oct 2017 18:59:59 +0000 (18:59 +0000)
LWG 3013 points out that the constructors and increment members
of the directory iterators need to allocate, and therefore cannot
be marked noexcept.

It also points out that `is_empty` and `copy` likely need to allocate
as well, and as such can also not be noexcept.

This patch speculatively implements the resolution removing noexcept,
because libc++ does indeed have the possibility of throwing on allocation
failure.

llvm-svn: 316941

libcxx/include/experimental/filesystem
libcxx/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/ctor.pass.cpp
libcxx/test/std/experimental/filesystem/class.directory_iterator/directory_iterator.members/increment.pass.cpp
libcxx/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp
libcxx/test/std/experimental/filesystem/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp
libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy/copy.pass.cpp
libcxx/test/std/experimental/filesystem/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp

index 42157ba..747f62f 100644 (file)
     path canonical(const path& p, const path& base, error_code& ec);
 
     void copy(const path& from, const path& to);
-    void copy(const path& from, const path& to, error_code& ec) _NOEXCEPT;
+    void copy(const path& from, const path& to, error_code& ec);
     void copy(const path& from, const path& to, copy_options options);
     void copy(const path& from, const path& to, copy_options options,
-                   error_code& ec) _NOEXCEPT;
+                   error_code& ec);
 
     bool copy_file(const path& from, const path& to);
     bool copy_file(const path& from, const path& to, error_code& ec) _NOEXCEPT;
@@ -1351,7 +1351,7 @@ void copy(const path& __from, const path& __to) {
 }
 
 inline _LIBCPP_INLINE_VISIBILITY
-void copy(const path& __from, const path& __to, error_code& __ec) _NOEXCEPT {
+void copy(const path& __from, const path& __to, error_code& __ec) {
     __copy(__from, __to, copy_options::none, &__ec);
 }
 
@@ -1362,7 +1362,7 @@ void copy(const path& __from, const path& __to, copy_options __opt) {
 
 inline _LIBCPP_INLINE_VISIBILITY
 void copy(const path& __from, const path& __to,
-          copy_options __opt, error_code& __ec) _NOEXCEPT {
+          copy_options __opt, error_code& __ec) {
     __copy(__from, __to, __opt, &__ec);
 }
 
@@ -1561,7 +1561,7 @@ bool is_empty(const path& __p) {
 }
 
 inline _LIBCPP_INLINE_VISIBILITY
-bool is_empty(const path& __p, error_code& __ec) _NOEXCEPT {
+bool is_empty(const path& __p, error_code& __ec) {
     return __fs_is_empty(__p, &__ec);
 }
 
@@ -1903,12 +1903,12 @@ public:
         : directory_iterator(__p, nullptr, __opts)
     { }
 
-    directory_iterator(const path& __p, error_code& __ec) _NOEXCEPT
+    directory_iterator(const path& __p, error_code& __ec)
         : directory_iterator(__p, &__ec)
     { }
 
     directory_iterator(const path& __p, directory_options __opts,
-                       error_code& __ec) _NOEXCEPT
+                       error_code& __ec)
         : directory_iterator(__p, &__ec, __opts)
     { }
 
@@ -1943,7 +1943,7 @@ public:
         return __p;
     }
 
-    directory_iterator& increment(error_code& __ec) _NOEXCEPT
+    directory_iterator& increment(error_code& __ec)
     { return __increment(&__ec); }
 
 private:
@@ -2013,12 +2013,12 @@ public:
 
     _LIBCPP_INLINE_VISIBILITY
     recursive_directory_iterator(const path& __p,
-        directory_options __xoptions, error_code& __ec) _NOEXCEPT
+        directory_options __xoptions, error_code& __ec)
         : recursive_directory_iterator(__p, __xoptions, &__ec)
     { }
 
     _LIBCPP_INLINE_VISIBILITY
-    recursive_directory_iterator(const path& __p, error_code& __ec) _NOEXCEPT
+    recursive_directory_iterator(const path& __p, error_code& __ec)
         : recursive_directory_iterator(__p, directory_options::none,  &__ec)
     { }
 
@@ -2060,7 +2060,7 @@ public:
     }
 
     _LIBCPP_INLINE_VISIBILITY
-    recursive_directory_iterator& increment(error_code& __ec) _NOEXCEPT
+    recursive_directory_iterator& increment(error_code& __ec)
     { return __increment(&__ec); }
 
     _LIBCPP_FUNC_VIS directory_options options() const;
index 830e812..4fd6088 100644 (file)
@@ -15,8 +15,8 @@
 
 // explicit directory_iterator(const path& p);
 // directory_iterator(const path& p, directory_options options);
-// directory_iterator(const path& p, error_code& ec) noexcept;
-// directory_iterator(const path& p, directory_options options, error_code& ec) noexcept;
+// directory_iterator(const path& p, error_code& ec);
+// directory_iterator(const path& p, directory_options options, error_code& ec);
 
 #include <experimental/filesystem>
 #include <type_traits>
@@ -40,15 +40,22 @@ TEST_CASE(test_constructor_signatures)
     static_assert(std::is_constructible<D, path>::value, "");
     static_assert(!std::is_nothrow_constructible<D, path>::value, "");
 
-    // directory_iterator(path const&, error_code&) noexcept
-    static_assert(std::is_nothrow_constructible<D, path, std::error_code&>::value, "");
+    // directory_iterator(path const&, error_code&)
+    static_assert(std::is_constructible<D, path,
+        std::error_code&>::value, "");
+    static_assert(!std::is_nothrow_constructible<D, path,
+        std::error_code&>::value, "");
 
     // directory_iterator(path const&, directory_options);
     static_assert(std::is_constructible<D, path, directory_options>::value, "");
     static_assert(!std::is_nothrow_constructible<D, path, directory_options>::value, "");
 
-    // directory_iterator(path const&, directory_options, error_code&) noexcept
-    static_assert(std::is_nothrow_constructible<D, path, directory_options, std::error_code&>::value, "");
+    // directory_iterator(path const&, directory_options, error_code&)
+    static_assert(std::is_constructible<D, path, directory_options,
+        std::error_code&>::value, "");
+    static_assert(!std::is_nothrow_constructible<D, path, directory_options,
+        std::error_code&>::value, "");
+
 }
 
 TEST_CASE(test_construction_from_bad_path)
index 589b4ec..8d88871 100644 (file)
@@ -14,7 +14,7 @@
 // class directory_iterator
 
 // directory_iterator& operator++();
-// directory_iterator& increment(error_code& ec) noexcept;
+// directory_iterator& increment(error_code& ec);
 
 #include <experimental/filesystem>
 #include <type_traits>
@@ -40,7 +40,7 @@ TEST_CASE(test_increment_signatures)
     ASSERT_NOT_NOEXCEPT(++d);
 
     ASSERT_SAME_TYPE(decltype(d.increment(ec)), directory_iterator&);
-    ASSERT_NOEXCEPT(d.increment(ec));
+    ASSERT_NOT_NOEXCEPT(d.increment(ec));
 }
 
 TEST_CASE(test_prefix_increment)
index 8f6009d..1469dae 100644 (file)
@@ -16,8 +16,8 @@
 //
 // explicit recursive_directory_iterator(const path& p);
 // recursive_directory_iterator(const path& p, directory_options options);
-// recursive_directory_iterator(const path& p, error_code& ec) noexcept;
-// recursive_directory_iterator(const path& p, directory_options options, error_code& ec) noexcept;
+// recursive_directory_iterator(const path& p, error_code& ec);
+// recursive_directory_iterator(const path& p, directory_options options, error_code& ec);
 
 
 #include <experimental/filesystem>
@@ -44,15 +44,19 @@ TEST_CASE(test_constructor_signatures)
     static_assert(std::is_constructible<D, path>::value, "");
     static_assert(!std::is_nothrow_constructible<D, path>::value, "");
 
-    // directory_iterator(path const&, error_code&) noexcept
-    static_assert(std::is_nothrow_constructible<D, path, std::error_code&>::value, "");
+    // directory_iterator(path const&, error_code&)
+    static_assert(std::is_constructible<D, path,
+        std::error_code&>::value, "");
+    static_assert(!std::is_nothrow_constructible<D, path,
+        std::error_code&>::value, "");
 
     // directory_iterator(path const&, directory_options);
     static_assert(std::is_constructible<D, path, directory_options>::value, "");
     static_assert(!std::is_nothrow_constructible<D, path, directory_options>::value, "");
 
-    // directory_iterator(path const&, directory_options, error_code&) noexcept
-    static_assert(std::is_nothrow_constructible<D, path, directory_options, std::error_code&>::value, "");
+    // directory_iterator(path const&, directory_options, error_code&)
+    static_assert(std::is_constructible<D, path, directory_options, std::error_code&>::value, "");
+    static_assert(!std::is_nothrow_constructible<D, path, directory_options, std::error_code&>::value, "");
 }
 
 TEST_CASE(test_construction_from_bad_path)
index e91bd50..ea81ee2 100644 (file)
@@ -40,7 +40,7 @@ TEST_CASE(test_increment_signatures)
     ASSERT_NOT_NOEXCEPT(++d);
 
     ASSERT_SAME_TYPE(decltype(d.increment(ec)), recursive_directory_iterator&);
-    ASSERT_NOEXCEPT(d.increment(ec));
+    ASSERT_NOT_NOEXCEPT(d.increment(ec));
 }
 
 TEST_CASE(test_prefix_increment)
index c9b42b3..8f44e0d 100644 (file)
 // <experimental/filesystem>
 
 // void copy(const path& from, const path& to);
-// void copy(const path& from, const path& to, error_code& ec) noexcept;
+// void copy(const path& from, const path& to, error_code& ec);
 // void copy(const path& from, const path& to, copy_options options);
 // void copy(const path& from, const path& to, copy_options options,
-//           error_code& ec) noexcept;
+//           error_code& ec);
 
 #include <experimental/filesystem>
 #include <type_traits>
@@ -39,9 +39,9 @@ TEST_CASE(signature_test)
     std::error_code ec; ((void)ec);
     const copy_options opts{}; ((void)opts);
     ASSERT_NOT_NOEXCEPT(fs::copy(p, p));
-    ASSERT_NOEXCEPT(fs::copy(p, p, ec));
+    ASSERT_NOT_NOEXCEPT(fs::copy(p, p, ec));
     ASSERT_NOT_NOEXCEPT(copy(p, p, opts));
-    ASSERT_NOEXCEPT(copy(p, p, opts, ec));
+    ASSERT_NOT_NOEXCEPT(copy(p, p, opts, ec));
 }
 
 // There are 4 cases is the proposal for absolute path.
index bc62086..2da163c 100644 (file)
@@ -12,7 +12,7 @@
 // <experimental/filesystem>
 
 // bool is_empty(path const& p);
-// bool is_empty(path const& p, std::error_code& ec) noexcept;
+// bool is_empty(path const& p, std::error_code& ec);
 
 #include <experimental/filesystem>
 #include <type_traits>
@@ -30,7 +30,7 @@ TEST_CASE(signature_test)
 {
     const path p; ((void)p);
     std::error_code ec; ((void)ec);
-    ASSERT_NOEXCEPT(is_empty(p, ec));
+    ASSERT_NOT_NOEXCEPT(is_empty(p, ec));
     ASSERT_NOT_NOEXCEPT(is_empty(p));
 }