From 299ac653c2df2f3b5b2878d7e85a2f098d2f1cdf Mon Sep 17 00:00:00 2001 From: Michael Layzell Date: Mon, 25 Jan 2016 19:54:05 -0500 Subject: [PATCH] Bug 1242789 - Allow lambdas to capture raw pointers to refcounted objects by reference, r=ehsan --- build/clang-plugin/clang-plugin.cpp | 2 +- .../tests/TestNoRefcountedInsideLambdas.cpp | 28 +++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/build/clang-plugin/clang-plugin.cpp b/build/clang-plugin/clang-plugin.cpp index 85749233d5d5..9d442bdfc945 100644 --- a/build/clang-plugin/clang-plugin.cpp +++ b/build/clang-plugin/clang-plugin.cpp @@ -1272,7 +1272,7 @@ void DiagnosticsMatcher::RefCountedInsideLambdaChecker::run( const LambdaExpr *Lambda = Result.Nodes.getNodeAs("lambda"); for (const LambdaCapture Capture : Lambda->captures()) { - if (Capture.capturesVariable()) { + if (Capture.capturesVariable() && Capture.getCaptureKind() != LCK_ByRef) { QualType Pointee = Capture.getCapturedVar()->getType()->getPointeeType(); if (!Pointee.isNull() && isClassRefCounted(Pointee)) { diff --git a/build/clang-plugin/tests/TestNoRefcountedInsideLambdas.cpp b/build/clang-plugin/tests/TestNoRefcountedInsideLambdas.cpp index 35aac9dd6000..713760c20b3a 100644 --- a/build/clang-plugin/tests/TestNoRefcountedInsideLambdas.cpp +++ b/build/clang-plugin/tests/TestNoRefcountedInsideLambdas.cpp @@ -21,7 +21,7 @@ void foo() { SmartPtr sp; take([&](R* argptr) { R* localptr; - ptr->method(); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}} + ptr->method(); argptr->method(); localptr->method(); }); @@ -33,7 +33,7 @@ void foo() { }); take([&](R* argptr) { R* localptr; - take(ptr); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be captured by a lambda}} expected-note{{Please consider using a smart pointer}} + take(ptr); take(argptr); take(localptr); }); @@ -91,4 +91,28 @@ void foo() { take(argsp); take(localsp); }); + take([&ptr](R* argptr) { + R* localptr; + ptr->method(); + argptr->method(); + localptr->method(); + }); + take([&sp](SmartPtr argsp) { + SmartPtr localsp; + sp->method(); + argsp->method(); + localsp->method(); + }); + take([&ptr](R* argptr) { + R* localptr; + take(ptr); + take(argptr); + take(localptr); + }); + take([&sp](SmartPtr argsp) { + SmartPtr localsp; + take(sp); + take(argsp); + take(localsp); + }); }