1 //===--- AssignmentInIfConditionCheck.cpp - clang-tidy --------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "AssignmentInIfConditionCheck.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/AST/RecursiveASTVisitor.h"
12 #include "clang/ASTMatchers/ASTMatchFinder.h"
14 using namespace clang::ast_matchers
;
16 namespace clang::tidy::bugprone
{
18 void AssignmentInIfConditionCheck::registerMatchers(MatchFinder
*Finder
) {
19 Finder
->addMatcher(translationUnitDecl(), this);
22 void AssignmentInIfConditionCheck::check(
23 const ast_matchers::MatchFinder::MatchResult
&Result
) {
24 class Visitor
: public RecursiveASTVisitor
<Visitor
> {
25 AssignmentInIfConditionCheck
&Check
;
28 explicit Visitor(AssignmentInIfConditionCheck
&Check
) : Check(Check
) {}
29 bool VisitIfStmt(IfStmt
*If
) {
30 class ConditionVisitor
: public RecursiveASTVisitor
<ConditionVisitor
> {
31 AssignmentInIfConditionCheck
&Check
;
34 explicit ConditionVisitor(AssignmentInIfConditionCheck
&Check
)
37 // Dont traverse into any lambda expressions.
38 bool TraverseLambdaExpr(LambdaExpr
*, DataRecursionQueue
* = nullptr) {
42 // Dont traverse into any requires expressions.
43 bool TraverseRequiresExpr(RequiresExpr
*,
44 DataRecursionQueue
* = nullptr) {
48 bool VisitBinaryOperator(BinaryOperator
*BO
) {
49 if (BO
->isAssignmentOp())
54 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr
*OCE
) {
55 if (OCE
->isAssignmentOp())
61 ConditionVisitor(Check
).TraverseStmt(If
->getCond());
65 Visitor(*this).TraverseAST(*Result
.Context
);
68 void AssignmentInIfConditionCheck::report(const Expr
*AssignmentExpr
) {
69 SourceLocation OpLoc
=
70 isa
<BinaryOperator
>(AssignmentExpr
)
71 ? cast
<BinaryOperator
>(AssignmentExpr
)->getOperatorLoc()
72 : cast
<CXXOperatorCallExpr
>(AssignmentExpr
)->getOperatorLoc();
74 diag(OpLoc
, "an assignment within an 'if' condition is bug-prone")
75 << AssignmentExpr
->getSourceRange();
77 "if it should be an assignment, move it out of the 'if' condition",
79 diag(OpLoc
, "if it is meant to be an equality check, change '=' to '=='",
83 } // namespace clang::tidy::bugprone