Merge topic 'filesystem-path-c++03-abi'

ee9805ccd1 cm/filesystem: Fix crash with pre-C++11 std::string GNU ABI in C++17

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: buildbot <buildbot@kitware.com>
Merge-request: !7813
This commit is contained in:
Brad King
2022-10-21 14:05:34 +00:00
committed by Kitware Robot
3 changed files with 18 additions and 13 deletions

View File

@@ -80,9 +80,7 @@ if(CMake_HAVE_CXX_MAKE_UNIQUE)
set(CMake_HAVE_CXX_UNIQUE_PTR 1)
endif()
cm_check_cxx_feature(unique_ptr)
if (NOT CMAKE_CXX_STANDARD LESS "17"
AND NOT MSYS # FIXME: RunCMake.cmake_path cases crash with MSYS std::filesystem
)
if (NOT CMAKE_CXX_STANDARD LESS "17")
if (NOT CMAKE_CROSSCOMPILING OR CMAKE_CROSSCOMPILING_EMULATOR)
cm_check_cxx_feature(filesystem TRY_RUN)
else()

View File

@@ -23,5 +23,16 @@ int main()
}
#endif
// If std::string is copy-on-write, the std::filesystem::path
// implementation may accidentally trigger a reallocation and compute
// an offset between two allocations, leading to undefined behavior.
#if defined(__GLIBCXX__) && \
(!defined(_GLIBCXX_USE_CXX11_ABI) || !_GLIBCXX_USE_CXX11_ABI)
std::string p5s1 = "/path";
std::string p5s2 = std::move(p5s1);
std::filesystem::path p5 = std::string(p5s2);
p5.remove_filename();
#endif
return 0;
}

View File

@@ -809,13 +809,11 @@ public:
path& remove_filename()
{
# if defined(__CYGWIN__)
// FIXME: Avoid crash due to CYGWIN/MSYS bug(?). See CMake Issue 22090.
static_cast<void>(this->path_.data());
# endif
auto fname = this->get_filename();
if (!fname.empty()) {
this->path_.erase(fname.data() - this->path_.data());
this->path_.erase(fname.data() -
// Avoid C++17 non-const .data() that may reallocate.
static_cast<path_type const&>(this->path_).data());
}
return *this;
}
@@ -829,13 +827,11 @@ public:
path& replace_extension(const path& replacement = path())
{
# if defined(__CYGWIN__)
// FIXME: Avoid crash due to CYGWIN/MSYS bug(?). See CMake Issue 22090.
static_cast<void>(this->path_.data());
# endif
auto ext = this->get_filename_fragment(filename_fragment::extension);
if (!ext.empty()) {
this->path_.erase(ext.data() - this->path_.data());
this->path_.erase(ext.data() -
// Avoid C++17 non-const .data() that may reallocate.
static_cast<path_type const&>(this->path_).data());
}
if (!replacement.path_.empty()) {
if (replacement.path_[0] != '.') {