Index: include/clang/AST/ExprCXX.h =================================================================== --- include/clang/AST/ExprCXX.h +++ include/clang/AST/ExprCXX.h @@ -3505,6 +3505,9 @@ /// The source location of the operator is invalid in this case. bool isImplicitAccess() const; + /// True if this an implicit access with a 'this' base object. + bool isImplicitCXXThisAccess() const; + /// \brief Retrieve the base object of this member expressions, /// e.g., the \c x in \c x.m. Expr *getBase() { Index: lib/AST/ExprCXX.cpp =================================================================== --- lib/AST/ExprCXX.cpp +++ lib/AST/ExprCXX.cpp @@ -1246,6 +1246,12 @@ return cast(Base)->isImplicitCXXThis(); } +bool UnresolvedMemberExpr::isImplicitCXXThisAccess() const { + if (!Base) + return false; + return cast(Base)->isImplicitCXXThis(); +} + UnresolvedMemberExpr *UnresolvedMemberExpr::Create( const ASTContext &C, bool HasUnresolvedUsing, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, Index: lib/Sema/TreeTransform.h =================================================================== --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -11264,6 +11264,12 @@ return ExprError(); BaseType = Base.get()->getType(); } else { + // Check an implicit 'this' base expression to ensure that an explicit + // 'this' capture is marked as 'used'. + if (Old->isImplicitCXXThisAccess()) + getSema().CheckCXXThisCapture(Old->getMemberNameInfo().getLoc(), + /*Explicit=*/false, + /*BuildAndDiagnose=*/false); BaseType = getDerived().TransformType(Old->getBaseType()); } Index: test/SemaCXX/warn-unused-lambda-capture.cpp =================================================================== --- test/SemaCXX/warn-unused-lambda-capture.cpp +++ test/SemaCXX/warn-unused-lambda-capture.cpp @@ -200,3 +200,21 @@ auto vla_unused = [&c] {}; // expected-warning{{lambda capture 'c' is not used}} } } // namespace pr35555 + +namespace pr36880 { + +template struct DummyTemplate { + template void methodTemplate(const T2 &) {} + + void ToTemplate(const int ¶m) { + [this](const auto &p) { methodTemplate(p); }(param); // no warning + } +}; + +void main() { + int i = 0; + DummyTemplate dt; + dt.ToTemplate(i); +} + +} // namespace pr36880