mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-27 22:03:57 +08:00
Make filesystem::path safe for self assignment
The standard says "If *this and p are the same object, has no effect." Previously we ended up clearing the path. * include/bits/fs_path.h (path::operator=(path&&)): Check for self assignment. * src/c++17/fs_path.cc (path::operator=(const path&)): Likewise. * testsuite/27_io/filesystem/path/assign/copy.cc: Test self assignment. From-SVN: r270171
This commit is contained in:
parent
10f26de915
commit
d96f11a272
@ -1,5 +1,11 @@
|
||||
2019-04-05 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
* include/bits/fs_path.h (path::operator=(path&&)): Check for self
|
||||
assignment.
|
||||
* src/c++17/fs_path.cc (path::operator=(const path&)): Likewise.
|
||||
* testsuite/27_io/filesystem/path/assign/copy.cc: Test self
|
||||
assignment.
|
||||
|
||||
PR libstdc++/87431 (again)
|
||||
* include/bits/basic_string.h (__variant::_Never_valueless_alt):
|
||||
Define partial specialization for basic_string.
|
||||
|
@ -877,6 +877,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
|
||||
inline path&
|
||||
path::operator=(path&& __p) noexcept
|
||||
{
|
||||
if (&__p == this) [[__unlikely__]]
|
||||
return *this;
|
||||
|
||||
_M_pathname = std::move(__p._M_pathname);
|
||||
_M_cmpts = std::move(__p._M_cmpts);
|
||||
__p.clear();
|
||||
|
@ -444,6 +444,9 @@ path::_List::reserve(int newcap, bool exact = false)
|
||||
path&
|
||||
path::operator=(const path& p)
|
||||
{
|
||||
if (&p == this) [[__unlikely__]]
|
||||
return *this;
|
||||
|
||||
_M_pathname.reserve(p._M_pathname.length());
|
||||
_M_cmpts = p._M_cmpts; // might throw
|
||||
_M_pathname = p._M_pathname; // won't throw because we reserved enough space
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include <filesystem>
|
||||
#include <testsuite_fs.h>
|
||||
#include <testsuite_hooks.h>
|
||||
|
||||
using std::filesystem::path;
|
||||
using __gnu_test::compare_paths;
|
||||
@ -47,9 +48,26 @@ test02()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
test03()
|
||||
{
|
||||
// self assignment should have no effect
|
||||
const path orig = "foo/bar/baz";
|
||||
path p = orig;
|
||||
const auto ptr1 = p.c_str();
|
||||
const auto ptr2 = p.begin()->c_str();
|
||||
p = std::move(p);
|
||||
__gnu_test::compare_paths(p, orig);
|
||||
p = p;
|
||||
__gnu_test::compare_paths(p, orig);
|
||||
VERIFY( ptr1 == p.c_str() );
|
||||
VERIFY( ptr2 == p.begin()->c_str() );
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
test01();
|
||||
test02();
|
||||
test03();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user