r305315 - Fix spurious Wunused-lambda-capture warning
Yi Kong via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 13 11:38:31 PDT 2017
Author: kongyi
Date: Tue Jun 13 13:38:31 2017
New Revision: 305315
URL: http://llvm.org/viewvc/llvm-project?rev=305315&view=rev
Log:
Fix spurious Wunused-lambda-capture warning
Summary:
Clang emits unused-lambda-capture warning for captures in generic lambdas even though they are actually used.
Fixes PR31815.
Reviewers: malcolm.parsons, aaron.ballman, rsmith
Reviewed By: malcolm.parsons
Subscribers: ahatanak, cfe-commits
Differential Revision: https://reviews.llvm.org/D33526
Modified:
cfe/trunk/lib/Sema/SemaLambda.cpp
cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp
Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=305315&r1=305314&r2=305315&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Tue Jun 13 13:38:31 2017
@@ -1492,6 +1492,7 @@ ExprResult Sema::BuildLambdaExpr(SourceL
bool ExplicitResultType;
CleanupInfo LambdaCleanup;
bool ContainsUnexpandedParameterPack;
+ bool IsGenericLambda;
{
CallOperator = LSI->CallOperator;
Class = LSI->Lambda;
@@ -1500,7 +1501,8 @@ ExprResult Sema::BuildLambdaExpr(SourceL
ExplicitResultType = !LSI->HasImplicitReturnType;
LambdaCleanup = LSI->Cleanup;
ContainsUnexpandedParameterPack = LSI->ContainsUnexpandedParameterPack;
-
+ IsGenericLambda = Class->isGenericLambda();
+
CallOperator->setLexicalDeclContext(Class);
Decl *TemplateOrNonTemplateCallOperatorDecl =
CallOperator->getDescribedFunctionTemplate()
@@ -1520,8 +1522,13 @@ ExprResult Sema::BuildLambdaExpr(SourceL
bool IsImplicit = I >= LSI->NumExplicitCaptures;
// Warn about unused explicit captures.
- if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed())
- DiagnoseUnusedLambdaCapture(From);
+ if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) {
+ // Initialized captures that are non-ODR used may not be eliminated.
+ bool NonODRUsedInitCapture =
+ IsGenericLambda && From.isNonODRUsed() && From.getInitExpr();
+ if (!NonODRUsedInitCapture)
+ DiagnoseUnusedLambdaCapture(From);
+ }
// Handle 'this' capture.
if (From.isThisCapture()) {
@@ -1568,8 +1575,7 @@ ExprResult Sema::BuildLambdaExpr(SourceL
// same parameter and return types as the closure type's function call
// operator.
// FIXME: Fix generic lambda to block conversions.
- if (getLangOpts().Blocks && getLangOpts().ObjC1 &&
- !Class->isGenericLambda())
+ if (getLangOpts().Blocks && getLangOpts().ObjC1 && !IsGenericLambda)
addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator);
// Finalize the lambda class.
Modified: cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp?rev=305315&r1=305314&r2=305315&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-unused-lambda-capture.cpp Tue Jun 13 13:38:31 2017
@@ -142,11 +142,14 @@ void test_templated() {
auto implicit_by_reference = [&] { i++; };
auto explicit_by_value_used = [i] { return i + 1; };
+ auto explicit_by_value_used_generic = [i](auto c) { return i + 1; };
auto explicit_by_value_used_void = [i] { (void)i; };
+
auto explicit_by_value_unused = [i] {}; // expected-warning{{lambda capture 'i' is not used}}
auto explicit_by_value_unused_sizeof = [i] { return sizeof(i); }; // expected-warning{{lambda capture 'i' is not required to be captured for this use}}
auto explicit_by_value_unused_decltype = [i] { decltype(i) j = 0; }; // expected-warning{{lambda capture 'i' is not used}}
auto explicit_by_value_unused_const = [k] { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
+ auto explicit_by_value_unused_const_generic = [k](auto c) { return k + 1; }; // expected-warning{{lambda capture 'k' is not required to be captured for this use}}
auto explicit_by_reference_used = [&i] { i++; };
auto explicit_by_reference_unused = [&i] {}; // expected-warning{{lambda capture 'i' is not used}}
@@ -161,6 +164,8 @@ void test_templated() {
auto explicit_initialized_value_trivial_init = [j = Trivial()]{}; // expected-warning{{lambda capture 'j' is not used}}
auto explicit_initialized_value_non_trivial_init = [j = Trivial(42)]{};
auto explicit_initialized_value_with_side_effect = [j = side_effect()]{};
+ auto explicit_initialized_value_generic_used = [i = 1](auto c) mutable { i++; };
+ auto explicit_initialized_value_generic_unused = [i = 1](auto c) mutable {}; // expected-warning{{lambda capture 'i' is not used}}
auto nested = [&i] {
auto explicit_by_value_used = [i] { return i + 1; };
More information about the cfe-commits
mailing list