diff mbox series

PR libstdc++/90299 make filesystem::absolute overloads consistent

Message ID 20190504143750.GA11760@redhat.com
State New
Headers show
Series PR libstdc++/90299 make filesystem::absolute overloads consistent | expand

Commit Message

Jonathan Wakely May 4, 2019, 2:37 p.m. UTC
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.

	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.


Tested powerpc64le-linux, committed to trunk.

I'll backport this to gcc-9-branch too.
commit 84eda927e0c194fd2d405a283c54b5456e425a45
Author: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Sat May 4 14:35:33 2019 +0000

    PR libstdc++/90299 make filesystem::absolute overloads consistent
    
    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.
    
            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.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@270874 138bc75d-0d04-0410-961f-82ee72b054a4
diff mbox series

Patch

diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc
index 5ca523826cb..2d13b172d69 100644
--- a/libstdc++-v3/src/c++17/fs_ops.cc
+++ b/libstdc++-v3/src/c++17/fs_ops.cc
@@ -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();
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/absolute.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/absolute.cc
index 45f66ac96c5..156e68ac87d 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/absolute.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/absolute.cc
@@ -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();
 }