Skip to content

Commit e7f422d

Browse files
authored
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.
1 parent fd85761 commit e7f422d

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

llvm/include/llvm/ADT/ArrayRef.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,16 @@ namespace llvm {
7070
/*implicit*/ ArrayRef(std::nullopt_t) {}
7171

7272
/// Construct an ArrayRef from a single element.
73-
/*implicit*/ ArrayRef(const T &OneElt)
74-
: Data(&OneElt), Length(1) {}
73+
/*implicit*/ ArrayRef(const T &OneElt LLVM_LIFETIME_BOUND)
74+
: Data(&OneElt), Length(1) {}
7575

7676
/// Construct an ArrayRef from a pointer and length.
77-
constexpr /*implicit*/ ArrayRef(const T *data, size_t length)
77+
constexpr /*implicit*/ ArrayRef(const T *data LLVM_LIFETIME_BOUND,
78+
size_t length)
7879
: Data(data), Length(length) {}
7980

8081
/// Construct an ArrayRef from a range.
81-
constexpr ArrayRef(const T *begin, const T *end)
82+
constexpr ArrayRef(const T *begin LLVM_LIFETIME_BOUND, const T *end)
8283
: Data(begin), Length(end - begin) {
8384
assert(begin <= end);
8485
}
@@ -103,7 +104,8 @@ namespace llvm {
103104

104105
/// Construct an ArrayRef from a C array.
105106
template <size_t N>
106-
/*implicit*/ constexpr ArrayRef(const T (&Arr)[N]) : Data(Arr), Length(N) {}
107+
/*implicit*/ constexpr ArrayRef(const T (&Arr LLVM_LIFETIME_BOUND)[N])
108+
: Data(Arr), Length(N) {}
107109

108110
/// Construct an ArrayRef from a std::initializer_list.
109111
#if LLVM_GNUC_PREREQ(9, 0, 0)
@@ -113,7 +115,8 @@ namespace llvm {
113115
#pragma GCC diagnostic push
114116
#pragma GCC diagnostic ignored "-Winit-list-lifetime"
115117
#endif
116-
constexpr /*implicit*/ ArrayRef(std::initializer_list<T> Vec)
118+
constexpr /*implicit*/ ArrayRef(
119+
std::initializer_list<T> Vec LLVM_LIFETIME_BOUND)
117120
: Data(Vec.begin() == Vec.end() ? (T *)nullptr : Vec.begin()),
118121
Length(Vec.size()) {}
119122
#if LLVM_GNUC_PREREQ(9, 0, 0)

llvm/include/llvm/Support/Compiler.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,12 @@
413413
#define LLVM_GSL_POINTER
414414
#endif
415415

416+
#if LLVM_HAS_CPP_ATTRIBUTE(clang::lifetimebound)
417+
#define LLVM_LIFETIME_BOUND [[clang::lifetimebound]]
418+
#else
419+
#define LLVM_LIFETIME_BOUND
420+
#endif
421+
416422
#if LLVM_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L
417423
#define LLVM_CTOR_NODISCARD [[nodiscard]]
418424
#else

0 commit comments

Comments
 (0)