зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1699844 - Add an escape hatch for the refcounted inside lambda checker. r=andi
Allow using the MOZ_KnownLive function to get around it. Use case is the following: I have an std::function member variable, and I want that member to be able to capture `this`. Using a strong reference creates a cycle and thus would leak. I know `this` to always outlive the member, so it is fine to use a weak capture there. Differential Revision: https://phabricator.services.mozilla.com/D111850
This commit is contained in:
Родитель
3bbb2fccca
Коммит
80439edf68
|
@ -36,6 +36,18 @@ void RefCountedInsideLambdaChecker::emitDiagnostics(SourceLocation Loc,
|
|||
diag(Loc, "Please consider using a smart pointer", DiagnosticIDs::Note);
|
||||
}
|
||||
|
||||
static bool IsKnownLive(const VarDecl *Var) {
|
||||
const Stmt *Init = Var->getInit();
|
||||
if (!Init) {
|
||||
return false;
|
||||
}
|
||||
if (auto *Call = dyn_cast<CallExpr>(Init)) {
|
||||
const FunctionDecl *Callee = Call->getDirectCallee();
|
||||
return Callee && Callee->getName() == "MOZ_KnownLive";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RefCountedInsideLambdaChecker::check(
|
||||
const MatchFinder::MatchResult &Result) {
|
||||
static DenseSet<const CXXRecordDecl *> CheckedDecls;
|
||||
|
@ -107,11 +119,11 @@ void RefCountedInsideLambdaChecker::check(
|
|||
// pointers.
|
||||
for (const LambdaCapture &Capture : Lambda->captures()) {
|
||||
if (Capture.capturesVariable()) {
|
||||
QualType Pointee = Capture.getCapturedVar()->getType()->getPointeeType();
|
||||
|
||||
if (!Pointee.isNull() && isClassRefCounted(Pointee)) {
|
||||
emitDiagnostics(Capture.getLocation(),
|
||||
Capture.getCapturedVar()->getName(), Pointee);
|
||||
const VarDecl *Var = Capture.getCapturedVar();
|
||||
QualType Pointee = Var->getType()->getPointeeType();
|
||||
if (!Pointee.isNull() && isClassRefCounted(Pointee) &&
|
||||
!IsKnownLive(Var)) {
|
||||
emitDiagnostics(Capture.getLocation(), Var->getName(), Pointee);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#include <mozilla/StaticAnalysisFunctions.h>
|
||||
|
||||
#include <functional>
|
||||
#define MOZ_STRONG_REF
|
||||
#define MOZ_IMPLICIT __attribute__((annotate("moz_implicit")))
|
||||
|
@ -667,6 +669,9 @@ R::privateMethod() {
|
|||
privateMethod();
|
||||
});
|
||||
|
||||
std::function<void()>(
|
||||
[instance = MOZ_KnownLive(this)]() { instance->privateMethod(); });
|
||||
|
||||
// It should be OK to go through `this` if we have captured a reference to it.
|
||||
std::function<void()>([this, self]() {
|
||||
this->method();
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# endif
|
||||
# define MOZ_CONSTEXPR
|
||||
#else // __cplusplus
|
||||
# include "mozilla/Attributes.h"
|
||||
# define MOZ_CONSTEXPR constexpr
|
||||
#endif
|
||||
/*
|
||||
|
|
Загрузка…
Ссылка в новой задаче