Bug 1170388 - Restrict the static analysis error given about raw pointers to refcounted objects inside a lambda, to the case where the raw pointer is captured. r=ehsan

--HG--
extra : rebase_source : c76a1dbb2942a07788ec1e87bc5edab79bfee3f5
extra : source : 4abfbfd822789a609c5a7c8c7eef499c776ba489
This commit is contained in:
Botond Ballo 2015-06-03 16:51:36 -04:00
parent 638d83d097
commit f03fd8179e
2 changed files with 66 additions and 24 deletions

View File

@ -704,8 +704,14 @@ DiagnosticsMatcher::DiagnosticsMatcher()
).bind("node"),
&noAddRefReleaseOnReturnChecker);
// Match declrefs with type "pointer to object of ref-counted type" inside a
// lambda, where the declaration they reference is not inside the lambda.
// This excludes arguments and local variables, leaving only captured
// variables.
astMatcher.addMatcher(lambdaExpr(
hasDescendant(declRefExpr(hasType(pointerType(pointee(isRefCounted())))).bind("node"))
hasDescendant(declRefExpr(hasType(pointerType(pointee(isRefCounted()))),
to(decl().bind("decl"))).bind("declref")),
unless(hasDescendant(decl(equalsBoundNode("decl"))))
),
&refCountedInsideLambdaChecker);
@ -917,14 +923,14 @@ void DiagnosticsMatcher::RefCountedInsideLambdaChecker::run(
const MatchFinder::MatchResult &Result) {
DiagnosticsEngine &Diag = Result.Context->getDiagnostics();
unsigned errorID = Diag.getDiagnosticIDs()->getCustomDiagID(
DiagnosticIDs::Error, "Refcounted variable %0 of type %1 cannot be used inside a lambda");
DiagnosticIDs::Error, "Refcounted variable %0 of type %1 cannot be captured by a lambda");
unsigned noteID = Diag.getDiagnosticIDs()->getCustomDiagID(
DiagnosticIDs::Note, "Please consider using a smart pointer");
const DeclRefExpr *node = Result.Nodes.getNodeAs<DeclRefExpr>("node");
const DeclRefExpr *declref = Result.Nodes.getNodeAs<DeclRefExpr>("declref");
Diag.Report(node->getLocStart(), errorID) << node->getFoundDecl() <<
node->getType()->getPointeeType();
Diag.Report(node->getLocStart(), noteID);
Diag.Report(declref->getLocStart(), errorID) << declref->getFoundDecl() <<
declref->getType()->getPointeeType();
Diag.Report(declref->getLocStart(), noteID);
}
void DiagnosticsMatcher::ExplicitOperatorBoolChecker::run(

View File

@ -19,40 +19,76 @@ void take(...);
void foo() {
R* ptr;
SmartPtr<R> sp;
take([&]() {
ptr->method(); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be used inside a lambda}} expected-note{{Please consider using a smart pointer}}
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}}
argptr->method();
localptr->method();
});
take([&]() {
take([&](SmartPtr<R> argsp) {
SmartPtr<R> localsp;
sp->method();
argsp->method();
localsp->method();
});
take([&]() {
take(ptr); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be used inside a lambda}} expected-note{{Please consider using a smart pointer}}
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(argptr);
take(localptr);
});
take([&]() {
take([&](SmartPtr<R> argsp) {
SmartPtr<R> localsp;
take(sp);
take(argsp);
take(localsp);
});
take([=]() {
ptr->method(); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be used inside a lambda}} expected-note{{Please consider using a smart pointer}}
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}}
argptr->method();
localptr->method();
});
take([=]() {
take([=](SmartPtr<R> argsp) {
SmartPtr<R> localsp;
sp->method();
argsp->method();
localsp->method();
});
take([=]() {
take(ptr); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be used inside a lambda}} expected-note{{Please consider using a smart pointer}}
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(argptr);
take(localptr);
});
take([=]() {
take([=](SmartPtr<R> argsp) {
SmartPtr<R> localsp;
take(sp);
take(argsp);
take(localsp);
});
take([ptr]() {
ptr->method(); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be used inside a lambda}} expected-note{{Please consider using a smart pointer}}
take([ptr](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}}
argptr->method();
localptr->method();
});
take([sp]() {
take([sp](SmartPtr<R> argsp) {
SmartPtr<R> localsp;
sp->method();
argsp->method();
localsp->method();
});
take([ptr]() {
take(ptr); // expected-error{{Refcounted variable 'ptr' of type 'R' cannot be used inside a lambda}} expected-note{{Please consider using a smart pointer}}
take([ptr](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(argptr);
take(localptr);
});
take([sp]() {
take([sp](SmartPtr<R> argsp) {
SmartPtr<R> localsp;
take(sp);
take(argsp);
take(localsp);
});
}