- Notifications
You must be signed in to change notification settings - Fork 15.2k
Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max #77816
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 3 commits
Commits
Show all changes
54 commits Select commit Hold shift + click to select a range
1883d98 Add readability check to suggest replacement of conditional statement…
11happy 89be4ba Formatted the code
11happy e1b65a9 small fix
11happy 042ddc3 Revert "small fix"
11happy c17b298 Revert "Formatted the code"
11happy 9aad658 Revert "Add readability check to suggest replacement of conditional s…
11happy 2fc0938 Added Suggested Changes
11happy 1139ac4 Formatted the Code
11happy f73e9f0 Added Release Notes
11happy faf3312 corrected file name
11happy 5ed9896 corrected title length in docs
11happy 19c4b63 Suggested Changes
11happy 8167787 body indentation
11happy 3a28399 added intialisation,constexpr tests
11happy 2ecd08a small fixes
11happy 00d4080 Addded Suggested Changes
11happy 6db0820 formatted the code
11happy 5073650 Added Include Check
11happy c728a39 Formatted the code
11happy b8202ae Added tests for macro & if with brackets
11happy 3b57307 Fixed merge Conflict
11happy 5e31665 Added suggested changes
11happy a2cfcdc Formatted the code
11happy f5a0f12 Converted to Lambdas,placed at sorted location
11happy e239576 Single Lambda
11happy b868d5b CamelCase,const auto*
11happy 0797e0c fixes
11happy c6028b0 few nits
11happy 6acf645 formatted the code
11happy 0eb4aca extra checks
11happy d5b8dc2 ensure if has no else if
11happy a92160c correct style issue
11happy 5eafb59 correct docs
11happy 26bfbdc correct docs
11happy 57bccd6 static functions
11happy 61fd66a small fix
11happy a841ebc style issues
11happy 7d2c085 corrrect style issue
11happy 399c4c5 Merge branch 'SecondPR' of https://github.com/11happy/llvm-project in…
11happy abec9b5 correct functional bugs
11happy 6a0e495 pass dependent types
11happy 274b55f filter implicit cast expr
11happy b7ca014 resolved merge conflict
11happy 8bf8235 Add mising type, optimise
11happy d8df8c8 removed whitespace
11happy 8a5d585 remove unsed initialisation
11happy 85fb67d small change
11happy 1214547 simplify
11happy 6aef713 small fix
11happy f03b2ff non template alias
11happy 5d504a7 simplify pointer dereference
11happy 19cc1f3 remove extra parentheses
11happy a316744 use spefici type instead of auto
11happy f0ef998 use auto for cast kind
11happy File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
88 changes: 88 additions & 0 deletions 88 clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| //===--- ConditionaltostdminmaxCheck.cpp - clang-tidy ---------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| | ||
| #include "ConditionaltostdminmaxCheck.h" | ||
| #include "clang/AST/ASTContext.h" | ||
| #include "clang/ASTMatchers/ASTMatchFinder.h" | ||
| | ||
| using namespace clang::ast_matchers; | ||
| | ||
| namespace clang::tidy::readability { | ||
| | ||
| void ConditionaltostdminmaxCheck::registerMatchers(MatchFinder *Finder) { | ||
| Finder->addMatcher( | ||
| ifStmt(has(binaryOperator( | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| anyOf(hasOperatorName("<"), hasOperatorName(">")), | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| hasLHS(ignoringImpCasts(declRefExpr().bind("lhsVar1"))), | ||
| hasRHS(ignoringImpCasts(declRefExpr().bind("rhsVar1"))))), | ||
| hasThen(stmt(binaryOperator( | ||
| hasOperatorName("="), | ||
| hasLHS(ignoringImpCasts(declRefExpr().bind("lhsVar2"))), | ||
| hasRHS(ignoringImpCasts(declRefExpr().bind("rhsVar2"))))))) | ||
| .bind("ifStmt"), | ||
| this); | ||
| } | ||
| | ||
| void ConditionaltostdminmaxCheck::check( | ||
| const MatchFinder::MatchResult &Result) { | ||
| const DeclRefExpr *lhsVar1 = Result.Nodes.getNodeAs<DeclRefExpr>("lhsVar1"); | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| const DeclRefExpr *rhsVar1 = Result.Nodes.getNodeAs<DeclRefExpr>("rhsVar1"); | ||
| const DeclRefExpr *lhsVar2 = Result.Nodes.getNodeAs<DeclRefExpr>("lhsVar2"); | ||
| const DeclRefExpr *rhsVar2 = Result.Nodes.getNodeAs<DeclRefExpr>("rhsVar2"); | ||
| const IfStmt *ifStmt = Result.Nodes.getNodeAs<IfStmt>("ifStmt"); | ||
| | ||
| if (!lhsVar1 || !rhsVar1 || !lhsVar2 || !rhsVar2 || !ifStmt) | ||
| return; | ||
| | ||
| const BinaryOperator *binaryOp = dyn_cast<BinaryOperator>(ifStmt->getCond()); | ||
| if (!binaryOp) | ||
| return; | ||
| | ||
| SourceLocation ifLocation = ifStmt->getIfLoc(); | ||
| SourceLocation thenLocation = ifStmt->getEndLoc(); | ||
| | ||
| if (binaryOp->getOpcode() == BO_LT) { | ||
| if (lhsVar1->getDecl() == lhsVar2->getDecl() && | ||
| rhsVar1->getDecl() == rhsVar2->getDecl()) { | ||
| diag(ifStmt->getIfLoc(), "use std::max instead of <") | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| << FixItHint::CreateReplacement( | ||
| SourceRange(ifLocation, thenLocation), | ||
| lhsVar2->getNameInfo().getAsString() + " = std::max(" + | ||
| lhsVar1->getNameInfo().getAsString() + ", " + | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| rhsVar1->getNameInfo().getAsString() + ")"); | ||
| } else if (lhsVar1->getDecl() == rhsVar2->getDecl() && | ||
| rhsVar1->getDecl() == lhsVar2->getDecl()) { | ||
| diag(ifStmt->getIfLoc(), "use std::min instead of <") | ||
| << FixItHint::CreateReplacement( | ||
| SourceRange(ifLocation, thenLocation), | ||
| lhsVar2->getNameInfo().getAsString() + " = std::min(" + | ||
| lhsVar1->getNameInfo().getAsString() + ", " + | ||
| rhsVar1->getNameInfo().getAsString() + ")"); | ||
| } | ||
| } else if (binaryOp->getOpcode() == BO_GT) { | ||
| if (lhsVar1->getDecl() == lhsVar2->getDecl() && | ||
| rhsVar1->getDecl() == rhsVar2->getDecl()) { | ||
| diag(ifStmt->getIfLoc(), "use std::min instead of >") | ||
| << FixItHint::CreateReplacement( | ||
| SourceRange(ifLocation, thenLocation), | ||
| lhsVar2->getNameInfo().getAsString() + " = std::min(" + | ||
| lhsVar1->getNameInfo().getAsString() + ", " + | ||
| rhsVar1->getNameInfo().getAsString() + ")"); | ||
| } else if (lhsVar1->getDecl() == rhsVar2->getDecl() && | ||
| rhsVar1->getDecl() == lhsVar2->getDecl()) { | ||
| diag(ifStmt->getIfLoc(), "use std::max instead of >") | ||
| << FixItHint::CreateReplacement( | ||
| SourceRange(ifLocation, thenLocation), | ||
| lhsVar2->getNameInfo().getAsString() + " = std::max(" + | ||
| lhsVar1->getNameInfo().getAsString() + ", " + | ||
| rhsVar1->getNameInfo().getAsString() + ")"); | ||
| } | ||
| } | ||
| } | ||
| | ||
| } // namespace clang::tidy::readability | ||
32 changes: 32 additions & 0 deletions 32 clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| //===--- ConditionaltostdminmaxCheck.h - clang-tidy -------------*- C++ -*-===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| | ||
| #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONDITIONALTOSTDMINMAXCHECK_H | ||
| #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONDITIONALTOSTDMINMAXCHECK_H | ||
| | ||
| #include "../ClangTidyCheck.h" | ||
| | ||
| namespace clang::tidy::readability { | ||
| | ||
| /// FIXME: replaces certain conditional statements with equivalent std::min or | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| /// std::max expressions, improving readability and promoting the use of | ||
| /// standard library functions." | ||
| /// | ||
| /// For the user-facing documentation see: | ||
| /// http://clang.llvm.org/extra/clang-tidy/checks/readability/ConditionalToStdMinMax.html | ||
| class ConditionaltostdminmaxCheck : public ClangTidyCheck { | ||
| public: | ||
| ConditionaltostdminmaxCheck(StringRef Name, ClangTidyContext *Context) | ||
| : ClangTidyCheck(Name, Context) {} | ||
| void registerMatchers(ast_matchers::MatchFinder *Finder) override; | ||
| void check(const ast_matchers::MatchFinder::MatchResult &Result) override; | ||
| }; | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved 11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| } // namespace clang::tidy::readability | ||
| | ||
| #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONDITIONALTOSTDMINMAXCHECK_H | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions 29 clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| .. title:: clang-tidy - readability-ConditionalToStdMinMax | ||
| | ||
| readability-ConditionalToStdMinMax | ||
| ================================== | ||
| | ||
| Replaces certain conditional statements with equivalent std::min or std::max expressions, | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved 11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| improving readability and promoting the use of standard library functions. | ||
| | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| Examples: | ||
| | ||
| Before: | ||
| | ||
| .. code-block:: c++ | ||
| | ||
| void foo(){ | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| int a,b; | ||
| if(a < b) | ||
| a = b; | ||
| } | ||
| | ||
| | ||
| After: | ||
| | ||
| .. code-block:: c++ | ||
| | ||
| void foo(){ | ||
| a = std::max(a, b); | ||
| | ||
| } | ||
27 changes: 27 additions & 0 deletions 27 clang-tools-extra/test/clang-tidy/checkers/readability/ConditionalToStdMinMax.cpp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // RUN: %check_clang_tidy %s readability-ConditionalToStdMinMax %t | ||
| | ||
| void foo() { | ||
| int value1,value2; | ||
| | ||
| // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use std::max instead of < [readability-ConditionalToStdMinMax] | ||
| if (value1 < value2) | ||
| value1 = value2; // CHECK-FIXES: value1 = std::max(value1, value2); | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| | ||
| // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use std::min instead of < [readability-ConditionalToStdMinMax] | ||
| if (value1 < value2) | ||
| value2 = value1; // CHECK-FIXES: value2 = std::min(value1, value2); | ||
| | ||
| // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use std::min instead of > [readability-ConditionalToStdMinMax] | ||
| if (value2 > value1) | ||
| value2 = value1; // CHECK-FIXES: value2 = std::min(value2, value1); | ||
| | ||
| // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use std::max instead of > [readability-ConditionalToStdMinMax] | ||
| if (value2 > value1) | ||
| value1 = value2; // CHECK-FIXES: value1 = std::max(value2, value1); | ||
| | ||
| // No suggestion needed here | ||
| if (value1 == value2) | ||
| value1 = value2; | ||
| | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved 11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved 11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
| } | ||
11happy marked this conversation as resolved. Outdated Show resolved Hide resolved | ||
Add this suggestion to a batch that can be applied as a single commit. This suggestion is invalid because no changes were made to the code. Suggestions cannot be applied while the pull request is closed. Suggestions cannot be applied while viewing a subset of changes. Only one suggestion per line can be applied in a batch. Add this suggestion to a batch that can be applied as a single commit. Applying suggestions on deleted lines is not supported. You must change the existing code in this line in order to create a valid suggestion. Outdated suggestions cannot be applied. This suggestion has been applied or marked resolved. Suggestions cannot be applied from pending reviews. Suggestions cannot be applied on multi-line comments. Suggestions cannot be applied while the pull request is queued to merge. Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.