[clang-tidy] fix readability-implicit-bool-cast false alarm on |=, &=
llvm-svn: 302161
This commit is contained in:
parent
cbe8d16da4
commit
b92cb07bad
|
|
@ -40,24 +40,6 @@ AST_MATCHER(Stmt, isNULLMacroExpansion) {
|
||||||
return isNULLMacroExpansion(&Node, Finder->getASTContext());
|
return isNULLMacroExpansion(&Node, Finder->getASTContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_matchers::internal::Matcher<Expr> createExceptionCasesMatcher() {
|
|
||||||
return expr(anyOf(hasParent(explicitCastExpr()),
|
|
||||||
allOf(isMacroExpansion(), unless(isNULLMacroExpansion())),
|
|
||||||
isInTemplateInstantiation(),
|
|
||||||
hasAncestor(functionTemplateDecl())));
|
|
||||||
}
|
|
||||||
|
|
||||||
StatementMatcher createImplicitCastFromBoolMatcher() {
|
|
||||||
return implicitCastExpr(
|
|
||||||
unless(createExceptionCasesMatcher()),
|
|
||||||
anyOf(hasCastKind(CK_IntegralCast), hasCastKind(CK_IntegralToFloating),
|
|
||||||
// Prior to C++11 cast from bool literal to pointer was allowed.
|
|
||||||
allOf(anyOf(hasCastKind(CK_NullToPointer),
|
|
||||||
hasCastKind(CK_NullToMemberPointer)),
|
|
||||||
hasSourceExpression(cxxBoolLiteral()))),
|
|
||||||
hasSourceExpression(expr(hasType(qualType(booleanType())))));
|
|
||||||
}
|
|
||||||
|
|
||||||
StringRef getZeroLiteralToCompareWithForType(CastKind CastExprKind,
|
StringRef getZeroLiteralToCompareWithForType(CastKind CastExprKind,
|
||||||
QualType Type,
|
QualType Type,
|
||||||
ASTContext &Context) {
|
ASTContext &Context) {
|
||||||
|
|
@ -284,10 +266,15 @@ void ImplicitBoolCastCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto exceptionCases = expr(
|
||||||
|
anyOf(hasParent(explicitCastExpr()),
|
||||||
|
allOf(isMacroExpansion(), unless(isNULLMacroExpansion())),
|
||||||
|
isInTemplateInstantiation(), hasAncestor(functionTemplateDecl())));
|
||||||
|
|
||||||
Finder->addMatcher(
|
Finder->addMatcher(
|
||||||
implicitCastExpr(
|
implicitCastExpr(
|
||||||
// Exclude cases common to implicit cast to and from bool.
|
// Exclude cases common to implicit cast to and from bool.
|
||||||
unless(createExceptionCasesMatcher()),
|
unless(exceptionCases),
|
||||||
// Exclude case of using if or while statements with variable
|
// Exclude case of using if or while statements with variable
|
||||||
// declaration, e.g.:
|
// declaration, e.g.:
|
||||||
// if (int var = functionCall()) {}
|
// if (int var = functionCall()) {}
|
||||||
|
|
@ -303,17 +290,30 @@ void ImplicitBoolCastCheck::registerMatchers(MatchFinder *Finder) {
|
||||||
.bind("implicitCastToBool"),
|
.bind("implicitCastToBool"),
|
||||||
this);
|
this);
|
||||||
|
|
||||||
|
auto implicitCastFromBool = implicitCastExpr(
|
||||||
|
unless(exceptionCases),
|
||||||
|
anyOf(hasCastKind(CK_IntegralCast), hasCastKind(CK_IntegralToFloating),
|
||||||
|
// Prior to C++11 cast from bool literal to pointer was allowed.
|
||||||
|
allOf(anyOf(hasCastKind(CK_NullToPointer),
|
||||||
|
hasCastKind(CK_NullToMemberPointer)),
|
||||||
|
hasSourceExpression(cxxBoolLiteral()))),
|
||||||
|
hasSourceExpression(expr(hasType(booleanType()))));
|
||||||
|
|
||||||
|
auto boolComparison = binaryOperator(
|
||||||
|
anyOf(hasOperatorName("=="), hasOperatorName("!=")),
|
||||||
|
hasLHS(implicitCastFromBool), hasRHS(implicitCastFromBool));
|
||||||
|
auto boolOpAssignment = binaryOperator(
|
||||||
|
anyOf(hasOperatorName("|="), hasOperatorName("&=")),
|
||||||
|
hasLHS(expr(hasType(booleanType()))), hasRHS(implicitCastFromBool));
|
||||||
Finder->addMatcher(
|
Finder->addMatcher(
|
||||||
implicitCastExpr(
|
implicitCastExpr(
|
||||||
createImplicitCastFromBoolMatcher(),
|
implicitCastFromBool,
|
||||||
// Exclude comparisons of bools, as they are always cast to integers
|
// Exclude comparisons of bools, as they are always cast to integers
|
||||||
// in such context:
|
// in such context:
|
||||||
// bool_expr_a == bool_expr_b
|
// bool_expr_a == bool_expr_b
|
||||||
// bool_expr_a != bool_expr_b
|
// bool_expr_a != bool_expr_b
|
||||||
unless(hasParent(binaryOperator(
|
unless(hasParent(
|
||||||
anyOf(hasOperatorName("=="), hasOperatorName("!=")),
|
binaryOperator(anyOf(boolComparison, boolOpAssignment)))),
|
||||||
hasLHS(createImplicitCastFromBoolMatcher()),
|
|
||||||
hasRHS(createImplicitCastFromBoolMatcher())))),
|
|
||||||
// Check also for nested casts, for example: bool -> int -> float.
|
// Check also for nested casts, for example: bool -> int -> float.
|
||||||
anyOf(hasParent(implicitCastExpr().bind("furtherImplicitCast")),
|
anyOf(hasParent(implicitCastExpr().bind("furtherImplicitCast")),
|
||||||
anything()))
|
anything()))
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,11 @@ float implicitCastFromBoolInReturnValue() {
|
||||||
// CHECK-FIXES: return static_cast<float>(boolean);
|
// CHECK-FIXES: return static_cast<float>(boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
void implicitCastFromBoolInSingleBoolExpressions() {
|
void implicitCastFromBoolInSingleBoolExpressions(bool b1, bool b2) {
|
||||||
bool boolean = true;
|
bool boolean = true;
|
||||||
|
boolean = b1 && b2;
|
||||||
|
boolean |= !b1 || !b2;
|
||||||
|
boolean &= b1;
|
||||||
|
|
||||||
int integer = boolean - 3;
|
int integer = boolean - 3;
|
||||||
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit cast bool -> 'int'
|
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: implicit cast bool -> 'int'
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue