-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[clang-tidy] False positive for cppcoreguidelines-missing-std-forward when forwarding into lambda #68105
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
Comments
Simplified test case to #include <utility>
template <typename T>
void f(T&& x)
{
[y = std::forward(x)] {};
} |
This is not a false positive, because variable template<typename F>
auto make_lambda(F&& f)
{
return [f = std::forward<F>(f)] { f(); };
} is located in lambda expression, not in function |
See the simplified test case by @AMS21 |
I see two cases in test of template <class T>
void lambda_value_capture(T&& t) {
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]
[=]() { T other = std::forward<T>(t); };
}
template <class T>
void lambda_value_reference(T&& t) {
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]
[&]() { T other = std::forward<T>(t); };
} If they are different and indeed it's a bug, I'm pleasure to fix it. |
@jcsxky I am watching this ticket as well, and can offer some insight on your question. The two lambdas in the test cases you show are never invoked in the body of the function being tested. So, in essence, the lambda body in both is dead code, with the possible exception that T's copy constructor might have an observable side-effect. I am not sure whether this clang-tidy check would be discerning enough to see that. However, if I were to add an immediate invocation of these lambdas, then they would become unconditionally "live", and then there would indeed be a clear difference between them. template <class T>
void lambda_value_capture(T&& t) {
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]
- [=]() { T other = std::forward<T>(t); };
+ [=]() { T other = std::forward<T>(t); }();
}
template <class T>
void lambda_value_reference(T&& t) {
// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: forwarding reference parameter 't' is never forwarded inside the function body [cppcoreguidelines-missing-std-forward]
- [&]() { T other = std::forward<T>(t); };
+ [&]() { T other = std::forward<T>(t); }();
} The first one captures a copy of The second one captures a reference to There is a place for a third case that could be added: template <class T>
void lambda_value_forwarded_capture(T&& t) {
[t = std::forward<T>(t)]() mutable { T other = std::move(t); }();
} This is distinct from the first two, in that it performs an effective forwarding at capture time. I hope this is helpful. |
@iillyyaa Thanks for your detail explanation! |
Capturing by reference and then forwarding in the lambda body, or capturing by value from a forwarded reference should pass. Capturing by value without forwarding at capture time should not pass. Thanks for looking into it! |
…ard (llvm#77056) Parameter variable which is forwarded in lambda capture list or in body by reference is reasonable and current version of this check produces false positive on these cases. This patch try to fix the [issue](llvm#68105) Co-authored-by: huqizhi <836744285@qq.com>
The following seemingly valid code
results in the error
Encountered on
installed with the script from https://apt.llvm.org/llvm.sh .
The text was updated successfully, but these errors were encountered: