[alpha.webkit.NoDeleteChecker] Don't emit a warning for a function without annotation. (#178824)
This PR fixes the bug in alpha.webkit.NoDeleteChecker that it emits a
warning for any function without
[[clang::annotate_type("webkit.nodelete")]] annotation if it contains
non-trivial code. It also fixes a bug hat we weren't checking the
presence of the annotation on superclass' corresponding member
functions.
This commit is contained in:
parent
8f690ec7ff
commit
a34e89fcb5
@ -65,39 +65,31 @@ public:
|
||||
visitor.TraverseDecl(const_cast<TranslationUnitDecl *>(TUD));
|
||||
}
|
||||
|
||||
static bool hasNoDeleteAnnotation(const FunctionDecl *FD) {
|
||||
if (llvm::any_of(FD->redecls(), isNoDeleteFunction))
|
||||
return true;
|
||||
|
||||
const auto *MD = dyn_cast<CXXMethodDecl>(FD);
|
||||
if (!MD || !MD->isVirtual())
|
||||
return false;
|
||||
|
||||
auto Overriders = llvm::to_vector(MD->overridden_methods());
|
||||
while (!Overriders.empty()) {
|
||||
const auto *Fn = Overriders.pop_back_val();
|
||||
llvm::append_range(Overriders, Fn->overridden_methods());
|
||||
if (isNoDeleteFunction(Fn))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void visitFunctionDecl(const FunctionDecl *FD) const {
|
||||
if (!FD->doesThisDeclarationHaveABody())
|
||||
return;
|
||||
|
||||
bool HasNoDeleteAnnotation = isNoDeleteFunction(FD);
|
||||
if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
|
||||
if (auto *Cls = MD->getParent(); Cls && MD->isVirtual()) {
|
||||
CXXBasePaths Paths;
|
||||
Paths.setOrigin(Cls);
|
||||
|
||||
Cls->lookupInBases(
|
||||
[&](const CXXBaseSpecifier *Base, CXXBasePath &) {
|
||||
const Type *T = Base->getType().getTypePtrOrNull();
|
||||
if (!T)
|
||||
return false;
|
||||
|
||||
const CXXRecordDecl *R = T->getAsCXXRecordDecl();
|
||||
if (!R)
|
||||
return false;
|
||||
|
||||
for (const CXXMethodDecl *BaseMD : R->methods()) {
|
||||
if (BaseMD->getCorrespondingMethodInClass(Cls) == MD) {
|
||||
if (isNoDeleteFunction(FD)) {
|
||||
HasNoDeleteAnnotation = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
Paths, /*LookupInDependent =*/true);
|
||||
}
|
||||
}
|
||||
if (!hasNoDeleteAnnotation(FD))
|
||||
return;
|
||||
|
||||
auto Body = FD->getBody();
|
||||
if (!Body || TFA.isTrivial(Body))
|
||||
|
||||
@ -3,6 +3,10 @@
|
||||
void someFunction();
|
||||
void [[clang::annotate_type("webkit.nodelete")]] safeFunction();
|
||||
|
||||
void functionWithoutNoDeleteAnnotation() {
|
||||
someFunction();
|
||||
}
|
||||
|
||||
void [[clang::annotate_type("webkit.nodelete")]] callsUnsafe() {
|
||||
// expected-warning@-1{{A function 'callsUnsafe' has [[clang::annotate_type("webkit.nodelete")]] but it contains code that could destruct an object}}
|
||||
someFunction();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user