diff options
author | Malcolm Parsons <malcolm.parsons@gmail.com> | 2017-03-01 10:23:38 +0000 |
---|---|---|
committer | Malcolm Parsons <malcolm.parsons@gmail.com> | 2017-03-01 10:23:38 +0000 |
commit | ded2306208d875ed38309cef6478b88f87a3ecd7 (patch) | |
tree | ddfd98fa35e0b08e8a8433998c3f9789052eda19 /clang/lib/Sema/SemaLambda.cpp | |
parent | 9b802e4650c5fe5ea0fc273a15536d1d6a67fbf9 (diff) | |
download | bcm5719-llvm-ded2306208d875ed38309cef6478b88f87a3ecd7.tar.gz bcm5719-llvm-ded2306208d875ed38309cef6478b88f87a3ecd7.zip |
[Sema] Improve side effect checking for unused-lambda-capture warning
Summary:
Don't warn about unused lambda captures that involve copying a
value of a type that cannot be trivially copied and destroyed.
Fixes PR31977
Reviewers: rsmith, aaron.ballman
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D30327
llvm-svn: 296602
Diffstat (limited to 'clang/lib/Sema/SemaLambda.cpp')
-rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 26 |
1 files changed, 24 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index c17f9fbd07e..fc823f4aca3 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1438,13 +1438,35 @@ mapImplicitCaptureStyle(CapturingScopeInfo::ImplicitCaptureStyle ICS) { llvm_unreachable("Unknown implicit capture style"); } -void Sema::DiagnoseUnusedLambdaCapture(const LambdaScopeInfo::Capture &From) { +bool Sema::CaptureHasSideEffects(const LambdaScopeInfo::Capture &From) { if (!From.isVLATypeCapture()) { Expr *Init = From.getInitExpr(); if (Init && Init->HasSideEffects(Context)) - return; + return true; } + if (!From.isCopyCapture()) + return false; + + const QualType T = From.isThisCapture() + ? getCurrentThisType()->getPointeeType() + : From.getCaptureType(); + + if (T.isVolatileQualified()) + return true; + + const Type *BaseT = T->getBaseElementTypeUnsafe(); + if (const CXXRecordDecl *RD = BaseT->getAsCXXRecordDecl()) + return !RD->isCompleteDefinition() || !RD->hasTrivialCopyConstructor() || + !RD->hasTrivialDestructor(); + + return false; +} + +void Sema::DiagnoseUnusedLambdaCapture(const LambdaScopeInfo::Capture &From) { + if (CaptureHasSideEffects(From)) + return; + auto diag = Diag(From.getLocation(), diag::warn_unused_lambda_capture); if (From.isThisCapture()) diag << "'this'"; |