-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang] Add a lifetime_capture_by testcase for temporary capturing object. #117733
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-clang Author: Haojian Wu (hokein) ChangesFixes #117728 Full diff: https://github.com/llvm/llvm-project/pull/117733.diff 2 Files Affected:
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index a49605e4867651..54d8bbdfc0f4fd 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3248,9 +3248,13 @@ void Sema::checkLifetimeCaptureBy(FunctionDecl *FD, bool IsMemberFunction,
checkCaptureByLifetime(*this, CE, Captured);
}
};
- for (unsigned I = 0; I < FD->getNumParams(); ++I)
- HandleCaptureByAttr(FD->getParamDecl(I)->getAttr<LifetimeCaptureByAttr>(),
- I + IsMemberFunction);
+ // Suppress the warning if the capturing object is also a temporary to reduce
+ // noise, e.g `vector<string_view>().push_back(std::string());`.
+ if (!isa_and_present<MaterializeTemporaryExpr>(ThisArg)) {
+ for (unsigned I = 0; I < FD->getNumParams(); ++I)
+ HandleCaptureByAttr(FD->getParamDecl(I)->getAttr<LifetimeCaptureByAttr>(),
+ I + IsMemberFunction);
+ }
// Check when the implicit object param is captured.
if (IsMemberFunction) {
TypeSourceInfo *TSI = FD->getTypeSourceInfo();
diff --git a/clang/test/Sema/warn-lifetime-analysis-capture-by.cpp b/clang/test/Sema/warn-lifetime-analysis-capture-by.cpp
index 4d562bac1e305b..61d13c9e585e44 100644
--- a/clang/test/Sema/warn-lifetime-analysis-capture-by.cpp
+++ b/clang/test/Sema/warn-lifetime-analysis-capture-by.cpp
@@ -143,6 +143,17 @@ void use() {
}
} // namespace this_is_captured
+namespace ignore_temporary_class_object {
+struct S {
+ void add(const int& x [[clang::lifetime_capture_by(this)]]);
+};
+
+void test() {
+ S().add(1);
+ S{}.add(1);
+}
+} // namespace ignore_temporary_class_object
+
// ****************************************************************************
// Capture by Global and Unknown.
// ****************************************************************************
|
I considered this during implementation. This is a little controversial. It is possible that the temporary capturing object uses the captured entity in its destructor. In principle, we can always detect the order of destructions of the temporaries and choose to suppress cases when captured temporary outlives capturing temporary. But it would be a very confusing behaviour for the user, eg: switching order of params suppresses the warning. I would be in favour of not doing this and always diagnosing this for simplicity until we see a strong need or practical false positives. WDYT ? |
This is a good point. We could potentially limit the suppression to cases where the destructor is trivial, but that might not be worth the added complexity. Agree that this is probably not a critical issue -- I just noticed it while reading the code. I’m fine with leaving it as is. I have repurposed this PR to add a test case for it instead. |
bf69788
to
30235e4
Compare
Thanks for the tests. LGTM. |
Add a test case to indicate this is an expected behavior.