llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-libcxx

Author: None (llvmbot)

<details>
<summary>Changes</summary>

Backport 8b5185984e57df12878ea026febb414769c54b03

Requested by: @<!-- -->ldionne

---
Full diff: https://github.com/llvm/llvm-project/pull/177595.diff


2 Files Affected:

- (modified) libcxx/include/__filesystem/path.h (+17-15) 
- (added) 
libcxx/test/libcxx/input.output/filesystems/class.path/lifetimebound.verify.cpp 
(+39) 


``````````diff
diff --git a/libcxx/include/__filesystem/path.h 
b/libcxx/include/__filesystem/path.h
index 4fd3acad4d430..4957761c0ef7e 100644
--- a/libcxx/include/__filesystem/path.h
+++ b/libcxx/include/__filesystem/path.h
@@ -449,7 +449,7 @@ class _LIBCPP_EXPORTED_FROM_ABI path {
     return *this;
   }
 
-  _LIBCPP_HIDE_FROM_ABI path& assign(string_type&& __s) noexcept {
+  _LIBCPP_HIDE_FROM_ABI path& assign(string_type&& __s) noexcept 
_LIBCPP_LIFETIMEBOUND {
     __pn_ = std::move(__s);
     return *this;
   }
@@ -460,14 +460,14 @@ class _LIBCPP_EXPORTED_FROM_ABI path {
   }
 
   template <class _Source>
-  _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> assign(const _Source& 
__src) {
+  _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> assign(const _Source& 
__src) _LIBCPP_LIFETIMEBOUND {
     __pn_.clear();
     _SourceCVT<_Source>::__append_source(__pn_, __src);
     return *this;
   }
 
   template <class _InputIt>
-  _LIBCPP_HIDE_FROM_ABI path& assign(_InputIt __first, _InputIt __last) {
+  _LIBCPP_HIDE_FROM_ABI path& assign(_InputIt __first, _InputIt __last) 
_LIBCPP_LIFETIMEBOUND {
     typedef typename iterator_traits<_InputIt>::value_type _ItVal;
     __pn_.clear();
     _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
@@ -501,12 +501,12 @@ class _LIBCPP_EXPORTED_FROM_ABI path {
   }
 
   template <class _Source>
-  _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> append(const _Source& 
__src) {
+  _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> append(const _Source& 
__src) _LIBCPP_LIFETIMEBOUND {
     return operator/=(path(__src));
   }
 
   template <class _InputIt>
-  _LIBCPP_HIDE_FROM_ABI path& append(_InputIt __first, _InputIt __last) {
+  _LIBCPP_HIDE_FROM_ABI path& append(_InputIt __first, _InputIt __last) 
_LIBCPP_LIFETIMEBOUND {
     return operator/=(path(__first, __last));
   }
 #  else
@@ -530,7 +530,7 @@ class _LIBCPP_EXPORTED_FROM_ABI path {
   }
 
   template <class _Source>
-  _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> append(const _Source& 
__src) {
+  _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> append(const _Source& 
__src) _LIBCPP_LIFETIMEBOUND {
     using _Traits             = __is_pathable<_Source>;
     using _CVT                = _PathCVT<_SourceChar<_Source> >;
     bool __source_is_absolute = 
filesystem::__is_separator(_Traits::__first_or_null(__src));
@@ -543,7 +543,7 @@ class _LIBCPP_EXPORTED_FROM_ABI path {
   }
 
   template <class _InputIt>
-  _LIBCPP_HIDE_FROM_ABI path& append(_InputIt __first, _InputIt __last) {
+  _LIBCPP_HIDE_FROM_ABI path& append(_InputIt __first, _InputIt __last) 
_LIBCPP_LIFETIMEBOUND {
     typedef typename iterator_traits<_InputIt>::value_type _ItVal;
     static_assert(__can_convert_char<_ItVal>::value, "Must convertible");
     using _CVT = _PathCVT<_ItVal>;
@@ -594,13 +594,13 @@ class _LIBCPP_EXPORTED_FROM_ABI path {
   }
 
   template <class _Source>
-  _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> concat(const _Source& __x) {
+  _LIBCPP_HIDE_FROM_ABI _EnableIfPathable<_Source> concat(const _Source& __x) 
_LIBCPP_LIFETIMEBOUND {
     _SourceCVT<_Source>::__append_source(__pn_, __x);
     return *this;
   }
 
   template <class _InputIt>
-  _LIBCPP_HIDE_FROM_ABI path& concat(_InputIt __first, _InputIt __last) {
+  _LIBCPP_HIDE_FROM_ABI path& concat(_InputIt __first, _InputIt __last) 
_LIBCPP_LIFETIMEBOUND {
     typedef typename iterator_traits<_InputIt>::value_type _ItVal;
     _PathCVT<_ItVal>::__append_range(__pn_, __first, __last);
     return *this;
@@ -609,26 +609,26 @@ class _LIBCPP_EXPORTED_FROM_ABI path {
   // modifiers
   _LIBCPP_HIDE_FROM_ABI void clear() noexcept { __pn_.clear(); }
 
-  _LIBCPP_HIDE_FROM_ABI path& make_preferred() {
+  _LIBCPP_HIDE_FROM_ABI path& make_preferred() _LIBCPP_LIFETIMEBOUND {
 #  if defined(_LIBCPP_WIN32API)
     std::replace(__pn_.begin(), __pn_.end(), L'/', L'\\');
 #  endif
     return *this;
   }
 
-  _LIBCPP_HIDE_FROM_ABI path& remove_filename() {
+  _LIBCPP_HIDE_FROM_ABI path& remove_filename() _LIBCPP_LIFETIMEBOUND {
     auto __fname = __filename();
     if (!__fname.empty())
       __pn_.erase(__fname.data() - __pn_.data());
     return *this;
   }
 
-  _LIBCPP_HIDE_FROM_ABI path& replace_filename(const path& __replacement) {
+  _LIBCPP_HIDE_FROM_ABI path& replace_filename(const path& __replacement) 
_LIBCPP_LIFETIMEBOUND {
     remove_filename();
     return (*this /= __replacement);
   }
 
-  path& replace_extension(const path& __replacement = path());
+  path& replace_extension(const path& __replacement = path()) 
_LIBCPP_LIFETIMEBOUND;
 
   friend _LIBCPP_HIDE_FROM_ABI bool operator==(const path& __lhs, const path& 
__rhs) noexcept {
     return __lhs.__compare(__rhs.__pn_) == 0;
@@ -667,9 +667,11 @@ class _LIBCPP_EXPORTED_FROM_ABI path {
   _LIBCPP_HIDE_FROM_ABI void __reserve(size_t __s) { __pn_.reserve(__s); }
 
   // native format observers
-  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const string_type& native() const 
noexcept { return __pn_; }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const string_type& native() const 
noexcept _LIBCPP_LIFETIMEBOUND { return __pn_; }
 
-  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const value_type* c_str() const noexcept 
{ return __pn_.c_str(); }
+  [[nodiscard]] _LIBCPP_HIDE_FROM_ABI const value_type* c_str() const noexcept 
_LIBCPP_LIFETIMEBOUND {
+    return __pn_.c_str();
+  }
 
   _LIBCPP_HIDE_FROM_ABI operator string_type() const { return __pn_; }
 
diff --git 
a/libcxx/test/libcxx/input.output/filesystems/class.path/lifetimebound.verify.cpp
 
b/libcxx/test/libcxx/input.output/filesystems/class.path/lifetimebound.verify.cpp
new file mode 100644
index 0000000000000..3e5aa5e57e259
--- /dev/null
+++ 
b/libcxx/test/libcxx/input.output/filesystems/class.path/lifetimebound.verify.cpp
@@ -0,0 +1,39 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// UNSUPPORTED: c++03, c++11, c++14
+// ADDITIONAL_COMPILE_FLAGS: -Wno-unused-variable
+
+#include <filesystem>
+
+// clang-format off
+
+namespace fs = std::filesystem;
+
+fs::path& test() {
+  fs::path p;
+  char arr[] = "Banane";
+
+  auto&& v1 = fs::path().native(); // expected-warning {{temporary bound to 
local reference 'v1' will be destroyed at the end of the full-expression}}
+  auto v2   = fs::path().c_str();  // expected-warning {{temporary whose 
address is used as value of local variable 'v2' will be destroyed at the end of 
the full-expression}}
+
+  return p.assign("");                             // expected-warning 
{{reference to stack memory associated with local variable 'p' returned}}
+  return p.assign(std::string());                  // expected-warning 
{{reference to stack memory associated with local variable 'p' returned}}
+  return p.assign(std::begin(arr), std::end(arr)); // expected-warning 
{{reference to stack memory associated with local variable 'p' returned}}
+
+  return p.append("");                             // expected-warning 
{{reference to stack memory associated with local variable 'p' returned}}
+  return p.append(std::begin(arr), std::end(arr)); // expected-warning 
{{reference to stack memory associated with local variable 'p' returned}}
+
+  return p.concat("");                             // expected-warning 
{{reference to stack memory associated with local variable 'p' returned}}
+  return p.concat(std::begin(arr), std::end(arr)); // expected-warning 
{{reference to stack memory associated with local variable 'p' returned}}
+
+  return p.make_preferred();     // expected-warning {{reference to stack 
memory associated with local variable 'p' returned}}
+  return p.remove_filename();    // expected-warning {{reference to stack 
memory associated with local variable 'p' returned}}
+  return p.replace_filename(""); // expected-warning {{reference to stack 
memory associated with local variable 'p' returned}}
+  return p.replace_extension();  // expected-warning {{reference to stack 
memory associated with local variable 'p' returned}}
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/177595
_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to