Add clang::lifetimebound annotation to ArrayRef constructors. (#113547)

This enables clang to detect more dangling issues.

```
ArrayRef<int> func() {
   constexpr int array[] = {...}; // oops, missing the static
   return array; // return a dangling reference, bomb.
}
```

See #113533.
This commit is contained in:
Haojian Wu
2024-10-28 08:38:56 +01:00
committed by GitHub
parent fd85761208
commit e7f422d5c2
2 changed files with 15 additions and 6 deletions

View File

@@ -70,15 +70,16 @@ namespace llvm {
/*implicit*/ ArrayRef(std::nullopt_t) {}
/// Construct an ArrayRef from a single element.
/*implicit*/ ArrayRef(const T &OneElt)
: Data(&OneElt), Length(1) {}
/*implicit*/ ArrayRef(const T &OneElt LLVM_LIFETIME_BOUND)
: Data(&OneElt), Length(1) {}
/// Construct an ArrayRef from a pointer and length.
constexpr /*implicit*/ ArrayRef(const T *data, size_t length)
constexpr /*implicit*/ ArrayRef(const T *data LLVM_LIFETIME_BOUND,
size_t length)
: Data(data), Length(length) {}
/// Construct an ArrayRef from a range.
constexpr ArrayRef(const T *begin, const T *end)
constexpr ArrayRef(const T *begin LLVM_LIFETIME_BOUND, const T *end)
: Data(begin), Length(end - begin) {
assert(begin <= end);
}
@@ -103,7 +104,8 @@ namespace llvm {
/// Construct an ArrayRef from a C array.
template <size_t N>
/*implicit*/ constexpr ArrayRef(const T (&Arr)[N]) : Data(Arr), Length(N) {}
/*implicit*/ constexpr ArrayRef(const T (&Arr LLVM_LIFETIME_BOUND)[N])
: Data(Arr), Length(N) {}
/// Construct an ArrayRef from a std::initializer_list.
#if LLVM_GNUC_PREREQ(9, 0, 0)
@@ -113,7 +115,8 @@ namespace llvm {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Winit-list-lifetime"
#endif
constexpr /*implicit*/ ArrayRef(std::initializer_list<T> Vec)
constexpr /*implicit*/ ArrayRef(
std::initializer_list<T> Vec LLVM_LIFETIME_BOUND)
: Data(Vec.begin() == Vec.end() ? (T *)nullptr : Vec.begin()),
Length(Vec.size()) {}
#if LLVM_GNUC_PREREQ(9, 0, 0)

View File

@@ -413,6 +413,12 @@
#define LLVM_GSL_POINTER
#endif
#if LLVM_HAS_CPP_ATTRIBUTE(clang::lifetimebound)
#define LLVM_LIFETIME_BOUND [[clang::lifetimebound]]
#else
#define LLVM_LIFETIME_BOUND
#endif
#if LLVM_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L
#define LLVM_CTOR_NODISCARD [[nodiscard]]
#else