ziangwan created this revision. ziangwan added reviewers: rsmith, nickdesaulniers, kongyi, pirama, stephenkelly. Herald added a project: clang. Herald added a subscriber: cfe-commits.
This is a continuation of https://reviews.llvm.org/D44844 and a potential fix for https://bugs.llvm.org/show_bug.cgi?id=36880. template <typename A> class Variant { public: Variant() { [this](auto value) { Construct(value); }(5); // false positive warning about "this" capture unused. } template <typename Arg> void Construct(Arg value) {} }; int main() { Variant<int> v; return 0; } Whenever we see a `UnresolvedMemberExpr`, we always mark a this capture ODR-used, even if later on it may be resolved to a static member function. The trade-off of this fix is that it will leads to false negative in the following case: template <typename A> class OverloadedMixFalseNegative { public: OverloadedMixFalseNegative() { [this](auto value) { Construct(value); }(5); // warning disappears but should happen } static void Construct(int value) {} void Construct(float value) {} }; Repository: rC Clang https://reviews.llvm.org/D65549 Files: clang/lib/Sema/SemaExpr.cpp clang/test/SemaCXX/warn-unused-lambda-capture-this.cpp
Index: clang/test/SemaCXX/warn-unused-lambda-capture-this.cpp =================================================================== --- /dev/null +++ clang/test/SemaCXX/warn-unused-lambda-capture-this.cpp @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 -fsyntax-only -Wunused-lambda-capture -verify %s + +template <typename A> +class TemplatedStatic { +public: + TemplatedStatic() { + [this](auto value) { Construct(value); }(5); // expected-warning {{lambda capture 'this' is not used}} + } + + template <typename Arg> + static void Construct(Arg value) {} +}; + +template <typename A> +class TemplatedMember { +public: + TemplatedMember() { + [this](auto value) { Construct(value); }(5); + } + + template <typename Arg> + void Construct(Arg value) {} +}; + +template <typename A> +class OverloadedStatic { +public: + OverloadedStatic() { + [this](auto value) { Construct(value); }(5); // expected-warning {{lambda capture 'this' is not used}} + } + + static void Construct(int value) {} + static void Construct(float value) {} +}; + +template <typename A> +class OverloadedMember { +public: + OverloadedMember() { + [this](auto value) { Construct(value); }(5); + } + + void Construct(int value) {} + void Construct(float value) {} +}; + +template <typename A> +class OverloadedMixTrueNegative { +public: + OverloadedMixTrueNegative() { + [this](auto value) { Construct(value); }(5); + } + + void Construct(int value) {} + static void Construct(float value) {} +}; + +template <typename A> +class OverloadedMixFalseNegative { +public: + OverloadedMixFalseNegative() { + // Currently we mark this capture as used whenever UnresolvedMemberExpr + // happens, even if "Construct" will be resolved to the static one. + // Ideally we should issue 'this' not used warning. + [this](auto value) { Construct(value); }(5); + } + + static void Construct(int value) {} + void Construct(float value) {} +}; + +int main() { + TemplatedStatic<int> t1; // expected-note {{in instantiation of member function 'TemplatedStatic<int>::TemplatedStatic' requested here}} + TemplatedMember<int> t2; + OverloadedStatic<int> t3; // expected-note {{in instantiation of member function 'OverloadedStatic<int>::OverloadedStatic' requested here}} + OverloadedMember<int> t4; + OverloadedMixTrueNegative<int> t5; + OverloadedMixFalseNegative<int> t6; + return 0; +} Index: clang/lib/Sema/SemaExpr.cpp =================================================================== --- clang/lib/Sema/SemaExpr.cpp +++ clang/lib/Sema/SemaExpr.cpp @@ -5619,6 +5619,17 @@ *this, dyn_cast<UnresolvedMemberExpr>(Fn->IgnoreParens()), Fn->getBeginLoc()); + // Mark this capture as ODR-used if we are in a lambda + // expression and the callee is UnresolvedMemberExpr. + LambdaScopeInfo *CurLSI = getCurLambda(); + if (CurLSI && isa<UnresolvedMemberExpr>(Fn->IgnoreParens())) { + for (auto &Capture : CurLSI->Captures) { + if (Capture.isThisCapture()) { + Capture.markUsed(/*IsODRUse=*/true); + } + } + } + return CallExpr::Create(Context, Fn, ArgExprs, Context.DependentTy, VK_RValue, RParenLoc); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits