Backed out changeset 517de066cc6f (bug 1615826) for linting failures at CustomAttributes.cpp on a CLOSED TREE

This commit is contained in:
Andreea Pavel 2020-02-17 20:16:08 +02:00
Родитель 766d80fdda
Коммит ff331ccbb6
17 изменённых файлов: 208 добавлений и 168 удалений

Просмотреть файл

@ -55,10 +55,12 @@
void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) { void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
auto Refcounted = qualType(hasDeclaration(cxxRecordDecl(isRefCounted()))); auto Refcounted = qualType(hasDeclaration(cxxRecordDecl(isRefCounted())));
auto StackSmartPtr = auto StackSmartPtr =
ignoreTrivials(declRefExpr(to(varDecl(hasAutomaticStorageDuration())), ignoreTrivials(
declRefExpr(to(varDecl(hasAutomaticStorageDuration())),
hasType(isSmartPtrToRefCounted()))); hasType(isSmartPtrToRefCounted())));
auto ConstMemberOfThisSmartPtr = auto ConstMemberOfThisSmartPtr =
memberExpr(hasType(isSmartPtrToRefCounted()), hasType(isConstQualified()), memberExpr(hasType(isSmartPtrToRefCounted()),
hasType(isConstQualified()),
hasObjectExpression(cxxThisExpr())); hasObjectExpression(cxxThisExpr()));
// A smartptr can be known-live for three reasons: // A smartptr can be known-live for three reasons:
// 1) It's declared on the stack. // 1) It's declared on the stack.
@ -68,14 +70,15 @@ void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
// 3) It's an immediate temporary being constructed at the point where the // 3) It's an immediate temporary being constructed at the point where the
// call is happening. // call is happening.
auto KnownLiveSmartPtr = anyOf( auto KnownLiveSmartPtr = anyOf(
StackSmartPtr, ConstMemberOfThisSmartPtr, StackSmartPtr,
ConstMemberOfThisSmartPtr,
ignoreTrivials(cxxConstructExpr(hasType(isSmartPtrToRefCounted())))); ignoreTrivials(cxxConstructExpr(hasType(isSmartPtrToRefCounted()))));
auto MozKnownLiveCall = auto MozKnownLiveCall =
ignoreTrivials(callExpr(callee(functionDecl(hasName("MOZ_KnownLive"))))); ignoreTrivials(callExpr(callee(functionDecl(hasName("MOZ_KnownLive")))));
// Params of the calling function are presumed live, because it itself should // Params of the calling function are presumed live, because it itself should be
// be MOZ_CAN_RUN_SCRIPT. Note that this is subject to // MOZ_CAN_RUN_SCRIPT. Note that this is subject to
// https://bugzilla.mozilla.org/show_bug.cgi?id=1537656 a the moment. // https://bugzilla.mozilla.org/show_bug.cgi?id=1537656 a the moment.
auto KnownLiveParam = anyOf( auto KnownLiveParam = anyOf(
// "this" is OK // "this" is OK
@ -105,12 +108,15 @@ void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
// return non-live objects (e.g. consider "live_pointer->foo()" as an // return non-live objects (e.g. consider "live_pointer->foo()" as an
// example). For purposes of this analysis we are assuming the method // example). For purposes of this analysis we are assuming the method
// calls on smart ptrs all just return the pointer inside, // calls on smart ptrs all just return the pointer inside,
cxxMemberCallExpr( cxxMemberCallExpr(on(
on(allOf(hasType(isSmartPtrToRefCounted()), KnownLiveBase))), allOf(hasType(isSmartPtrToRefCounted()),
KnownLiveBase))),
// operator* or operator-> on a thing that is already known to be live. // operator* or operator-> on a thing that is already known to be live.
cxxOperatorCallExpr(anyOf(hasOverloadedOperatorName("*"), cxxOperatorCallExpr(
anyOf(hasOverloadedOperatorName("*"),
hasOverloadedOperatorName("->")), hasOverloadedOperatorName("->")),
hasAnyArgument(KnownLiveBase), argumentCountIs(1)), hasAnyArgument(KnownLiveBase),
argumentCountIs(1)),
// A dereference on a thing that is known to be live. This is _not_ // A dereference on a thing that is known to be live. This is _not_
// caught by the "operator* or operator->" clause above, because // caught by the "operator* or operator->" clause above, because
// cxxOperatorCallExpr() only catches cases when a class defines // cxxOperatorCallExpr() only catches cases when a class defines
@ -133,27 +139,37 @@ void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
// does not guarantee liveness; in fact the callee could modify those // does not guarantee liveness; in fact the callee could modify those
// things! In practice they would be the wrong type anyway, though, so // things! In practice they would be the wrong type anyway, though, so
// it's hard to add a test for this. // it's hard to add a test for this.
unaryOperator(hasOperatorName("&"), unaryOperator(
hasUnaryOperand(allOf(anyOf(hasType(references(Refcounted)), hasOperatorName("&"),
hasUnaryOperand(allOf(
anyOf(
hasType(references(Refcounted)),
hasType(Refcounted)), hasType(Refcounted)),
ignoreTrivials(KnownLiveBase))))); ignoreTrivials(KnownLiveBase))))
);
auto KnownLive = anyOf( auto KnownLive = anyOf(
// Anything above, of course. // Anything above, of course.
KnownLiveSimple, KnownLiveSimple,
// Conditional operators where both arms are live. // Conditional operators where both arms are live.
conditionalOperator(hasFalseExpression(ignoreTrivials(KnownLiveSimple)), conditionalOperator(
hasFalseExpression(ignoreTrivials(KnownLiveSimple)),
hasTrueExpression(ignoreTrivials(KnownLiveSimple))) hasTrueExpression(ignoreTrivials(KnownLiveSimple)))
// We're not handling cases like a dereference of a conditional operator, // We're not handling cases like a dereference of a conditional operator,
// mostly because handling a dereference in general is so ugly. I // mostly because handling a dereference in general is so ugly. I
// _really_ wish I could just write a recursive matcher here easily. // _really_ wish I could just write a recursive matcher here easily.
); );
auto InvalidArg = ignoreTrivialsConditional( auto InvalidArg =
ignoreTrivialsConditional(
// We want to consider things if there is anything refcounted involved, // We want to consider things if there is anything refcounted involved,
// including in any of the trivials that we otherwise strip off. // including in any of the trivials that we otherwise strip off.
anyOf(hasType(Refcounted), hasType(pointsTo(Refcounted)), anyOf(
hasType(references(Refcounted)), hasType(isSmartPtrToRefCounted())), hasType(Refcounted),
hasType(pointsTo(Refcounted)),
hasType(references(Refcounted)),
hasType(isSmartPtrToRefCounted())
),
// We want to find any expression, // We want to find any expression,
expr( expr(
// which is not known live, // which is not known live,
@ -162,7 +178,8 @@ void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
// always safe, // always safe,
unless(cxxDefaultArgExpr(isNullDefaultArg())), unless(cxxDefaultArgExpr(isNullDefaultArg())),
// and which is not a literal nullptr, // and which is not a literal nullptr,
unless(cxxNullPtrLiteralExpr()), expr().bind("invalidArg"))); unless(cxxNullPtrLiteralExpr()),
expr().bind("invalidArg")));
// A matcher which will mark the first invalid argument it finds invalid, but // A matcher which will mark the first invalid argument it finds invalid, but
// will always match, even if it finds no invalid arguments, so it doesn't // will always match, even if it finds no invalid arguments, so it doesn't
@ -186,7 +203,11 @@ void CanRunScriptChecker::registerMatchers(MatchFinder *AstMatcher) {
// which optionally has an invalid arg, // which optionally has an invalid arg,
OptionalInvalidExplicitArg, OptionalInvalidExplicitArg,
// or which optionally has an invalid this argument, // or which optionally has an invalid this argument,
anyOf(on(InvalidArg), anything()), expr().bind("callExpr")), anyOf(
on(InvalidArg),
anything()
),
expr().bind("callExpr")),
// or a regular call expression, // or a regular call expression,
callExpr( callExpr(
// which optionally has an invalid arg. // which optionally has an invalid arg.
@ -219,7 +240,8 @@ class FuncSetCallback : public MatchFinder::MatchCallback {
public: public:
FuncSetCallback(CanRunScriptChecker& Checker, FuncSetCallback(CanRunScriptChecker& Checker,
std::unordered_set<const FunctionDecl *> &FuncSet) std::unordered_set<const FunctionDecl *> &FuncSet)
: CanRunScriptFuncs(FuncSet), Checker(Checker) {} : CanRunScriptFuncs(FuncSet),
Checker(Checker) {}
void run(const MatchFinder::MatchResult &Result) override; void run(const MatchFinder::MatchResult &Result) override;
@ -261,7 +283,8 @@ void FuncSetCallback::checkOverriddenMethods(const CXXMethodDecl *Method) {
Checker.diag(Method->getLocation(), ErrorNonCanRunScriptOverridden, Checker.diag(Method->getLocation(), ErrorNonCanRunScriptOverridden,
DiagnosticIDs::Error); DiagnosticIDs::Error);
Checker.diag(OverriddenMethod->getLocation(), Checker.diag(OverriddenMethod->getLocation(),
NoteNonCanRunScriptOverridden, DiagnosticIDs::Note); NoteNonCanRunScriptOverridden,
DiagnosticIDs::Note);
} }
} }
} }
@ -277,7 +300,9 @@ void CanRunScriptChecker::buildFuncSet(ASTContext *Context) {
Finder.addMatcher( Finder.addMatcher(
functionDecl(hasCanRunScriptAnnotation()).bind("canRunScriptFunction"), functionDecl(hasCanRunScriptAnnotation()).bind("canRunScriptFunction"),
&Callback); &Callback);
Finder.addMatcher(lambdaExpr().bind("lambda"), &Callback); Finder.addMatcher(
lambdaExpr().bind("lambda"),
&Callback);
// We start the analysis, given the ASTContext our main checker is in. // We start the analysis, given the ASTContext our main checker is in.
Finder.matchAST(*Context); Finder.matchAST(*Context);
} }
@ -358,9 +383,11 @@ void CanRunScriptChecker::check(const MatchFinder::MatchResult &Result) {
// If we have an invalid argument in the call, we emit the diagnostic to // If we have an invalid argument in the call, we emit the diagnostic to
// signal it. // signal it.
if (InvalidArg) { if (InvalidArg) {
const std::string invalidArgText = Lexer::getSourceText( const std::string invalidArgText =
Lexer::getSourceText(
CharSourceRange::getTokenRange(InvalidArg->getSourceRange()), CharSourceRange::getTokenRange(InvalidArg->getSourceRange()),
Result.Context->getSourceManager(), Result.Context->getLangOpts()); Result.Context->getSourceManager(),
Result.Context->getLangOpts());
diag(InvalidArg->getExprLoc(), ErrorInvalidArg, DiagnosticIDs::Error) diag(InvalidArg->getExprLoc(), ErrorInvalidArg, DiagnosticIDs::Error)
<< InvalidArg->getSourceRange() << invalidArgText; << InvalidArg->getSourceRange() << invalidArgText;
} }

Просмотреть файл

@ -2,10 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <algorithm>
#include "CustomAttributes.h" #include "CustomAttributes.h"
#include "plugin.h" #include "plugin.h"
#include "clang/Frontend/FrontendPluginRegistry.h" #include "clang/Frontend/FrontendPluginRegistry.h"
#include <algorithm>
/* Having annotations in the AST unexpectedly impacts codegen. /* Having annotations in the AST unexpectedly impacts codegen.
* Ideally, we'd avoid having annotations at all, by using an API such as * Ideally, we'd avoid having annotations at all, by using an API such as
@ -28,7 +28,8 @@ using namespace llvm;
static DenseMap<const Decl*, CustomAttributesSet> AttributesCache; static DenseMap<const Decl*, CustomAttributesSet> AttributesCache;
static CustomAttributesSet CacheAttributes(const Decl *D) { static CustomAttributesSet CacheAttributes(const Decl* D)
{
CustomAttributesSet attrs = {}; CustomAttributesSet attrs = {};
for (auto Attr : D->specific_attrs<AnnotateAttr>()) { for (auto Attr : D->specific_attrs<AnnotateAttr>()) {
auto annotation = Attr->getAnnotation(); auto annotation = Attr->getAnnotation();
@ -45,15 +46,17 @@ static CustomAttributesSet CacheAttributes(const Decl *D) {
return attrs; return attrs;
} }
static void Report(const Decl *D, const char *message) { static void Report(const Decl* D, const char* message)
{
ASTContext& Context = D->getASTContext(); ASTContext& Context = D->getASTContext();
DiagnosticsEngine& Diag = Context.getDiagnostics(); DiagnosticsEngine& Diag = Context.getDiagnostics();
unsigned ID = unsigned ID = Diag.getDiagnosticIDs()->getCustomDiagID(
Diag.getDiagnosticIDs()->getCustomDiagID(DiagnosticIDs::Warning, message); DiagnosticIDs::Warning, message);
Diag.Report(D->getBeginLoc(), ID); Diag.Report(D->getBeginLoc(), ID);
} }
CustomAttributesSet GetAttributes(const Decl *D) { CustomAttributesSet GetAttributes(const Decl* D)
{
CustomAttributesSet attrs = {}; CustomAttributesSet attrs = {};
if (D->hasAttr<AnnotateAttr>()) { if (D->hasAttr<AnnotateAttr>()) {
Report(D, "Declaration has unhandled annotations."); Report(D, "Declaration has unhandled annotations.");
@ -67,22 +70,22 @@ CustomAttributesSet GetAttributes(const Decl *D) {
return attrs; return attrs;
} }
bool hasCustomAttribute(const clang::Decl *D, CustomAttributes A) { bool hasCustomAttribute(const clang::Decl* D, CustomAttributes A)
{
CustomAttributesSet attrs = GetAttributes(D); CustomAttributesSet attrs = GetAttributes(D);
switch (A) { switch (A) {
#define ATTR(a) \ #define ATTR(a) case a: return attrs.has_ ## a;
case a: \
return attrs.has_##a;
#include "CustomAttributes.inc" #include "CustomAttributes.inc"
#undef ATTR #undef ATTR
} }
return false; return false;
} }
class CustomAttributesMatcher class CustomAttributesMatcher : public ast_matchers::MatchFinder::MatchCallback {
: public ast_matchers::MatchFinder::MatchCallback {
public: public:
virtual void run(const ast_matchers::MatchFinder::MatchResult &Result) final { virtual void
run(const ast_matchers::MatchFinder::MatchResult &Result) final
{
if (auto D = Result.Nodes.getNodeAs<Decl>("decl")) { if (auto D = Result.Nodes.getNodeAs<Decl>("decl")) {
CacheAttributes(D); CacheAttributes(D);
} else if (auto L = Result.Nodes.getNodeAs<LambdaExpr>("lambda")) { } else if (auto L = Result.Nodes.getNodeAs<LambdaExpr>("lambda")) {
@ -98,8 +101,7 @@ public:
StringRef FileName) override { StringRef FileName) override {
auto& Context = CI.getASTContext(); auto& Context = CI.getASTContext();
auto AstMatcher = new (Context.Allocate<MatchFinder>()) MatchFinder(); auto AstMatcher = new (Context.Allocate<MatchFinder>()) MatchFinder();
auto Matcher = new (Context.Allocate<CustomAttributesMatcher>()) auto Matcher = new (Context.Allocate<CustomAttributesMatcher>()) CustomAttributesMatcher();
CustomAttributesMatcher();
AstMatcher->addMatcher(decl().bind("decl"), Matcher); AstMatcher->addMatcher(decl().bind("decl"), Matcher);
AstMatcher->addMatcher(lambdaExpr().bind("lambda"), Matcher); AstMatcher->addMatcher(lambdaExpr().bind("lambda"), Matcher);
return AstMatcher->newASTConsumer(); return AstMatcher->newASTConsumer();
@ -110,8 +112,11 @@ public:
return true; return true;
} }
ActionType getActionType() override { return AddBeforeMainAction; } ActionType getActionType() override {
return AddBeforeMainAction;
}
}; };
static FrontendPluginRegistry::Add<CustomAttributesAction> static FrontendPluginRegistry::Add<CustomAttributesAction> X(
X("moz-custom-attributes", "prepare custom attributes for moz-check"); "moz-custom-attributes",
"prepare custom attributes for moz-check");

Просмотреть файл

@ -20,14 +20,16 @@ struct CustomAttributesSet {
#undef ATTR #undef ATTR
}; };
template <CustomAttributes A> bool hasCustomAttribute(const clang::Decl *D) { template<CustomAttributes A>
bool hasCustomAttribute(const clang::Decl* D) {
return false; return false;
} }
extern CustomAttributesSet GetAttributes(const clang::Decl* D); extern CustomAttributesSet GetAttributes(const clang::Decl* D);
#define ATTR(name) \ #define ATTR(name) \
template <> inline bool hasCustomAttribute<name>(const clang::Decl *D) { \ template<> \
inline bool hasCustomAttribute<name>(const clang::Decl* D) { \
return GetAttributes(D).has_ ## name; \ return GetAttributes(D).has_ ## name; \
} }
#include "CustomAttributes.inc" #include "CustomAttributes.inc"

Просмотреть файл

@ -224,17 +224,18 @@ AST_MATCHER_P(Expr, ignoreTrivials, internal::Matcher<Expr>, InnerMatcher) {
return InnerMatcher.matches(*IgnoreTrivials(&Node), Finder, Builder); return InnerMatcher.matches(*IgnoreTrivials(&Node), Finder, Builder);
} }
// Takes two matchers: the first one is a condition; the second is a matcher to // Takes two matchers: the first one is a condition; the second is a matcher to be
// be applied once we are done unwrapping trivials. While the condition does // applied once we are done unwrapping trivials. While the condition does not match
// not match and we're looking at a trivial, will keep unwrapping the trivial // and we're looking at a trivial, will keep unwrapping the trivial and trying again.
// and trying again. Once the condition matches, we will go ahead and unwrap all // Once the condition matches, we will go ahead and unwrap all trivials and apply the
// trivials and apply the inner matcher to the result. // inner matcher to the result.
// //
// The expected use here is if we want to condition a match on some typecheck // The expected use here is if we want to condition a match on some typecheck but
// but apply the match to only non-trivials, because there are trivials (e.g. // apply the match to only non-trivials, because there are trivials (e.g. casts) that
// casts) that can change types. // can change types.
AST_MATCHER_P2(Expr, ignoreTrivialsConditional, internal::Matcher<Expr>, AST_MATCHER_P2(Expr, ignoreTrivialsConditional,
Condition, internal::Matcher<Expr>, InnerMatcher) { internal::Matcher<Expr>, Condition,
internal::Matcher<Expr>, InnerMatcher) {
const Expr *node = &Node; const Expr *node = &Node;
while (true) { while (true) {
if (Condition.matches(*node, Finder, Builder)) { if (Condition.matches(*node, Finder, Builder)) {
@ -317,8 +318,7 @@ AST_MATCHER(QualType, isSmartPtrToRefCounted) {
} }
AST_MATCHER(ClassTemplateSpecializationDecl, isSmartPtrToRefCountedDecl) { AST_MATCHER(ClassTemplateSpecializationDecl, isSmartPtrToRefCountedDecl) {
auto *D = dyn_cast_or_null<CXXRecordDecl>( auto *D = dyn_cast_or_null<CXXRecordDecl>(Node.getSpecializedTemplate()->getTemplatedDecl());
Node.getSpecializedTemplate()->getTemplatedDecl());
if (!D) { if (!D) {
return false; return false;
} }
@ -328,6 +328,7 @@ AST_MATCHER(ClassTemplateSpecializationDecl, isSmartPtrToRefCountedDecl) {
return D && hasCustomAttribute<moz_is_smartptr_to_refcounted>(D); return D && hasCustomAttribute<moz_is_smartptr_to_refcounted>(D);
} }
AST_MATCHER(CXXRecordDecl, hasBaseClasses) { AST_MATCHER(CXXRecordDecl, hasBaseClasses) {
const CXXRecordDecl *Decl = Node.getCanonicalDecl(); const CXXRecordDecl *Decl = Node.getCanonicalDecl();
@ -347,8 +348,7 @@ AST_MATCHER(CXXMethodDecl, isNonVirtual) {
AST_MATCHER(FunctionDecl, isMozMustReturnFromCaller) { AST_MATCHER(FunctionDecl, isMozMustReturnFromCaller) {
const FunctionDecl *Decl = Node.getCanonicalDecl(); const FunctionDecl *Decl = Node.getCanonicalDecl();
return Decl && return Decl && hasCustomAttribute<moz_must_return_from_caller_if_this_is_arg>(Decl);
hasCustomAttribute<moz_must_return_from_caller_if_this_is_arg>(Decl);
} }
/// This matcher will select default args which have nullptr as the value. /// This matcher will select default args which have nullptr as the value.

Просмотреть файл

@ -42,12 +42,12 @@ void DanglingOnTemporaryChecker::registerMatchers(MatchFinder *AstMatcher) {
// Main checker // // Main checker //
////////////////// //////////////////
auto hasParentCall = hasParent( auto hasParentCall = hasParent(expr(
expr(anyOf(cxxOperatorCallExpr( anyOf(cxxOperatorCallExpr(
// If we're in a lamda, we may have an operator call // If we're in a lamda, we may have an operator call expression
// expression ancestor in the AST, but the temporary we're // ancestor in the AST, but the temporary we're matching
// matching against is not going to have the same lifetime // against is not going to have the same lifetime as the
// as the constructor call. // constructor call.
unless(has(expr(ignoreTrivials(lambdaExpr())))), unless(has(expr(ignoreTrivials(lambdaExpr())))),
expr().bind("parentOperatorCallExpr")), expr().bind("parentOperatorCallExpr")),
callExpr( callExpr(
@ -58,10 +58,10 @@ void DanglingOnTemporaryChecker::registerMatchers(MatchFinder *AstMatcher) {
unless(has(expr(ignoreTrivials(lambdaExpr())))), unless(has(expr(ignoreTrivials(lambdaExpr())))),
expr().bind("parentCallExpr")), expr().bind("parentCallExpr")),
objcMessageExpr( objcMessageExpr(
// If we're in a lamda, we may have an objc message // If we're in a lamda, we may have an objc message expression
// expression ancestor in the AST, but the temporary we're // ancestor in the AST, but the temporary we're matching
// matching against is not going to have the same lifetime // against is not going to have the same lifetime as the
// as the function call. // function call.
unless(has(expr(ignoreTrivials(lambdaExpr())))), unless(has(expr(ignoreTrivials(lambdaExpr())))),
expr().bind("parentObjCMessageExpr")), expr().bind("parentObjCMessageExpr")),
cxxConstructExpr( cxxConstructExpr(

Просмотреть файл

@ -21,7 +21,8 @@ void ExplicitOperatorBoolChecker::check(
Result.Nodes.getNodeAs<CXXConversionDecl>("node"); Result.Nodes.getNodeAs<CXXConversionDecl>("node");
const CXXRecordDecl *Clazz = Method->getParent(); const CXXRecordDecl *Clazz = Method->getParent();
if (!Method->isExplicit() && !hasCustomAttribute<moz_implicit>(Method) && if (!Method->isExplicit() &&
!hasCustomAttribute<moz_implicit>(Method) &&
!ASTIsInSystemHeader(Method->getASTContext(), *Method) && !ASTIsInSystemHeader(Method->getASTContext(), *Method) &&
isInterestingDeclForImplicitConversion(Method)) { isInterestingDeclForImplicitConversion(Method)) {
diag(Method->getBeginLoc(), "bad implicit conversion operator for %0", diag(Method->getBeginLoc(), "bad implicit conversion operator for %0",

Просмотреть файл

@ -9,7 +9,8 @@
class FopenUsageChecker : public BaseCheck { class FopenUsageChecker : public BaseCheck {
public: public:
FopenUsageChecker(StringRef CheckName, ContextType *Context = nullptr) FopenUsageChecker(StringRef CheckName,
ContextType *Context = nullptr)
: BaseCheck(CheckName, Context) {} : BaseCheck(CheckName, Context) {}
void registerMatchers(MatchFinder* AstMatcher) override; void registerMatchers(MatchFinder* AstMatcher) override;
void check(const MatchFinder::MatchResult &Result) override; void check(const MatchFinder::MatchResult &Result) override;

Просмотреть файл

@ -6,7 +6,8 @@
#include "CustomMatchers.h" #include "CustomMatchers.h"
void KungFuDeathGripChecker::registerMatchers(MatchFinder *AstMatcher) { void KungFuDeathGripChecker::registerMatchers(MatchFinder *AstMatcher) {
AstMatcher->addMatcher(varDecl(allOf(hasType(isRefPtr()), hasLocalStorage(), AstMatcher->addMatcher(varDecl(allOf(hasType(isRefPtr()),
hasLocalStorage(),
hasInitializer(anything()))) hasInitializer(anything())))
.bind("decl"), .bind("decl"),
this); this);

Просмотреть файл

@ -5,8 +5,7 @@
#include "NoUsingNamespaceMozillaJavaChecker.h" #include "NoUsingNamespaceMozillaJavaChecker.h"
#include "CustomMatchers.h" #include "CustomMatchers.h"
void NoUsingNamespaceMozillaJavaChecker::registerMatchers( void NoUsingNamespaceMozillaJavaChecker::registerMatchers(MatchFinder *AstMatcher) {
MatchFinder *AstMatcher) {
AstMatcher->addMatcher( AstMatcher->addMatcher(
usingDirectiveDecl(isUsingNamespaceMozillaJava()).bind("directive"), usingDirectiveDecl(isUsingNamespaceMozillaJava()).bind("directive"),
this); this);
@ -18,7 +17,9 @@ void NoUsingNamespaceMozillaJavaChecker::check(
Result.Nodes.getNodeAs<UsingDirectiveDecl>("directive"); Result.Nodes.getNodeAs<UsingDirectiveDecl>("directive");
const NamespaceDecl *Namespace = Directive->getNominatedNamespace(); const NamespaceDecl *Namespace = Directive->getNominatedNamespace();
diag(Directive->getUsingLoc(), "using namespace %0 is forbidden", diag(Directive->getUsingLoc(),
"using namespace %0 is forbidden",
DiagnosticIDs::Error) DiagnosticIDs::Error)
<< Namespace->getQualifiedNameAsString(); << Namespace->getQualifiedNameAsString();
} }

Просмотреть файл

@ -17,3 +17,4 @@ public:
}; };
#endif #endif

Просмотреть файл

@ -7,8 +7,7 @@
void ParamTraitsEnumChecker::registerMatchers(MatchFinder* AstMatcher) { void ParamTraitsEnumChecker::registerMatchers(MatchFinder* AstMatcher) {
AstMatcher->addMatcher( AstMatcher->addMatcher(
classTemplateSpecializationDecl(hasName("ParamTraits")).bind("decl"), classTemplateSpecializationDecl(hasName("ParamTraits")).bind("decl"), this);
this);
} }
void ParamTraitsEnumChecker::check(const MatchFinder::MatchResult &Result) { void ParamTraitsEnumChecker::check(const MatchFinder::MatchResult &Result) {

Просмотреть файл

@ -9,7 +9,8 @@
class ParamTraitsEnumChecker : public BaseCheck { class ParamTraitsEnumChecker : public BaseCheck {
public: public:
ParamTraitsEnumChecker(StringRef CheckName, ContextType *Context = nullptr) ParamTraitsEnumChecker(StringRef CheckName,
ContextType *Context = nullptr)
: BaseCheck(CheckName, Context) {} : BaseCheck(CheckName, Context) {}
void registerMatchers(MatchFinder* AstMatcher) override; void registerMatchers(MatchFinder* AstMatcher) override;
void check(const MatchFinder::MatchResult &Result) override; void check(const MatchFinder::MatchResult &Result) override;

Просмотреть файл

@ -10,9 +10,8 @@ void ScopeChecker::registerMatchers(MatchFinder *AstMatcher) {
AstMatcher->addMatcher(cxxNewExpr().bind("node"), this); AstMatcher->addMatcher(cxxNewExpr().bind("node"), this);
AstMatcher->addMatcher( AstMatcher->addMatcher(
materializeTemporaryExpr( materializeTemporaryExpr(
unless(hasDescendant(cxxConstructExpr(allowsTemporary())))) unless(hasDescendant(cxxConstructExpr(allowsTemporary())))
.bind("node"), ).bind("node"), this);
this);
AstMatcher->addMatcher( AstMatcher->addMatcher(
callExpr(callee(functionDecl(heapAllocator()))).bind("node"), this); callExpr(callee(functionDecl(heapAllocator()))).bind("node"), this);
} }
@ -40,7 +39,8 @@ void ScopeChecker::check(const MatchFinder::MatchResult &Result) {
QualType T; QualType T;
bool IsStaticLocal = false; bool IsStaticLocal = false;
if (const ParmVarDecl *D = Result.Nodes.getNodeAs<ParmVarDecl>("node")) { if (const ParmVarDecl *D =
Result.Nodes.getNodeAs<ParmVarDecl>("node")) {
if (D->hasUnparsedDefaultArg() || D->hasUninstantiatedDefaultArg()) { if (D->hasUnparsedDefaultArg() || D->hasUninstantiatedDefaultArg()) {
return; return;
} }

Просмотреть файл

@ -6,7 +6,8 @@
#include "CustomMatchers.h" #include "CustomMatchers.h"
void TrivialDtorChecker::registerMatchers(MatchFinder *AstMatcher) { void TrivialDtorChecker::registerMatchers(MatchFinder *AstMatcher) {
AstMatcher->addMatcher(cxxRecordDecl(hasTrivialDtor()).bind("node"), this); AstMatcher->addMatcher(cxxRecordDecl(hasTrivialDtor()).bind("node"),
this);
} }
void TrivialDtorChecker::check(const MatchFinder::MatchResult &Result) { void TrivialDtorChecker::check(const MatchFinder::MatchResult &Result) {