]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR libstdc++/90299 make filesystem::absolute overloads consistent
authorJonathan Wakely <jwakely@redhat.com>
Thu, 16 May 2019 23:00:26 +0000 (00:00 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 16 May 2019 23:00:26 +0000 (00:00 +0100)
In this implementation it is an error to pass the empty path to absolute,
because the empty path doesn't represent any file in the filesystem so
the function cannot meet its postcondition.

Currently the absolute(const path&, error_code&) overload reports an
error for the empty path, but using errc::no_such_file_or_directory, and
the other overload does not report an error. This patch makes them
consistntly report an errc::invalid_argument error for the empty path.

Backport from mainline
2019-05-04  Jonathan Wakely  <jwakely@redhat.com>

PR libstdc++/90299
* src/c++17/fs_ops.cc (absolute(const path&)): Report an error if the
argument is an empty path.
(absolute(const path&, error_code&)): Use invalid_argument as error
code instead of no_such_file_or_directory.
* testsuite/27_io/filesystem/operations/absolute.cc: Check handling
of non-existent paths and empty paths with both overloads of absolute.

Backport from mainline
2019-05-16  Jonathan Wakely  <jwakely@redhat.com>

* src/c++17/fs_ops.cc (absolute(const path&, error_code&))
[_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Remove bogus assertion.

From-SVN: r271301

libstdc++-v3/ChangeLog
libstdc++-v3/src/c++17/fs_ops.cc
libstdc++-v3/testsuite/27_io/filesystem/operations/absolute.cc

index a658eb20e77398a3df5e0432b5a048aca479c03b..0868a6fe060ad0bcc501eba31518771a60f25e89 100644 (file)
@@ -1,3 +1,22 @@
+2019-05-16  Jonathan Wakely  <jwakely@redhat.com>
+
+       Backport from mainline
+       2019-05-16  Jonathan Wakely  <jwakely@redhat.com>
+
+       * src/c++17/fs_ops.cc (absolute(const path&, error_code&))
+       [_GLIBCXX_FILESYSTEM_IS_WINDOWS]: Remove bogus assertion.
+
+       Backport from mainline
+       2019-05-04  Jonathan Wakely  <jwakely@redhat.com>
+
+       PR libstdc++/90299
+       * src/c++17/fs_ops.cc (absolute(const path&)): Report an error if the
+       argument is an empty path.
+       (absolute(const path&, error_code&)): Use invalid_argument as error
+       code instead of no_such_file_or_directory.
+       * testsuite/27_io/filesystem/operations/absolute.cc: Check handling
+       of non-existent paths and empty paths with both overloads of absolute.
+
 2019-05-15  Jonathan Wakely  <jwakely@redhat.com>
 
        Backport from mainline
index 5ca523826cb390f7b17b11d52d634293a0dd43fd..274ee7f083453ad7a20dcac20e1fa8a682debed9 100644 (file)
@@ -72,6 +72,9 @@ fs::absolute(const path& p)
                                             ec));
   return ret;
 #else
+  if (p.empty())
+    _GLIBCXX_THROW_OR_ABORT(filesystem_error("cannot make absolute path", p,
+         make_error_code(std::errc::invalid_argument)));
   return current_path() / p;
 #endif
 }
@@ -82,7 +85,7 @@ fs::absolute(const path& p, error_code& ec)
   path ret;
   if (p.empty())
     {
-      ec = make_error_code(std::errc::no_such_file_or_directory);
+      ec = make_error_code(std::errc::invalid_argument);
       return ret;
     }
   ec.clear();
@@ -93,6 +96,7 @@ fs::absolute(const path& p, error_code& ec)
     }
 
 #ifdef _GLIBCXX_FILESYSTEM_IS_WINDOWS
+  // s must remain null-terminated
   wstring_view s = p.native();
 
   if (p.has_root_directory()) // implies !p.has_root_name()
@@ -105,9 +109,6 @@ fs::absolute(const path& p, error_code& ec)
       s.remove_prefix(std::min(s.length(), pos) - 1);
     }
 
-  // s must be null-terminated
-  __glibcxx_assert(!s.empty() && s.back() == 0);
-
   uint32_t len = 1024;
   wstring buf;
   do
index 45f66ac96c5f0bc0194487c0d841f9e066926871..156e68ac87de11127a6c4022b41ceed35564900b 100644 (file)
@@ -67,9 +67,37 @@ test02()
 #endif
 }
 
+void
+test03()
+{
+  // PR libstdc++/90299
+  const path p = __gnu_test::nonexistent_path();
+  std::error_code ec;
+  const path pabs = absolute(p, ec);
+  VERIFY( !ec );
+  VERIFY( pabs.is_absolute() );
+
+  const path pabs2 = absolute(p);
+  VERIFY( pabs2 == pabs );
+
+  const path eabs = absolute(path{}, ec);
+  VERIFY( ec == std::errc::invalid_argument );
+  VERIFY( eabs.empty() );
+
+  try {
+    absolute(path{});
+    VERIFY( false );
+  } catch (const std::filesystem::filesystem_error& e) {
+    VERIFY( e.code() == std::errc::invalid_argument );
+    VERIFY( e.path1().empty() );
+    VERIFY( e.path2().empty() );
+  }
+}
+
 int
 main()
 {
   test01();
   test02();
+  test03();
 }