Disable clang-tidy misc checkers when not compiling in C++ mode. Many of the checkers do not require additional testing as the tests will not compile for other languages or modes, or the checkers would never match a valid construct.
git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@246318 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
c9bb1cff21
Коммит
fbf0ffc607
|
@ -19,31 +19,37 @@ namespace misc {
|
|||
|
||||
void AssignOperatorSignatureCheck::registerMatchers(
|
||||
ast_matchers::MatchFinder *Finder) {
|
||||
const auto HasGoodReturnType = methodDecl(returns(lValueReferenceType(pointee(
|
||||
unless(isConstQualified()), hasDeclaration(equalsBoundNode("class"))))));
|
||||
// Only register the matchers for C++; the functionality currently does not
|
||||
// provide any benefit to other languages, despite being benign.
|
||||
if (getLangOpts().CPlusPlus) {
|
||||
const auto HasGoodReturnType = methodDecl(returns(lValueReferenceType(
|
||||
pointee(unless(isConstQualified()),
|
||||
hasDeclaration(equalsBoundNode("class"))))));
|
||||
|
||||
const auto IsSelf = qualType(
|
||||
anyOf(hasDeclaration(equalsBoundNode("class")),
|
||||
referenceType(pointee(hasDeclaration(equalsBoundNode("class"))))));
|
||||
const auto IsSelfAssign =
|
||||
methodDecl(unless(anyOf(isDeleted(), isPrivate(), isImplicit())),
|
||||
hasName("operator="), ofClass(recordDecl().bind("class")),
|
||||
hasParameter(0, parmVarDecl(hasType(IsSelf)))).bind("method");
|
||||
const auto IsSelf = qualType(anyOf(
|
||||
hasDeclaration(equalsBoundNode("class")),
|
||||
referenceType(pointee(hasDeclaration(equalsBoundNode("class"))))));
|
||||
const auto IsSelfAssign =
|
||||
methodDecl(unless(anyOf(isDeleted(), isPrivate(), isImplicit())),
|
||||
hasName("operator="), ofClass(recordDecl().bind("class")),
|
||||
hasParameter(0, parmVarDecl(hasType(IsSelf))))
|
||||
.bind("method");
|
||||
|
||||
Finder->addMatcher(
|
||||
methodDecl(IsSelfAssign, unless(HasGoodReturnType)).bind("ReturnType"),
|
||||
this);
|
||||
Finder->addMatcher(
|
||||
methodDecl(IsSelfAssign, unless(HasGoodReturnType)).bind("ReturnType"),
|
||||
this);
|
||||
|
||||
const auto BadSelf = referenceType(
|
||||
anyOf(lValueReferenceType(pointee(unless(isConstQualified()))),
|
||||
rValueReferenceType(pointee(isConstQualified()))));
|
||||
const auto BadSelf = referenceType(
|
||||
anyOf(lValueReferenceType(pointee(unless(isConstQualified()))),
|
||||
rValueReferenceType(pointee(isConstQualified()))));
|
||||
|
||||
Finder->addMatcher(
|
||||
methodDecl(IsSelfAssign, hasParameter(0, parmVarDecl(hasType(BadSelf))))
|
||||
.bind("ArgumentType"),
|
||||
this);
|
||||
Finder->addMatcher(
|
||||
methodDecl(IsSelfAssign, hasParameter(0, parmVarDecl(hasType(BadSelf))))
|
||||
.bind("ArgumentType"),
|
||||
this);
|
||||
|
||||
Finder->addMatcher(methodDecl(IsSelfAssign, isConst()).bind("Const"), this);
|
||||
Finder->addMatcher(methodDecl(IsSelfAssign, isConst()).bind("Const"), this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,21 +19,27 @@ namespace tidy {
|
|||
namespace misc {
|
||||
|
||||
void InaccurateEraseCheck::registerMatchers(MatchFinder *Finder) {
|
||||
const auto CheckForEndCall = hasArgument(
|
||||
1,
|
||||
anyOf(constructExpr(has(memberCallExpr(callee(methodDecl(hasName("end"))))
|
||||
.bind("InaccEndCall"))),
|
||||
anything()));
|
||||
// Only register the matchers for C++; the functionality currently does not
|
||||
// provide any benefit to other languages, despite being benign.
|
||||
if (getLangOpts().CPlusPlus) {
|
||||
const auto CheckForEndCall = hasArgument(
|
||||
1, anyOf(constructExpr(
|
||||
has(memberCallExpr(callee(methodDecl(hasName("end"))))
|
||||
.bind("InaccEndCall"))),
|
||||
anything()));
|
||||
|
||||
Finder->addMatcher(
|
||||
memberCallExpr(
|
||||
on(hasType(namedDecl(matchesName("^::std::")))),
|
||||
callee(methodDecl(hasName("erase"))), argumentCountIs(1),
|
||||
hasArgument(0, has(callExpr(callee(functionDecl(matchesName(
|
||||
"^::std::(remove(_if)?|unique)$"))),
|
||||
CheckForEndCall).bind("InaccAlgCall"))),
|
||||
unless(isInTemplateInstantiation())).bind("InaccErase"),
|
||||
this);
|
||||
Finder->addMatcher(
|
||||
memberCallExpr(
|
||||
on(hasType(namedDecl(matchesName("^::std::")))),
|
||||
callee(methodDecl(hasName("erase"))), argumentCountIs(1),
|
||||
hasArgument(0, has(callExpr(callee(functionDecl(matchesName(
|
||||
"^::std::(remove(_if)?|unique)$"))),
|
||||
CheckForEndCall)
|
||||
.bind("InaccAlgCall"))),
|
||||
unless(isInTemplateInstantiation()))
|
||||
.bind("InaccErase"),
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
void InaccurateEraseCheck::check(const MatchFinder::MatchResult &Result) {
|
||||
|
|
|
@ -28,30 +28,35 @@ static bool areTypesCompatible(QualType Left, QualType Right) {
|
|||
}
|
||||
|
||||
void InefficientAlgorithmCheck::registerMatchers(MatchFinder *Finder) {
|
||||
const std::string Algorithms =
|
||||
"^::std::(find|count|equal_range|lower_bound|upper_bound)$";
|
||||
const auto ContainerMatcher = classTemplateSpecializationDecl(
|
||||
matchesName("^::std::(unordered_)?(multi)?(set|map)$"));
|
||||
const auto Matcher =
|
||||
callExpr(
|
||||
callee(functionDecl(matchesName(Algorithms))),
|
||||
hasArgument(
|
||||
0, constructExpr(has(memberCallExpr(
|
||||
callee(methodDecl(hasName("begin"))),
|
||||
on(declRefExpr(
|
||||
hasDeclaration(decl().bind("IneffContObj")),
|
||||
anyOf(hasType(ContainerMatcher.bind("IneffCont")),
|
||||
hasType(pointsTo(
|
||||
ContainerMatcher.bind("IneffContPtr")))))
|
||||
.bind("IneffContExpr")))))),
|
||||
hasArgument(1, constructExpr(has(memberCallExpr(
|
||||
callee(methodDecl(hasName("end"))),
|
||||
on(declRefExpr(hasDeclaration(
|
||||
equalsBoundNode("IneffContObj")))))))),
|
||||
hasArgument(2, expr().bind("AlgParam")),
|
||||
unless(isInTemplateInstantiation())).bind("IneffAlg");
|
||||
// Only register the matchers for C++; the functionality currently does not
|
||||
// provide any benefit to other languages, despite being benign.
|
||||
if (getLangOpts().CPlusPlus) {
|
||||
const std::string Algorithms =
|
||||
"^::std::(find|count|equal_range|lower_bound|upper_bound)$";
|
||||
const auto ContainerMatcher = classTemplateSpecializationDecl(
|
||||
matchesName("^::std::(unordered_)?(multi)?(set|map)$"));
|
||||
const auto Matcher =
|
||||
callExpr(
|
||||
callee(functionDecl(matchesName(Algorithms))),
|
||||
hasArgument(
|
||||
0, constructExpr(has(memberCallExpr(
|
||||
callee(methodDecl(hasName("begin"))),
|
||||
on(declRefExpr(
|
||||
hasDeclaration(decl().bind("IneffContObj")),
|
||||
anyOf(hasType(ContainerMatcher.bind("IneffCont")),
|
||||
hasType(pointsTo(ContainerMatcher.bind(
|
||||
"IneffContPtr")))))
|
||||
.bind("IneffContExpr")))))),
|
||||
hasArgument(1, constructExpr(has(memberCallExpr(
|
||||
callee(methodDecl(hasName("end"))),
|
||||
on(declRefExpr(hasDeclaration(
|
||||
equalsBoundNode("IneffContObj")))))))),
|
||||
hasArgument(2, expr().bind("AlgParam")),
|
||||
unless(isInTemplateInstantiation()))
|
||||
.bind("IneffAlg");
|
||||
|
||||
Finder->addMatcher(Matcher, this);
|
||||
Finder->addMatcher(Matcher, this);
|
||||
}
|
||||
}
|
||||
|
||||
void InefficientAlgorithmCheck::check(const MatchFinder::MatchResult &Result) {
|
||||
|
|
|
@ -17,15 +17,19 @@ namespace clang {
|
|||
namespace tidy {
|
||||
|
||||
void MoveConstructorInitCheck::registerMatchers(MatchFinder *Finder) {
|
||||
Finder->addMatcher(
|
||||
constructorDecl(unless(isImplicit()), allOf(
|
||||
isMoveConstructor(),
|
||||
hasAnyConstructorInitializer(
|
||||
ctorInitializer(withInitializer(constructExpr(hasDeclaration(
|
||||
constructorDecl(isCopyConstructor()).bind("ctor")
|
||||
)))).bind("init")
|
||||
)
|
||||
)), this);
|
||||
// Only register the matchers for C++11; the functionality currently does not
|
||||
// provide any benefit to other languages, despite being benign.
|
||||
if (getLangOpts().CPlusPlus11) {
|
||||
Finder->addMatcher(
|
||||
constructorDecl(unless(isImplicit()), allOf(
|
||||
isMoveConstructor(),
|
||||
hasAnyConstructorInitializer(
|
||||
ctorInitializer(withInitializer(constructExpr(hasDeclaration(
|
||||
constructorDecl(isCopyConstructor()).bind("ctor")
|
||||
)))).bind("init")
|
||||
)
|
||||
)), this);
|
||||
}
|
||||
}
|
||||
|
||||
void MoveConstructorInitCheck::check(const MatchFinder::MatchResult &Result) {
|
||||
|
|
|
@ -17,11 +17,15 @@ namespace clang {
|
|||
namespace tidy {
|
||||
|
||||
void NoexceptMoveConstructorCheck::registerMatchers(MatchFinder *Finder) {
|
||||
Finder->addMatcher(
|
||||
methodDecl(anyOf(constructorDecl(), hasOverloadedOperatorName("=")),
|
||||
unless(isImplicit()), unless(isDeleted()))
|
||||
.bind("decl"),
|
||||
this);
|
||||
// Only register the matchers for C++11; the functionality currently does not
|
||||
// provide any benefit to other languages, despite being benign.
|
||||
if (getLangOpts().CPlusPlus11) {
|
||||
Finder->addMatcher(
|
||||
methodDecl(anyOf(constructorDecl(), hasOverloadedOperatorName("=")),
|
||||
unless(isImplicit()), unless(isDeleted()))
|
||||
.bind("decl"),
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
void NoexceptMoveConstructorCheck::check(
|
||||
|
|
|
@ -27,34 +27,47 @@ StaticAssertCheck::StaticAssertCheck(StringRef Name, ClangTidyContext *Context)
|
|||
: ClangTidyCheck(Name, Context) {}
|
||||
|
||||
void StaticAssertCheck::registerMatchers(MatchFinder *Finder) {
|
||||
auto IsAlwaysFalse = expr(ignoringParenImpCasts(
|
||||
expr(anyOf(boolLiteral(equals(false)), integerLiteral(equals(0)),
|
||||
nullPtrLiteralExpr(), gnuNullExpr())).bind("isAlwaysFalse")));
|
||||
auto IsAlwaysFalseWithCast = ignoringParenImpCasts(anyOf(IsAlwaysFalse,
|
||||
cStyleCastExpr(has(IsAlwaysFalse)).bind("castExpr")));
|
||||
auto AssertExprRoot = anyOf(
|
||||
binaryOperator(
|
||||
anyOf(hasOperatorName("&&"), hasOperatorName("==")),
|
||||
hasEitherOperand(ignoringImpCasts(stringLiteral().bind("assertMSG"))),
|
||||
anyOf(binaryOperator(hasEitherOperand(IsAlwaysFalseWithCast)),
|
||||
anything())).bind("assertExprRoot"),
|
||||
IsAlwaysFalse);
|
||||
auto NonConstexprFunctionCall =
|
||||
callExpr(hasDeclaration(functionDecl(unless(isConstexpr()))));
|
||||
auto AssertCondition = expr(anyOf(
|
||||
expr(ignoringParenCasts(anyOf(
|
||||
AssertExprRoot,
|
||||
unaryOperator(hasUnaryOperand(ignoringParenCasts(AssertExprRoot)))))),
|
||||
anything()), unless(findAll(NonConstexprFunctionCall))).bind("condition");
|
||||
auto Condition = anyOf(ignoringParenImpCasts(callExpr(
|
||||
hasDeclaration(functionDecl(hasName("__builtin_expect"))),
|
||||
hasArgument(0, AssertCondition))), AssertCondition);
|
||||
// FIXME: I don't see why this checker couldn't also be interesting for
|
||||
// _Static_assert in C11, or static_assert if <assert.h> has been included,
|
||||
// but it is currently only enabled for C++11. Investigate.
|
||||
if (getLangOpts().CPlusPlus11) {
|
||||
auto IsAlwaysFalse = expr(ignoringParenImpCasts(
|
||||
expr(anyOf(boolLiteral(equals(false)), integerLiteral(equals(0)),
|
||||
nullPtrLiteralExpr(), gnuNullExpr()))
|
||||
.bind("isAlwaysFalse")));
|
||||
auto IsAlwaysFalseWithCast = ignoringParenImpCasts(anyOf(
|
||||
IsAlwaysFalse, cStyleCastExpr(has(IsAlwaysFalse)).bind("castExpr")));
|
||||
auto AssertExprRoot =
|
||||
anyOf(binaryOperator(
|
||||
anyOf(hasOperatorName("&&"), hasOperatorName("==")),
|
||||
hasEitherOperand(
|
||||
ignoringImpCasts(stringLiteral().bind("assertMSG"))),
|
||||
anyOf(binaryOperator(hasEitherOperand(IsAlwaysFalseWithCast)),
|
||||
anything()))
|
||||
.bind("assertExprRoot"),
|
||||
IsAlwaysFalse);
|
||||
auto NonConstexprFunctionCall =
|
||||
callExpr(hasDeclaration(functionDecl(unless(isConstexpr()))));
|
||||
auto AssertCondition =
|
||||
expr(anyOf(expr(ignoringParenCasts(
|
||||
anyOf(AssertExprRoot,
|
||||
unaryOperator(hasUnaryOperand(
|
||||
ignoringParenCasts(AssertExprRoot)))))),
|
||||
anything()),
|
||||
unless(findAll(NonConstexprFunctionCall)))
|
||||
.bind("condition");
|
||||
auto Condition =
|
||||
anyOf(ignoringParenImpCasts(callExpr(
|
||||
hasDeclaration(functionDecl(hasName("__builtin_expect"))),
|
||||
hasArgument(0, AssertCondition))),
|
||||
AssertCondition);
|
||||
|
||||
Finder->addMatcher(
|
||||
stmt(anyOf(conditionalOperator(hasCondition(Condition)),
|
||||
ifStmt(hasCondition(Condition))),
|
||||
unless(isInTemplateInstantiation())).bind("condStmt"),
|
||||
this);
|
||||
Finder->addMatcher(stmt(anyOf(conditionalOperator(hasCondition(Condition)),
|
||||
ifStmt(hasCondition(Condition))),
|
||||
unless(isInTemplateInstantiation()))
|
||||
.bind("condStmt"),
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
void StaticAssertCheck::check(const MatchFinder::MatchResult &Result) {
|
||||
|
@ -70,8 +83,7 @@ void StaticAssertCheck::check(const MatchFinder::MatchResult &Result) {
|
|||
const auto *CastExpr = Result.Nodes.getNodeAs<CStyleCastExpr>("castExpr");
|
||||
SourceLocation AssertExpansionLoc = CondStmt->getLocStart();
|
||||
|
||||
if (!Opts.CPlusPlus11 || !AssertExpansionLoc.isValid() ||
|
||||
!AssertExpansionLoc.isMacroID())
|
||||
if (!AssertExpansionLoc.isValid() || !AssertExpansionLoc.isMacroID())
|
||||
return;
|
||||
|
||||
StringRef MacroName =
|
||||
|
|
|
@ -55,15 +55,20 @@ void UndelegatedConstructorCheck::registerMatchers(MatchFinder *Finder) {
|
|||
// depending on the type's destructor and the number of arguments on the
|
||||
// constructor call, this is handled by ignoringTemporaryExpr. Ignore template
|
||||
// instantiations to reduce the number of duplicated warnings.
|
||||
Finder->addMatcher(
|
||||
compoundStmt(
|
||||
hasParent(constructorDecl(ofClass(recordDecl().bind("parent")))),
|
||||
forEach(ignoringTemporaryExpr(
|
||||
constructExpr(hasDeclaration(constructorDecl(ofClass(
|
||||
recordDecl(baseOfBoundNode("parent"))))))
|
||||
.bind("construct"))),
|
||||
unless(isInTemplateInstantiation())),
|
||||
this);
|
||||
//
|
||||
// Only register the matchers for C++11; the functionality currently does not
|
||||
// provide any benefit to other languages, despite being benign.
|
||||
if (getLangOpts().CPlusPlus11) {
|
||||
Finder->addMatcher(
|
||||
compoundStmt(
|
||||
hasParent(constructorDecl(ofClass(recordDecl().bind("parent")))),
|
||||
forEach(ignoringTemporaryExpr(
|
||||
constructExpr(hasDeclaration(constructorDecl(ofClass(
|
||||
recordDecl(baseOfBoundNode("parent"))))))
|
||||
.bind("construct"))),
|
||||
unless(isInTemplateInstantiation())),
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
void UndelegatedConstructorCheck::check(const MatchFinder::MatchResult &Result) {
|
||||
|
|
|
@ -18,21 +18,25 @@ namespace tidy {
|
|||
namespace misc {
|
||||
|
||||
void UniqueptrResetReleaseCheck::registerMatchers(MatchFinder *Finder) {
|
||||
Finder->addMatcher(
|
||||
memberCallExpr(
|
||||
on(expr().bind("left")), callee(memberExpr().bind("reset_member")),
|
||||
callee(methodDecl(hasName("reset"),
|
||||
ofClass(recordDecl(hasName("::std::unique_ptr"),
|
||||
decl().bind("left_class"))))),
|
||||
has(memberCallExpr(
|
||||
on(expr().bind("right")),
|
||||
callee(memberExpr().bind("release_member")),
|
||||
callee(methodDecl(
|
||||
hasName("release"),
|
||||
ofClass(recordDecl(hasName("::std::unique_ptr"),
|
||||
decl().bind("right_class"))))))))
|
||||
.bind("reset_call"),
|
||||
this);
|
||||
// Only register the matchers for C++11; the functionality currently does not
|
||||
// provide any benefit to other languages, despite being benign.
|
||||
if (getLangOpts().CPlusPlus11) {
|
||||
Finder->addMatcher(
|
||||
memberCallExpr(
|
||||
on(expr().bind("left")), callee(memberExpr().bind("reset_member")),
|
||||
callee(methodDecl(hasName("reset"),
|
||||
ofClass(recordDecl(hasName("::std::unique_ptr"),
|
||||
decl().bind("left_class"))))),
|
||||
has(memberCallExpr(
|
||||
on(expr().bind("right")),
|
||||
callee(memberExpr().bind("release_member")),
|
||||
callee(methodDecl(
|
||||
hasName("release"),
|
||||
ofClass(recordDecl(hasName("::std::unique_ptr"),
|
||||
decl().bind("right_class"))))))))
|
||||
.bind("reset_call"),
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
|
|
@ -22,11 +22,15 @@ const ast_matchers::internal::VariadicDynCastAllOfMatcher<
|
|||
Decl, NamespaceAliasDecl> namespaceAliasDecl;
|
||||
|
||||
void UnusedAliasDeclsCheck::registerMatchers(MatchFinder *Finder) {
|
||||
// We cannot do anything about headers (yet), as the alias declarations
|
||||
// used in one header could be used by some other translation unit.
|
||||
Finder->addMatcher(namespaceAliasDecl(isExpansionInMainFile()).bind("alias"),
|
||||
this);
|
||||
Finder->addMatcher(nestedNameSpecifier().bind("nns"), this);
|
||||
// Only register the matchers for C++11; the functionality currently does not
|
||||
// provide any benefit to other languages, despite being benign.
|
||||
if (getLangOpts().CPlusPlus11) {
|
||||
// We cannot do anything about headers (yet), as the alias declarations
|
||||
// used in one header could be used by some other translation unit.
|
||||
Finder->addMatcher(
|
||||
namespaceAliasDecl(isExpansionInMainFile()).bind("alias"), this);
|
||||
Finder->addMatcher(nestedNameSpecifier().bind("nns"), this);
|
||||
}
|
||||
}
|
||||
|
||||
void UnusedAliasDeclsCheck::check(const MatchFinder::MatchResult &Result) {
|
||||
|
|
|
@ -25,17 +25,22 @@ namespace tidy {
|
|||
namespace misc {
|
||||
|
||||
void UnusedRAIICheck::registerMatchers(MatchFinder *Finder) {
|
||||
// Look for temporaries that are constructed in-place and immediately
|
||||
// destroyed. Look for temporaries created by a functional cast but not for
|
||||
// those returned from a call.
|
||||
auto BindTemp = bindTemporaryExpr(unless(has(callExpr()))).bind("temp");
|
||||
Finder->addMatcher(
|
||||
exprWithCleanups(unless(isInTemplateInstantiation()),
|
||||
hasParent(compoundStmt().bind("compound")),
|
||||
hasType(recordDecl(hasNonTrivialDestructor())),
|
||||
anyOf(has(BindTemp), has(functionalCastExpr(
|
||||
has(BindTemp))))).bind("expr"),
|
||||
this);
|
||||
// Only register the matchers for C++; the functionality currently does not
|
||||
// provide any benefit to other languages, despite being benign.
|
||||
if (getLangOpts().CPlusPlus) {
|
||||
// Look for temporaries that are constructed in-place and immediately
|
||||
// destroyed. Look for temporaries created by a functional cast but not for
|
||||
// those returned from a call.
|
||||
auto BindTemp = bindTemporaryExpr(unless(has(callExpr()))).bind("temp");
|
||||
Finder->addMatcher(
|
||||
exprWithCleanups(
|
||||
unless(isInTemplateInstantiation()),
|
||||
hasParent(compoundStmt().bind("compound")),
|
||||
hasType(recordDecl(hasNonTrivialDestructor())),
|
||||
anyOf(has(BindTemp), has(functionalCastExpr(has(BindTemp)))))
|
||||
.bind("expr"),
|
||||
this);
|
||||
}
|
||||
}
|
||||
|
||||
void UnusedRAIICheck::check(const MatchFinder::MatchResult &Result) {
|
||||
|
|
|
@ -19,7 +19,9 @@ namespace tidy {
|
|||
namespace misc {
|
||||
|
||||
void UseOverrideCheck::registerMatchers(MatchFinder *Finder) {
|
||||
Finder->addMatcher(methodDecl(isOverride()).bind("method"), this);
|
||||
// Only register the matcher for C++11.
|
||||
if (getLangOpts().CPlusPlus11)
|
||||
Finder->addMatcher(methodDecl(isOverride()).bind("method"), this);
|
||||
}
|
||||
|
||||
// Re-lex the tokens to get precise locations to insert 'override' and remove
|
||||
|
@ -58,9 +60,6 @@ static StringRef GetText(const Token &Tok, const SourceManager &Sources) {
|
|||
}
|
||||
|
||||
void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) {
|
||||
if (!Result.Context->getLangOpts().CPlusPlus11)
|
||||
return;
|
||||
|
||||
const FunctionDecl *Method = Result.Nodes.getStmtAs<FunctionDecl>("method");
|
||||
const SourceManager &Sources = *Result.SourceManager;
|
||||
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
// RUN: clang-tidy %s -checks=-*,misc-undelegated-constructor -- -std=c++98 | count 0
|
||||
|
||||
// Note: this test expects no diagnostics, but FileCheck cannot handle that,
|
||||
// hence the use of | count 0.
|
||||
|
||||
struct Ctor;
|
||||
Ctor foo();
|
||||
|
||||
struct Ctor {
|
||||
Ctor();
|
||||
Ctor(int);
|
||||
Ctor(int, int);
|
||||
Ctor(Ctor *i) {
|
||||
Ctor();
|
||||
Ctor(0);
|
||||
Ctor(1, 2);
|
||||
foo();
|
||||
}
|
||||
};
|
||||
|
||||
Ctor::Ctor() {
|
||||
Ctor(1);
|
||||
}
|
Загрузка…
Ссылка в новой задаче