diff --git a/libcxx/src/filesystem/operations.cpp b/libcxx/src/filesystem/operations.cpp --- a/libcxx/src/filesystem/operations.cpp +++ b/libcxx/src/filesystem/operations.cpp @@ -1235,6 +1235,11 @@ return err.report(errc::not_a_directory, "path \"%s\" is not a directory", p); + // https://llvm.org/PR45307: + // Avoid returning a temporary path with a trailing slash. + auto last_component = --p.end(); + if (last_component->empty()) + return p.parent_path(); return p; } diff --git a/libcxx/test/libcxx/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/trailing-slash.sh.cpp b/libcxx/test/libcxx/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/trailing-slash.sh.cpp new file mode 100644 --- /dev/null +++ b/libcxx/test/libcxx/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/trailing-slash.sh.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +// https://llvm.org/PR45307 +// +// Make sure that temp_directory_path() doesn't return a path with a trailing +// slash, even when one of the relevant environment variables contains a path +// with a trailing slash. + +// UNSUPPORTED: c++98, c++03 + +// The dylibs shipped until and including macosx10.15 did not contain the fix +// for this issue, so they fail at runtime. +// XFAIL: with_system_cxx_lib=macosx10.15 +// XFAIL: with_system_cxx_lib=macosx10.14 +// XFAIL: with_system_cxx_lib=macosx10.13 +// XFAIL: with_system_cxx_lib=macosx10.12 +// XFAIL: with_system_cxx_lib=macosx10.11 +// XFAIL: with_system_cxx_lib=macosx10.10 +// XFAIL: with_system_cxx_lib=macosx10.9 +// XFAIL: with_system_cxx_lib=macosx10.8 +// XFAIL: with_system_cxx_lib=macosx10.7 + +// RUN: %build +// RUN: mkdir -p "%t.dir" +// RUN: %exec env TMPDIR="%t.dir/" %t.exe "%t.dir" +// RUN: %exec env TMP="%t.dir/" %t.exe "%t.dir" +// RUN: %exec env TEMP="%t.dir/" %t.exe "%t.dir" +// RUN: %exec env TEMPDIR="%t.dir/" %t.exe "%t.dir" + +#include +#include + +int main(int, char** argv) { + std::filesystem::path expected_tmp = argv[1]; + std::filesystem::path tmp = std::filesystem::temp_directory_path(); + assert(tmp == expected_tmp); + return 0; +}