-
Notifications
You must be signed in to change notification settings - Fork 13.5k
Add clang::lifetimebound annotation to ArrayRef constructors. #113547
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-llvm-adt @llvm/pr-subscribers-llvm-support Author: Haojian Wu (hokein) ChangesThis enables clang to detect more dangling issues.
See #113533. Full diff: https://github.com/llvm/llvm-project/pull/113547.diff 2 Files Affected:
diff --git a/llvm/include/llvm/ADT/ArrayRef.h b/llvm/include/llvm/ADT/ArrayRef.h
index d9897320ce091a..1a2a8a307a2995 100644
--- a/llvm/include/llvm/ADT/ArrayRef.h
+++ b/llvm/include/llvm/ADT/ArrayRef.h
@@ -70,7 +70,7 @@ namespace llvm {
/*implicit*/ ArrayRef(std::nullopt_t) {}
/// Construct an ArrayRef from a single element.
- /*implicit*/ ArrayRef(const T &OneElt)
+ /*implicit*/ ArrayRef(const T &OneElt LLVM_LIFETIME_BOUND)
: Data(&OneElt), Length(1) {}
/// Construct an ArrayRef from a pointer and length.
@@ -103,7 +103,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)
diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
index 591e7647795bb2..3b03c2851a4214 100644
--- a/llvm/include/llvm/Support/Compiler.h
+++ b/llvm/include/llvm/Support/Compiler.h
@@ -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_LLVM_LIFETIME_BOUND
+#endif
+
#if LLVM_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L
#define LLVM_CTOR_NODISCARD [[nodiscard]]
#else
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
Any reason for not annotating the rest of the constructors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I think the std::vector
and std::array
ones could also be annotated.
Note that the ArrayRef is already annotated as gsl::Pointer, so constructor for the gsl::Owner already works without the lifetimebound annotation. I only target on the non-working cases, mostly the generic pointer/reference types. Below is my test:
|
Ah, I see! Thanks! That makes sense. I guess one question is if the future direction is to use both annotations together or to standardize on one of them for more clarity. I don't have a strong opinion on this one. |
The std::initializer_list is a lightweight object, it is passed by value in general. This would also avoid a false positive when adding the lifetimebound annotation (#113547) ``` ArrayRef<int> foo(std::initializer_list<int> list) { return ArrayRef<int>(list); } ```
907a185
to
0ac2069
Compare
…3590) The std::initializer_list is a lightweight object, it is passed by value in general. This would also avoid a false positive when adding the lifetimebound annotation (llvm#113547) ``` ArrayRef<int> foo(std::initializer_list<int> list) { return ArrayRef<int>(list); } ```
…13547) 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 llvm#113533.
This enables clang to detect more dangling issues.
See #113533.