Commit f9b22a0c by Jonathan Wakely Committed by Jonathan Wakely

PR libstdc++/90557 fix path assignment that alters source

	PR libstdc++/90557
	* src/c++17/fs_path.cc (path::_List::operator=(const _List&)): Fix
	reversed arguments to uninitialized_copy_n.
	* testsuite/27_io/filesystem/path/assign/copy.cc: Check that source
	is unchanged by copy assignment.
	* testsuite/util/testsuite_fs.h (compare_paths): Use std::equal to
	compare path components.

From-SVN: r271527
parent 7039cebf
2019-05-22 Jonathan Wakely <jwakely@redhat.com> 2019-05-22 Jonathan Wakely <jwakely@redhat.com>
PR libstdc++/90557
* src/c++17/fs_path.cc (path::_List::operator=(const _List&)): Fix
reversed arguments to uninitialized_copy_n.
* testsuite/27_io/filesystem/path/assign/copy.cc: Check that source
is unchanged by copy assignment.
* testsuite/util/testsuite_fs.h (compare_paths): Use std::equal to
compare path components.
PR libstdc++/77691 PR libstdc++/77691
* include/experimental/memory_resource: Add system header pragma and * include/experimental/memory_resource: Add system header pragma and
do not define anything unless compiled as C++14 or later. do not define anything unless compiled as C++14 or later.
......
...@@ -278,8 +278,8 @@ path::_List::operator=(const _List& other) ...@@ -278,8 +278,8 @@ path::_List::operator=(const _List& other)
to[i]._M_pathname.reserve(from[i]._M_pathname.length()); to[i]._M_pathname.reserve(from[i]._M_pathname.length());
if (newsize > oldsize) if (newsize > oldsize)
{ {
std::uninitialized_copy_n(to + oldsize, newsize - oldsize, std::uninitialized_copy_n(from + oldsize, newsize - oldsize,
from + oldsize); to + oldsize);
impl->_M_size = newsize; impl->_M_size = newsize;
} }
else if (newsize < oldsize) else if (newsize < oldsize)
......
...@@ -64,10 +64,25 @@ test03() ...@@ -64,10 +64,25 @@ test03()
VERIFY( ptr2 == p.begin()->c_str() ); VERIFY( ptr2 == p.begin()->c_str() );
} }
void
test04()
{
// PR libstdc++/90557
path p1 = "a/b/c";
const path p2 = "d/e";
const path p3 = p2;
p1.clear();
p1 = p2;
__gnu_test::compare_paths(p1, p2);
__gnu_test::compare_paths(p1, p3);
__gnu_test::compare_paths(p2, p3);
}
int int
main() main()
{ {
test01(); test01();
test02(); test02();
test03(); test03();
test04();
} }
...@@ -30,6 +30,7 @@ namespace test_fs = std::filesystem; ...@@ -30,6 +30,7 @@ namespace test_fs = std::filesystem;
#include <experimental/filesystem> #include <experimental/filesystem>
namespace test_fs = std::experimental::filesystem; namespace test_fs = std::experimental::filesystem;
#endif #endif
#include <algorithm>
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <cstdio> #include <cstdio>
...@@ -62,10 +63,15 @@ namespace __gnu_test ...@@ -62,10 +63,15 @@ namespace __gnu_test
PATH_CHK( p1, p2, is_relative ); PATH_CHK( p1, p2, is_relative );
auto d1 = std::distance(p1.begin(), p1.end()); auto d1 = std::distance(p1.begin(), p1.end());
auto d2 = std::distance(p2.begin(), p2.end()); auto d2 = std::distance(p2.begin(), p2.end());
if( d1 != d2 ) if (d1 != d2)
throw test_fs::filesystem_error( throw test_fs::filesystem_error(
"distance(begin, end)", p1, p2, "distance(begin1, end1) != distance(begin2, end2)", p1, p2,
std::make_error_code(std::errc::invalid_argument) ); std::make_error_code(std::errc::invalid_argument) );
if (!std::equal(p1.begin(), p1.end(), p2.begin(), p2.end()))
throw test_fs::filesystem_error(
"!equal(begin1, end1, begin2, end2)", p1, p2,
std::make_error_code(std::errc::invalid_argument) );
} }
const std::string test_paths[] = { const std::string test_paths[] = {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment