[llvm] Add clang::lifetimebound annotation to ArrayRef constructors. (PR #113547)

Haojian Wu via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 24 06:19:54 PDT 2024


================
@@ -113,7 +115,8 @@ namespace llvm {
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Winit-list-lifetime"
 #endif
-    constexpr /*implicit*/ ArrayRef(const std::initializer_list<T> &Vec)
+    constexpr /*implicit*/ ArrayRef(
+        const std::initializer_list<T> &Vec LLVM_LIFETIME_BOUND)
----------------
hokein wrote:

> Consider:

> ArrayRef<int> ref({1, 2, 3, 4});
> use(ref);


> Hmm, actually, I am not sure if I'm super confident about this one.
> 
> Consider:
> 
> ```
> ArrayRef<int> ref({1, 2, 3, 4});
> use(ref);
> ```
> 
> What would happen here? I wonder if this is actually safe despite the initializer list itself was a temporary and already destroyed when I invoke `use`.

This is actually a use-after-free, the backing array of the initializer_list is destroyed after the ref declaration statement, see https://godbolt.org/z/fYW7Tqcfq.

> The backing array has the same lifetime as any other [temporary object](https://en.cppreference.com/w/cpp/language/lifetime#Temporary_object_lifetime), except that initializing an [std::initializer_list](https://en.cppreference.com/w/cpp/utility/initializer_list) object from the backing array extends the lifetime of the array exactly like [binding a reference to a temporary](https://en.cppreference.com/w/cpp/language/reference_initialization#Lifetime_of_a_temporary).


https://github.com/llvm/llvm-project/pull/113547


More information about the llvm-commits mailing list