[clang] [clang-tools-extra] [llvm] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)
Bhuminjay Soni via llvm-commits
llvm-commits at lists.llvm.org
Mon Jan 22 10:22:10 PST 2024
https://github.com/11happy updated https://github.com/llvm/llvm-project/pull/77816
>From 1883d987b2f83adaef05fdb47ae25c7b06582a64 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 12 Jan 2024 00:02:46 +0530
Subject: [PATCH 01/31] Add readability check to suggest replacement of
conditional statement with std::min/std::max
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../clang-tidy/readability/CMakeLists.txt | 1 +
.../ConditionaltostdminmaxCheck.cpp | 86 +++++++++++++++++++
.../readability/ConditionaltostdminmaxCheck.h | 30 +++++++
.../readability/ReadabilityTidyModule.cpp | 3 +
clang-tools-extra/docs/ReleaseNotes.rst | 6 ++
.../docs/clang-tidy/checks/list.rst | 1 +
.../readability/ConditionalToStdMinMax.rst | 29 +++++++
.../readability/ConditionalToStdMinMax.cpp | 27 ++++++
8 files changed, 183 insertions(+)
create mode 100644 clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp
create mode 100644 clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h
create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/ConditionalToStdMinMax.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 408c822b861c5fe..4bc373bb69bb84a 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -8,6 +8,7 @@ add_clang_library(clangTidyReadabilityModule
AvoidReturnWithVoidValueCheck.cpp
AvoidUnconditionalPreprocessorIfCheck.cpp
BracesAroundStatementsCheck.cpp
+ ConditionaltostdminmaxCheck.cpp
ConstReturnTypeCheck.cpp
ContainerContainsCheck.cpp
ContainerDataPointerCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp
new file mode 100644
index 000000000000000..fba8c68f737450f
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp
@@ -0,0 +1,86 @@
+//===--- 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(
+ anyOf(hasOperatorName("<"),hasOperatorName(">")),
+ 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");
+ 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 <")<<FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
+ lhsVar2->getNameInfo().getAsString() + " = std::max(" + lhsVar1->getNameInfo().getAsString() + ", " +
+ 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
diff --git a/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h b/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h
new file mode 100644
index 000000000000000..b7eabcc7d16d416
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h
@@ -0,0 +1,30 @@
+//===--- 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 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;
+};
+
+} // namespace clang::tidy::readability
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONDITIONALTOSTDMINMAXCHECK_H
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index 0b0aad7c0dcb36c..63f8f03be6bb916 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -13,6 +13,7 @@
#include "AvoidReturnWithVoidValueCheck.h"
#include "AvoidUnconditionalPreprocessorIfCheck.h"
#include "BracesAroundStatementsCheck.h"
+#include "ConditionaltostdminmaxCheck.h"
#include "ConstReturnTypeCheck.h"
#include "ContainerContainsCheck.h"
#include "ContainerDataPointerCheck.h"
@@ -62,6 +63,8 @@ namespace readability {
class ReadabilityModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+ CheckFactories.registerCheck<ConditionaltostdminmaxCheck>(
+ "readability-ConditionalToStdMinMax");
CheckFactories.registerCheck<AvoidConstParamsInDecls>(
"readability-avoid-const-params-in-decls");
CheckFactories.registerCheck<AvoidReturnWithVoidValueCheck>(
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index b4d87e0ed2a67ae..c3fb990ad6a7382 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -224,6 +224,12 @@ New checks
Recommends the smallest possible underlying type for an ``enum`` or ``enum``
class based on the range of its enumerators.
+- New :doc:`readability-ConditionalToStdMinMax
+ <clang-tidy/checks/readability/ConditionalToStdMinMax>` check.
+
+ Replaces certain conditional statements with equivalent std::min or std::max expressions,
+ improving readability and promoting the use of standard library functions.
+
- New :doc:`readability-reference-to-constructed-temporary
<clang-tidy/checks/readability/reference-to-constructed-temporary>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 2f86121ad872998..c2eac55425c69e5 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -336,6 +336,7 @@ Clang-Tidy Checks
:doc:`portability-restrict-system-includes <portability/restrict-system-includes>`, "Yes"
:doc:`portability-simd-intrinsics <portability/simd-intrinsics>`,
:doc:`portability-std-allocator-const <portability/std-allocator-const>`,
+ :doc:`readability-ConditionalToStdMinMax <readability/ConditionalToStdMinMax>`, "Yes"
:doc:`readability-avoid-const-params-in-decls <readability/avoid-const-params-in-decls>`, "Yes"
:doc:`readability-avoid-return-with-void-value <readability/avoid-return-with-void-value>`,
:doc:`readability-avoid-unconditional-preprocessor-if <readability/avoid-unconditional-preprocessor-if>`,
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst
new file mode 100644
index 000000000000000..e95858999b27725
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst
@@ -0,0 +1,29 @@
+.. title:: clang-tidy - readability-ConditionalToStdMinMax
+
+readability-ConditionalToStdMinMax
+==================================
+
+Replaces certain conditional statements with equivalent std::min or std::max expressions,
+improving readability and promoting the use of standard library functions.
+
+Examples:
+
+Before:
+
+.. code-block:: c++
+
+ void foo(){
+ int a,b;
+ if(a < b)
+ a = b;
+ }
+
+
+After:
+
+.. code-block:: c++
+
+ int main(){
+ a = std::max(a, b);
+
+ }
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/ConditionalToStdMinMax.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/ConditionalToStdMinMax.cpp
new file mode 100644
index 000000000000000..d29e9aa9fec7080
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/ConditionalToStdMinMax.cpp
@@ -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);
+
+ // 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;
+
+
+}
\ No newline at end of file
>From 89be4baf2591918b11b633d2430050dc41068fde Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 12 Jan 2024 00:03:16 +0530
Subject: [PATCH 02/31] Formatted the code
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../ConditionaltostdminmaxCheck.cpp | 96 ++++++++++---------
.../readability/ConditionaltostdminmaxCheck.h | 4 +-
2 files changed, 52 insertions(+), 48 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp
index fba8c68f737450f..86420765d6f6c61 100644
--- a/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp
@@ -16,69 +16,71 @@ namespace clang::tidy::readability {
void ConditionaltostdminmaxCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
- ifStmt(
- has(
- binaryOperator(
- anyOf(hasOperatorName("<"),hasOperatorName(">")),
- 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);
-
-
-
+ ifStmt(has(binaryOperator(
+ anyOf(hasOperatorName("<"), hasOperatorName(">")),
+ 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) {
+void ConditionaltostdminmaxCheck::check(
+ const MatchFinder::MatchResult &Result) {
const DeclRefExpr *lhsVar1 = Result.Nodes.getNodeAs<DeclRefExpr>("lhsVar1");
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 DeclRefExpr *rhsVar2 = Result.Nodes.getNodeAs<DeclRefExpr>("rhsVar2");
const IfStmt *ifStmt = Result.Nodes.getNodeAs<IfStmt>("ifStmt");
if (!lhsVar1 || !rhsVar1 || !lhsVar2 || !rhsVar2 || !ifStmt)
- return;
+ return;
const BinaryOperator *binaryOp = dyn_cast<BinaryOperator>(ifStmt->getCond());
if (!binaryOp)
- return;
+ 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 <")<<FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- lhsVar2->getNameInfo().getAsString() + " = std::max(" + lhsVar1->getNameInfo().getAsString() + ", " +
- 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() + ")");
+ if (binaryOp->getOpcode() == BO_LT) {
+ if (lhsVar1->getDecl() == lhsVar2->getDecl() &&
+ rhsVar1->getDecl() == rhsVar2->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() + ")");
+ } 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(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() + ")");
+ } 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() + ")");
}
}
}
diff --git a/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h b/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h
index b7eabcc7d16d416..02ebed83fed6c82 100644
--- a/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h
@@ -13,7 +13,9 @@
namespace clang::tidy::readability {
-/// FIXME: replaces certain conditional statements with equivalent std::min or std::max expressions, improving readability and promoting the use of standard library functions."
+/// FIXME: replaces certain conditional statements with equivalent std::min or
+/// 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
>From e1b65a9fb0ea27d62b568d8d3038c0231927cdad Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 12 Jan 2024 00:15:54 +0530
Subject: [PATCH 03/31] small fix
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../clang-tidy/checks/readability/ConditionalToStdMinMax.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst
index e95858999b27725..2b75e78ecb80829 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst
@@ -23,7 +23,7 @@ After:
.. code-block:: c++
- int main(){
+ void foo(){
a = std::max(a, b);
}
\ No newline at end of file
>From 042ddc3d89ebad999378e6bb8ef29e1f05f81745 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 12 Jan 2024 15:43:22 +0530
Subject: [PATCH 04/31] Revert "small fix"
This reverts commit e1b65a9fb0ea27d62b568d8d3038c0231927cdad.
---
.../clang-tidy/checks/readability/ConditionalToStdMinMax.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst
index 2b75e78ecb80829..e95858999b27725 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst
@@ -23,7 +23,7 @@ After:
.. code-block:: c++
- void foo(){
+ int main(){
a = std::max(a, b);
}
\ No newline at end of file
>From c17b298185d50095d964d5afd8f79f52281e85f8 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 12 Jan 2024 15:43:38 +0530
Subject: [PATCH 05/31] Revert "Formatted the code"
This reverts commit 89be4baf2591918b11b633d2430050dc41068fde.
---
.../ConditionaltostdminmaxCheck.cpp | 96 +++++++++----------
.../readability/ConditionaltostdminmaxCheck.h | 4 +-
2 files changed, 48 insertions(+), 52 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp
index 86420765d6f6c61..fba8c68f737450f 100644
--- a/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp
@@ -16,71 +16,69 @@ namespace clang::tidy::readability {
void ConditionaltostdminmaxCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
- ifStmt(has(binaryOperator(
- anyOf(hasOperatorName("<"), hasOperatorName(">")),
- 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);
+ ifStmt(
+ has(
+ binaryOperator(
+ anyOf(hasOperatorName("<"),hasOperatorName(">")),
+ 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) {
+void ConditionaltostdminmaxCheck::check(const MatchFinder::MatchResult &Result) {
const DeclRefExpr *lhsVar1 = Result.Nodes.getNodeAs<DeclRefExpr>("lhsVar1");
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 DeclRefExpr *rhsVar2 = Result.Nodes.getNodeAs<DeclRefExpr>("rhsVar2");
const IfStmt *ifStmt = Result.Nodes.getNodeAs<IfStmt>("ifStmt");
if (!lhsVar1 || !rhsVar1 || !lhsVar2 || !rhsVar2 || !ifStmt)
- return;
+ return;
const BinaryOperator *binaryOp = dyn_cast<BinaryOperator>(ifStmt->getCond());
if (!binaryOp)
- return;
+ 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 <")
- << FixItHint::CreateReplacement(
- SourceRange(ifLocation, thenLocation),
- lhsVar2->getNameInfo().getAsString() + " = std::max(" +
- lhsVar1->getNameInfo().getAsString() + ", " +
- 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() + ")");
+ if(binaryOp->getOpcode() == BO_LT){
+ if(lhsVar1->getDecl() == lhsVar2->getDecl() && rhsVar1->getDecl() == rhsVar2->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() + ")");
+ }
+ 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 (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() + ")");
+ 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() + ")");
}
}
}
diff --git a/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h b/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h
index 02ebed83fed6c82..b7eabcc7d16d416 100644
--- a/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h
@@ -13,9 +13,7 @@
namespace clang::tidy::readability {
-/// FIXME: replaces certain conditional statements with equivalent std::min or
-/// std::max expressions, improving readability and promoting the use of
-/// standard library functions."
+/// FIXME: replaces certain conditional statements with equivalent std::min or 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
>From 9aad658ef0e6175cdc0388c914a444a5bcd9ba1c Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 12 Jan 2024 15:43:52 +0530
Subject: [PATCH 06/31] Revert "Add readability check to suggest replacement of
conditional statement with std::min/std::max"
This reverts commit 1883d987b2f83adaef05fdb47ae25c7b06582a64.
---
.../clang-tidy/readability/CMakeLists.txt | 1 -
.../ConditionaltostdminmaxCheck.cpp | 86 -------------------
.../readability/ConditionaltostdminmaxCheck.h | 30 -------
.../readability/ReadabilityTidyModule.cpp | 3 -
clang-tools-extra/docs/ReleaseNotes.rst | 6 --
.../docs/clang-tidy/checks/list.rst | 1 -
.../readability/ConditionalToStdMinMax.rst | 29 -------
.../readability/ConditionalToStdMinMax.cpp | 27 ------
8 files changed, 183 deletions(-)
delete mode 100644 clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp
delete mode 100644 clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h
delete mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst
delete mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/ConditionalToStdMinMax.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 4bc373bb69bb84a..408c822b861c5fe 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -8,7 +8,6 @@ add_clang_library(clangTidyReadabilityModule
AvoidReturnWithVoidValueCheck.cpp
AvoidUnconditionalPreprocessorIfCheck.cpp
BracesAroundStatementsCheck.cpp
- ConditionaltostdminmaxCheck.cpp
ConstReturnTypeCheck.cpp
ContainerContainsCheck.cpp
ContainerDataPointerCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp
deleted file mode 100644
index fba8c68f737450f..000000000000000
--- a/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-//===--- 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(
- anyOf(hasOperatorName("<"),hasOperatorName(">")),
- 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");
- 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 <")<<FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- lhsVar2->getNameInfo().getAsString() + " = std::max(" + lhsVar1->getNameInfo().getAsString() + ", " +
- 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
diff --git a/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h b/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h
deleted file mode 100644
index b7eabcc7d16d416..000000000000000
--- a/clang-tools-extra/clang-tidy/readability/ConditionaltostdminmaxCheck.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===--- 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 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;
-};
-
-} // namespace clang::tidy::readability
-
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_CONDITIONALTOSTDMINMAXCHECK_H
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index 63f8f03be6bb916..0b0aad7c0dcb36c 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -13,7 +13,6 @@
#include "AvoidReturnWithVoidValueCheck.h"
#include "AvoidUnconditionalPreprocessorIfCheck.h"
#include "BracesAroundStatementsCheck.h"
-#include "ConditionaltostdminmaxCheck.h"
#include "ConstReturnTypeCheck.h"
#include "ContainerContainsCheck.h"
#include "ContainerDataPointerCheck.h"
@@ -63,8 +62,6 @@ namespace readability {
class ReadabilityModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
- CheckFactories.registerCheck<ConditionaltostdminmaxCheck>(
- "readability-ConditionalToStdMinMax");
CheckFactories.registerCheck<AvoidConstParamsInDecls>(
"readability-avoid-const-params-in-decls");
CheckFactories.registerCheck<AvoidReturnWithVoidValueCheck>(
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index c3fb990ad6a7382..b4d87e0ed2a67ae 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -224,12 +224,6 @@ New checks
Recommends the smallest possible underlying type for an ``enum`` or ``enum``
class based on the range of its enumerators.
-- New :doc:`readability-ConditionalToStdMinMax
- <clang-tidy/checks/readability/ConditionalToStdMinMax>` check.
-
- Replaces certain conditional statements with equivalent std::min or std::max expressions,
- improving readability and promoting the use of standard library functions.
-
- New :doc:`readability-reference-to-constructed-temporary
<clang-tidy/checks/readability/reference-to-constructed-temporary>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index c2eac55425c69e5..2f86121ad872998 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -336,7 +336,6 @@ Clang-Tidy Checks
:doc:`portability-restrict-system-includes <portability/restrict-system-includes>`, "Yes"
:doc:`portability-simd-intrinsics <portability/simd-intrinsics>`,
:doc:`portability-std-allocator-const <portability/std-allocator-const>`,
- :doc:`readability-ConditionalToStdMinMax <readability/ConditionalToStdMinMax>`, "Yes"
:doc:`readability-avoid-const-params-in-decls <readability/avoid-const-params-in-decls>`, "Yes"
:doc:`readability-avoid-return-with-void-value <readability/avoid-return-with-void-value>`,
:doc:`readability-avoid-unconditional-preprocessor-if <readability/avoid-unconditional-preprocessor-if>`,
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst
deleted file mode 100644
index e95858999b27725..000000000000000
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/ConditionalToStdMinMax.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-.. title:: clang-tidy - readability-ConditionalToStdMinMax
-
-readability-ConditionalToStdMinMax
-==================================
-
-Replaces certain conditional statements with equivalent std::min or std::max expressions,
-improving readability and promoting the use of standard library functions.
-
-Examples:
-
-Before:
-
-.. code-block:: c++
-
- void foo(){
- int a,b;
- if(a < b)
- a = b;
- }
-
-
-After:
-
-.. code-block:: c++
-
- int main(){
- a = std::max(a, b);
-
- }
\ No newline at end of file
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/ConditionalToStdMinMax.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/ConditionalToStdMinMax.cpp
deleted file mode 100644
index d29e9aa9fec7080..000000000000000
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/ConditionalToStdMinMax.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// 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);
-
- // 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;
-
-
-}
\ No newline at end of file
>From 2fc0938430a25ca6672c2d408e55f5b1a3188d60 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 12 Jan 2024 17:24:08 +0530
Subject: [PATCH 07/31] Added Suggested Changes
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../clang-tidy/readability/CMakeLists.txt | 1 +
.../readability/ReadabilityTidyModule.cpp | 3 +
.../readability/UseStdMinMaxCheck.cpp | 103 ++++++++++++++++++
.../readability/UseStdMinMaxCheck.h | 38 +++++++
clang-tools-extra/docs/ReleaseNotes.rst | 5 +
.../docs/clang-tidy/checks/list.rst | 1 +
.../checks/readability/UseStdMinMax.rst | 33 ++++++
.../checkers/readability/use-std-min-max.cpp | 35 ++++++
8 files changed, 219 insertions(+)
create mode 100644 clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
create mode 100644 clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
create mode 100644 clang-tools-extra/docs/clang-tidy/checks/readability/UseStdMinMax.rst
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 408c822b861c5fe..3670a4399543459 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -52,6 +52,7 @@ add_clang_library(clangTidyReadabilityModule
UniqueptrDeleteReleaseCheck.cpp
UppercaseLiteralSuffixCheck.cpp
UseAnyOfAllOfCheck.cpp
+ UseStdMinMaxCheck.cpp
LINK_LIBS
clangTidy
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index 0b0aad7c0dcb36c..cba32ea24cec7c2 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -55,6 +55,7 @@
#include "UniqueptrDeleteReleaseCheck.h"
#include "UppercaseLiteralSuffixCheck.h"
#include "UseAnyOfAllOfCheck.h"
+#include "UseStdMinMaxCheck.h"
namespace clang::tidy {
namespace readability {
@@ -62,6 +63,8 @@ namespace readability {
class ReadabilityModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
+ CheckFactories.registerCheck<UseStdMinMaxCheck>(
+ "readability-use-std-min-max");
CheckFactories.registerCheck<AvoidConstParamsInDecls>(
"readability-avoid-const-params-in-decls");
CheckFactories.registerCheck<AvoidReturnWithVoidValueCheck>(
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
new file mode 100644
index 000000000000000..984792322ce5d30
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -0,0 +1,103 @@
+//===--- UseStdMinMaxCheck.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 "UseStdMinMaxCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Preprocessor.h"
+#include <optional>
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+void UseStdMinMaxCheck::registerMatchers(MatchFinder *Finder) {
+ Finder->addMatcher(
+ ifStmt(has(binaryOperator(
+ anyOf(hasOperatorName("<"), hasOperatorName(">"),hasOperatorName("<="), hasOperatorName(">=")),
+ hasLHS(expr().bind("lhsVar1")),
+ hasRHS(expr().bind("rhsVar1")))),
+ hasThen(stmt(binaryOperator(
+ hasOperatorName("="),
+ hasLHS(expr().bind("lhsVar2")),
+ hasRHS(expr().bind("rhsVar2"))))))
+ .bind("ifStmt"),
+ this);
+
+}
+
+void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
+ const auto *lhsVar1 = Result.Nodes.getNodeAs<Expr>("lhsVar1");
+ const auto *rhsVar1 = Result.Nodes.getNodeAs<Expr>("rhsVar1");
+ const auto *lhsVar2 = Result.Nodes.getNodeAs<Expr>("lhsVar2");
+ const auto *rhsVar2 = Result.Nodes.getNodeAs<Expr>("rhsVar2");
+ const auto *ifStmt = Result.Nodes.getNodeAs<IfStmt>("ifStmt");
+ auto &Context = *Result.Context;
+
+ 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();
+ auto lhsVar1Str = Lexer::getSourceText(CharSourceRange::getTokenRange(lhsVar1->getSourceRange()),
+ Context.getSourceManager(), Context.getLangOpts());
+
+ auto lhsVar2Str = Lexer::getSourceText(CharSourceRange::getTokenRange(lhsVar2->getSourceRange()),
+ Context.getSourceManager(), Context.getLangOpts());
+
+ auto rhsVar1Str = Lexer::getSourceText(CharSourceRange::getTokenRange(rhsVar1->getSourceRange()),
+ Context.getSourceManager(), Context.getLangOpts());
+
+ auto rhsVar2Str = Lexer::getSourceText(CharSourceRange::getTokenRange(rhsVar2->getSourceRange()),
+ Context.getSourceManager(), Context.getLangOpts());
+
+ if (binaryOp->getOpcode() == BO_LT) {
+ if (lhsVar1Str == lhsVar2Str &&
+ rhsVar1Str == rhsVar2Str) {
+ diag(ifStmt->getIfLoc(), "use `std::max` instead of `<`")
+ << FixItHint::CreateReplacement(
+ SourceRange(ifLocation, thenLocation),
+ lhsVar2Str.str() + " = std::max(" +
+ lhsVar1Str.str() + ", " +
+ rhsVar1Str.str() + ")");
+ } else if (lhsVar1Str == rhsVar2Str &&
+ rhsVar1Str == lhsVar2Str) {
+ diag(ifStmt->getIfLoc(), "use `std::min` instead of `<`")
+ << FixItHint::CreateReplacement(
+ SourceRange(ifLocation, thenLocation),
+ lhsVar2Str.str() + " = std::min(" +
+ lhsVar1Str.str() + ", " +
+ rhsVar1Str.str() + ")");
+ }
+ } else if (binaryOp->getOpcode() == BO_GT) {
+ if (lhsVar1Str == lhsVar2Str &&
+ rhsVar1Str == rhsVar2Str) {
+ diag(ifStmt->getIfLoc(), "use `std::min` instead of `>`")
+ << FixItHint::CreateReplacement(
+ SourceRange(ifLocation, thenLocation),
+ lhsVar2Str.str() + " = std::min(" +
+ lhsVar1Str.str() + ", " +
+ rhsVar1Str.str() + ")");
+ } else if (lhsVar1Str == rhsVar2Str &&
+ rhsVar1Str == lhsVar2Str) {
+ diag(ifStmt->getIfLoc(), "use `std::max` instead of `>`")
+ << FixItHint::CreateReplacement(
+ SourceRange(ifLocation, thenLocation),
+ lhsVar2Str.str() + " = std::max(" +
+ lhsVar1Str.str() + ", " +
+ rhsVar1Str.str() + ")");
+ }
+ }
+
+}
+
+} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
new file mode 100644
index 000000000000000..476b19ba5c9cf99
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
@@ -0,0 +1,38 @@
+//===--- UseStdMinMaxCheck.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_USESTDMINMAXCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USESTDMINMAXCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::readability {
+
+/// replaces certain conditional statements with equivalent ``std::min`` or
+/// ``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/UseStdMinMax.html
+class UseStdMinMaxCheck : public ClangTidyCheck {
+public:
+ UseStdMinMaxCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context) {}
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+ return LangOpts.CPlusPlus;
+ }
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ std::optional<TraversalKind> getCheckTraversalKind() const override {
+ return TK_IgnoreUnlessSpelledInSource;
+ }
+};
+
+} // namespace clang::tidy::readability
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USESTDMINMAXCHECK_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index b4d87e0ed2a67ae..2d3a2c2981e6ca0 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -224,6 +224,11 @@ New checks
Recommends the smallest possible underlying type for an ``enum`` or ``enum``
class based on the range of its enumerators.
+- New :doc:`readability-use-std-min-max
+ <clang-tidy/checks/readability/use-std-min-max>` check.
+
+ FIXME: add release notes.
+
- New :doc:`readability-reference-to-constructed-temporary
<clang-tidy/checks/readability/reference-to-constructed-temporary>` check.
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 2f86121ad872998..25b3550a77e4631 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -336,6 +336,7 @@ Clang-Tidy Checks
:doc:`portability-restrict-system-includes <portability/restrict-system-includes>`, "Yes"
:doc:`portability-simd-intrinsics <portability/simd-intrinsics>`,
:doc:`portability-std-allocator-const <portability/std-allocator-const>`,
+ :doc:`readability-use-std-min-max <readability/use-std-min-max>`, "Yes"
:doc:`readability-avoid-const-params-in-decls <readability/avoid-const-params-in-decls>`, "Yes"
:doc:`readability-avoid-return-with-void-value <readability/avoid-return-with-void-value>`,
:doc:`readability-avoid-unconditional-preprocessor-if <readability/avoid-unconditional-preprocessor-if>`,
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/UseStdMinMax.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/UseStdMinMax.rst
new file mode 100644
index 000000000000000..c8b9bdc7c5ea3bd
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/UseStdMinMax.rst
@@ -0,0 +1,33 @@
+.. title:: clang-tidy - readability-use-std-min-max
+
+readability-use-std-min-max
+========================
+
+Replaces certain conditional statements with equivalent ``std::min`` or ``std::max`` expressions,
+improving readability and promoting the use of standard library functions.
+Note: While this transformation improves code clarity, it may not be
+suitable for performance-critical code. Using ``std::min`` or ``std::max`` can
+introduce additional stores, potentially impacting performance compared to
+the original if statement that only assigns when the value needs to change.
+
+Examples:
+
+Before:
+
+.. code-block:: c++
+
+ void foo(){
+ int a,b;
+ if(a < b)
+ a = b;
+ }
+
+
+After:
+
+.. code-block:: c++
+
+ void foo(){
+ a = std::max(a, b);
+
+ }
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
new file mode 100644
index 000000000000000..37ee1fd65fb9150
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
@@ -0,0 +1,35 @@
+// RUN: %check_clang_tidy %s readability-use-std-min-max %t
+
+void foo() {
+ int value1,value2,value3;
+ short value4;
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ if (value1 < value2)
+ value1 = value2; // CHECK-FIXES: value1 = std::max(value1, value2);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
+ if (value1 < value2)
+ value2 = value1; // CHECK-FIXES: value2 = std::min(value1, value2);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
+ if (value2 > value1)
+ value2 = value1; // CHECK-FIXES: value2 = std::min(value2, value1);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `>` [readability-use-std-min-max
+ if (value2 > value1)
+ value1 = value2; // CHECK-FIXES: value1 = std::max(value2, value1);
+
+ // No suggestion needed here
+ if (value1 == value2)
+ value1 = value2;
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ if(value1<value4)
+ value1=value4; // CHECK-FIXES: value1 = std::max(value1, value4);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
+ if(value1+value2<value3)
+ value3 = value1+value2; // CHECK-FIXES: value3 = std::min(value1+value2, value3);
+
+}
\ No newline at end of file
>From 1139ac49be8023011bd57a2462781ac8b219c161 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 12 Jan 2024 17:24:47 +0530
Subject: [PATCH 08/31] Formatted the Code
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/UseStdMinMaxCheck.cpp | 88 +++++++++----------
1 file changed, 41 insertions(+), 47 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 984792322ce5d30..f203ec1e89b35e4 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -17,18 +17,17 @@ using namespace clang::ast_matchers;
namespace clang::tidy::readability {
void UseStdMinMaxCheck::registerMatchers(MatchFinder *Finder) {
- Finder->addMatcher(
- ifStmt(has(binaryOperator(
- anyOf(hasOperatorName("<"), hasOperatorName(">"),hasOperatorName("<="), hasOperatorName(">=")),
- hasLHS(expr().bind("lhsVar1")),
- hasRHS(expr().bind("rhsVar1")))),
- hasThen(stmt(binaryOperator(
- hasOperatorName("="),
- hasLHS(expr().bind("lhsVar2")),
- hasRHS(expr().bind("rhsVar2"))))))
+ Finder->addMatcher(
+ ifStmt(
+ has(binaryOperator(
+ anyOf(hasOperatorName("<"), hasOperatorName(">"),
+ hasOperatorName("<="), hasOperatorName(">=")),
+ hasLHS(expr().bind("lhsVar1")), hasRHS(expr().bind("rhsVar1")))),
+ hasThen(stmt(binaryOperator(hasOperatorName("="),
+ hasLHS(expr().bind("lhsVar2")),
+ hasRHS(expr().bind("rhsVar2"))))))
.bind("ifStmt"),
this);
-
}
void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
@@ -48,56 +47,51 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
SourceLocation ifLocation = ifStmt->getIfLoc();
SourceLocation thenLocation = ifStmt->getEndLoc();
- auto lhsVar1Str = Lexer::getSourceText(CharSourceRange::getTokenRange(lhsVar1->getSourceRange()),
- Context.getSourceManager(), Context.getLangOpts());
+ auto lhsVar1Str = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(lhsVar1->getSourceRange()),
+ Context.getSourceManager(), Context.getLangOpts());
- auto lhsVar2Str = Lexer::getSourceText(CharSourceRange::getTokenRange(lhsVar2->getSourceRange()),
- Context.getSourceManager(), Context.getLangOpts());
+ auto lhsVar2Str = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(lhsVar2->getSourceRange()),
+ Context.getSourceManager(), Context.getLangOpts());
- auto rhsVar1Str = Lexer::getSourceText(CharSourceRange::getTokenRange(rhsVar1->getSourceRange()),
- Context.getSourceManager(), Context.getLangOpts());
+ auto rhsVar1Str = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(rhsVar1->getSourceRange()),
+ Context.getSourceManager(), Context.getLangOpts());
- auto rhsVar2Str = Lexer::getSourceText(CharSourceRange::getTokenRange(rhsVar2->getSourceRange()),
- Context.getSourceManager(), Context.getLangOpts());
+ auto rhsVar2Str = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(rhsVar2->getSourceRange()),
+ Context.getSourceManager(), Context.getLangOpts());
if (binaryOp->getOpcode() == BO_LT) {
- if (lhsVar1Str == lhsVar2Str &&
- rhsVar1Str == rhsVar2Str) {
+ if (lhsVar1Str == lhsVar2Str && rhsVar1Str == rhsVar2Str) {
diag(ifStmt->getIfLoc(), "use `std::max` instead of `<`")
- << FixItHint::CreateReplacement(
- SourceRange(ifLocation, thenLocation),
- lhsVar2Str.str() + " = std::max(" +
- lhsVar1Str.str() + ", " +
- rhsVar1Str.str() + ")");
- } else if (lhsVar1Str == rhsVar2Str &&
- rhsVar1Str == lhsVar2Str) {
+ << FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
+ lhsVar2Str.str() + " = std::max(" +
+ lhsVar1Str.str() + ", " +
+ rhsVar1Str.str() + ")");
+ } else if (lhsVar1Str == rhsVar2Str && rhsVar1Str == lhsVar2Str) {
diag(ifStmt->getIfLoc(), "use `std::min` instead of `<`")
- << FixItHint::CreateReplacement(
- SourceRange(ifLocation, thenLocation),
- lhsVar2Str.str() + " = std::min(" +
- lhsVar1Str.str() + ", " +
- rhsVar1Str.str() + ")");
+ << FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
+ lhsVar2Str.str() + " = std::min(" +
+ lhsVar1Str.str() + ", " +
+ rhsVar1Str.str() + ")");
}
} else if (binaryOp->getOpcode() == BO_GT) {
- if (lhsVar1Str == lhsVar2Str &&
- rhsVar1Str == rhsVar2Str) {
+ if (lhsVar1Str == lhsVar2Str && rhsVar1Str == rhsVar2Str) {
diag(ifStmt->getIfLoc(), "use `std::min` instead of `>`")
- << FixItHint::CreateReplacement(
- SourceRange(ifLocation, thenLocation),
- lhsVar2Str.str() + " = std::min(" +
- lhsVar1Str.str() + ", " +
- rhsVar1Str.str() + ")");
- } else if (lhsVar1Str == rhsVar2Str &&
- rhsVar1Str == lhsVar2Str) {
+ << FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
+ lhsVar2Str.str() + " = std::min(" +
+ lhsVar1Str.str() + ", " +
+ rhsVar1Str.str() + ")");
+ } else if (lhsVar1Str == rhsVar2Str && rhsVar1Str == lhsVar2Str) {
diag(ifStmt->getIfLoc(), "use `std::max` instead of `>`")
- << FixItHint::CreateReplacement(
- SourceRange(ifLocation, thenLocation),
- lhsVar2Str.str() + " = std::max(" +
- lhsVar1Str.str() + ", " +
- rhsVar1Str.str() + ")");
+ << FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
+ lhsVar2Str.str() + " = std::max(" +
+ lhsVar1Str.str() + ", " +
+ rhsVar1Str.str() + ")");
}
}
-
}
} // namespace clang::tidy::readability
>From f73e9f019a03f5f864e952ddbad288d9a11b801e Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 12 Jan 2024 17:27:10 +0530
Subject: [PATCH 09/31] Added Release Notes
Signed-off-by: 11happy <soni5happy at gmail.com>
---
clang-tools-extra/docs/ReleaseNotes.rst | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 2d3a2c2981e6ca0..314e0eb69f79343 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -227,7 +227,9 @@ New checks
- New :doc:`readability-use-std-min-max
<clang-tidy/checks/readability/use-std-min-max>` check.
- FIXME: add release notes.
+ Replaces certain conditional statements with equivalent ``std::min`` or
+ ``std::max`` expressions, improving readability and promoting the use of
+ standard library functions.
- New :doc:`readability-reference-to-constructed-temporary
<clang-tidy/checks/readability/reference-to-constructed-temporary>` check.
>From faf3312b6d6713cb9af43ae09ca66f3ac05878bf Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 12 Jan 2024 17:31:38 +0530
Subject: [PATCH 10/31] corrected file name
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../checks/readability/{UseStdMinMax.rst => use-std-min-max.rst} | 0
1 file changed, 0 insertions(+), 0 deletions(-)
rename clang-tools-extra/docs/clang-tidy/checks/readability/{UseStdMinMax.rst => use-std-min-max.rst} (100%)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/UseStdMinMax.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
similarity index 100%
rename from clang-tools-extra/docs/clang-tidy/checks/readability/UseStdMinMax.rst
rename to clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
>From 5ed9896cffdbf057b4e8088a37c98a50e0e4d946 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 12 Jan 2024 17:35:44 +0530
Subject: [PATCH 11/31] corrected title length in docs
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../docs/clang-tidy/checks/readability/use-std-min-max.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
index c8b9bdc7c5ea3bd..573beeeb2a842b9 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
@@ -1,7 +1,7 @@
.. title:: clang-tidy - readability-use-std-min-max
readability-use-std-min-max
-========================
+===========================
Replaces certain conditional statements with equivalent ``std::min`` or ``std::max`` expressions,
improving readability and promoting the use of standard library functions.
>From 19c4b63da4a183f661a6e06fabc78aaf4e2868e4 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 12 Jan 2024 21:54:46 +0530
Subject: [PATCH 12/31] Suggested Changes
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/UseStdMinMaxCheck.cpp | 2 +-
.../checks/readability/use-std-min-max.rst | 22 +++++++++----------
.../checkers/readability/use-std-min-max.cpp | 1 -
3 files changed, 11 insertions(+), 14 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index f203ec1e89b35e4..1a4392523cf187d 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -41,7 +41,7 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
if (!lhsVar1 || !rhsVar1 || !lhsVar2 || !rhsVar2 || !ifStmt)
return;
- const BinaryOperator *binaryOp = dyn_cast<BinaryOperator>(ifStmt->getCond());
+ const auto *binaryOp = dyn_cast<BinaryOperator>(ifStmt->getCond());
if (!binaryOp)
return;
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
index 573beeeb2a842b9..2364acacbaffd7d 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
@@ -5,10 +5,8 @@ readability-use-std-min-max
Replaces certain conditional statements with equivalent ``std::min`` or ``std::max`` expressions,
improving readability and promoting the use of standard library functions.
-Note: While this transformation improves code clarity, it may not be
-suitable for performance-critical code. Using ``std::min`` or ``std::max`` can
-introduce additional stores, potentially impacting performance compared to
-the original if statement that only assigns when the value needs to change.
+Note: this transformation may impact performance in performance-critical code due to potential
+additional stores compared to the original if statement.
Examples:
@@ -16,18 +14,18 @@ Before:
.. code-block:: c++
- void foo(){
- int a,b;
- if(a < b)
- a = b;
- }
+ void foo() {
+ int a, b;
+ if (a < b)
+ a = b;
+ }
After:
.. code-block:: c++
- void foo(){
- a = std::max(a, b);
-
+ void foo() {
+ int a, b;
+ a = std::max(a, b);
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
index 37ee1fd65fb9150..b65e3a9b27cc216 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
@@ -31,5 +31,4 @@ void foo() {
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
if(value1+value2<value3)
value3 = value1+value2; // CHECK-FIXES: value3 = std::min(value1+value2, value3);
-
}
\ No newline at end of file
>From 8167787453886874b8e458f040c878ad7e711016 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 12 Jan 2024 22:35:17 +0530
Subject: [PATCH 13/31] body indentation
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../clang-tidy/checks/readability/use-std-min-max.rst | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
index 2364acacbaffd7d..de22f069d219232 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
@@ -15,9 +15,9 @@ Before:
.. code-block:: c++
void foo() {
- int a, b;
- if (a < b)
- a = b;
+ int a, b;
+ if (a < b)
+ a = b;
}
@@ -26,6 +26,6 @@ After:
.. code-block:: c++
void foo() {
- int a, b;
- a = std::max(a, b);
+ int a, b;
+ a = std::max(a, b);
}
>From 3a28399a08b4625abe7d08dee82fbee850de534e Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Sat, 13 Jan 2024 21:17:23 +0530
Subject: [PATCH 14/31] added intialisation,constexpr tests
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../checks/readability/use-std-min-max.rst | 4 ++--
.../checkers/readability/use-std-min-max.cpp | 23 +++++++++++++++++++
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
index de22f069d219232..0d621d4d4477f20 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
@@ -15,7 +15,7 @@ Before:
.. code-block:: c++
void foo() {
- int a, b;
+ int a = 2, b = 3;
if (a < b)
a = b;
}
@@ -26,6 +26,6 @@ After:
.. code-block:: c++
void foo() {
- int a, b;
+ int a = 2, b = 3;
a = std::max(a, b);
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
index b65e3a9b27cc216..1dc48ffc63cfb5e 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
@@ -1,5 +1,16 @@
// RUN: %check_clang_tidy %s readability-use-std-min-max %t
+constexpr int myConstexprMin(int a, int b) {
+ return a < b ? a : b;
+}
+
+constexpr int myConstexprMax(int a, int b) {
+ return a > b ? a : b;
+}
+
+int bar(int x, int y) {
+ return x < y ? x : y;
+}
void foo() {
int value1,value2,value3;
short value4;
@@ -31,4 +42,16 @@ void foo() {
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
if(value1+value2<value3)
value3 = value1+value2; // CHECK-FIXES: value3 = std::min(value1+value2, value3);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ if (value1 < myConstexprMin(value2, value3))
+ value1 = myConstexprMin(value2, value3); // CHECK-FIXES: value1 = std::max(value1, myConstexprMin(value2, value3));
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
+ if (value1 > myConstexprMax(value2, value3))
+ value1 = myConstexprMax(value2, value3); // CHECK-FIXES: value1 = std::min(value1, myConstexprMax(value2, value3));
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ if (value1 < bar(value2, value3))
+ value1 = bar(value2, value3); // CHECK-FIXES: value1 = std::max(value1, bar(value2, value3));
}
\ No newline at end of file
>From 2ecd08a149d60b9dfdc54d777bf10b34758054a8 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Sat, 13 Jan 2024 21:32:22 +0530
Subject: [PATCH 15/31] small fixes
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../clang-tidy/checks/readability/use-std-min-max.rst | 9 +++++----
.../clang-tidy/checkers/readability/use-std-min-max.cpp | 1 +
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
index 0d621d4d4477f20..7e64a05ccd8b89d 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
@@ -3,10 +3,11 @@
readability-use-std-min-max
===========================
-Replaces certain conditional statements with equivalent ``std::min`` or ``std::max`` expressions,
-improving readability and promoting the use of standard library functions.
-Note: this transformation may impact performance in performance-critical code due to potential
-additional stores compared to the original if statement.
+Replaces certain conditionals with ``std::min`` or ``std::max`` for readability,
+promoting use of standard library functions. Note: This may impact
+performance in critical code due to potential additional stores compared
+to the original if statement.
+
Examples:
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
index 1dc48ffc63cfb5e..9525d5e1f24890c 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
@@ -11,6 +11,7 @@ constexpr int myConstexprMax(int a, int b) {
int bar(int x, int y) {
return x < y ? x : y;
}
+
void foo() {
int value1,value2,value3;
short value4;
>From 00d4080a6a1f4af2b79b748ff60527aae10c9f97 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Mon, 15 Jan 2024 21:12:17 +0530
Subject: [PATCH 16/31] Addded Suggested Changes
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/UseStdMinMaxCheck.cpp | 50 +++++++--------
.../readability/UseStdMinMaxCheck.h | 2 +-
.../checkers/readability/use-std-min-max.cpp | 63 +++++++++++++++++++
3 files changed, 88 insertions(+), 27 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 1a4392523cf187d..833d27d4957b38f 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -8,6 +8,7 @@
#include "UseStdMinMaxCheck.h"
#include "clang/AST/ASTContext.h"
+#include "../utils/ASTUtils.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Preprocessor.h"
#include <optional>
@@ -47,6 +48,7 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
SourceLocation ifLocation = ifStmt->getIfLoc();
SourceLocation thenLocation = ifStmt->getEndLoc();
+
auto lhsVar1Str = Lexer::getSourceText(
CharSourceRange::getTokenRange(lhsVar1->getSourceRange()),
Context.getSourceManager(), Context.getLangOpts());
@@ -58,38 +60,34 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
auto rhsVar1Str = Lexer::getSourceText(
CharSourceRange::getTokenRange(rhsVar1->getSourceRange()),
Context.getSourceManager(), Context.getLangOpts());
+
+ auto replacementMax = lhsVar2Str.str() + " = std::max(" + lhsVar1Str.str() + ", " + rhsVar1Str.str() + ")";
+ auto replacementMin = lhsVar2Str.str() + " = std::min(" + lhsVar1Str.str() + ", " + rhsVar1Str.str() + ")";
+ auto *operatorStr = binaryOp->getOpcodeStr().data();
- auto rhsVar2Str = Lexer::getSourceText(
- CharSourceRange::getTokenRange(rhsVar2->getSourceRange()),
- Context.getSourceManager(), Context.getLangOpts());
-
- if (binaryOp->getOpcode() == BO_LT) {
- if (lhsVar1Str == lhsVar2Str && rhsVar1Str == rhsVar2Str) {
- diag(ifStmt->getIfLoc(), "use `std::max` instead of `<`")
+ if (binaryOp->getOpcode() == BO_LT || binaryOp->getOpcode() == BO_LE) {
+ if (tidy::utils::areStatementsIdentical(lhsVar1, lhsVar2,Context) &&
+ tidy::utils::areStatementsIdentical(rhsVar1, rhsVar2,Context)) {
+ diag(ifStmt->getIfLoc(), "use `std::max` instead of `%0`")<< operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- lhsVar2Str.str() + " = std::max(" +
- lhsVar1Str.str() + ", " +
- rhsVar1Str.str() + ")");
- } else if (lhsVar1Str == rhsVar2Str && rhsVar1Str == lhsVar2Str) {
- diag(ifStmt->getIfLoc(), "use `std::min` instead of `<`")
+ std::move(replacementMax));
+ } else if (tidy::utils::areStatementsIdentical(lhsVar1, rhsVar2,Context) &&
+ tidy::utils::areStatementsIdentical(rhsVar1, lhsVar2,Context)) {
+ diag(ifStmt->getIfLoc(), "use `std::min` instead of `%0`")<< operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- lhsVar2Str.str() + " = std::min(" +
- lhsVar1Str.str() + ", " +
- rhsVar1Str.str() + ")");
+ std::move(replacementMin));
}
- } else if (binaryOp->getOpcode() == BO_GT) {
- if (lhsVar1Str == lhsVar2Str && rhsVar1Str == rhsVar2Str) {
- diag(ifStmt->getIfLoc(), "use `std::min` instead of `>`")
+ } else if (binaryOp->getOpcode() == BO_GT || binaryOp->getOpcode() == BO_GE) {
+ if (tidy::utils::areStatementsIdentical(lhsVar1, lhsVar2,Context) &&
+ tidy::utils::areStatementsIdentical(rhsVar1, rhsVar2,Context)) {
+ diag(ifStmt->getIfLoc(), "use `std::min` instead of `%0`")<< operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- lhsVar2Str.str() + " = std::min(" +
- lhsVar1Str.str() + ", " +
- rhsVar1Str.str() + ")");
- } else if (lhsVar1Str == rhsVar2Str && rhsVar1Str == lhsVar2Str) {
- diag(ifStmt->getIfLoc(), "use `std::max` instead of `>`")
+ std::move(replacementMin));
+ } else if (tidy::utils::areStatementsIdentical(lhsVar1, rhsVar2,Context) &&
+ tidy::utils::areStatementsIdentical(rhsVar1, lhsVar2,Context)) {
+ diag(ifStmt->getIfLoc(), "use `std::max` instead of `%0`")<< operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- lhsVar2Str.str() + " = std::max(" +
- lhsVar1Str.str() + ", " +
- rhsVar1Str.str() + ")");
+ std::move(replacementMax));
}
}
}
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
index 476b19ba5c9cf99..d6f4fdf40ea3062 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
@@ -13,7 +13,7 @@
namespace clang::tidy::readability {
-/// replaces certain conditional statements with equivalent ``std::min`` or
+/// Replaces certain conditional statements with equivalent ``std::min`` or
/// ``std::max`` expressions, improving readability and promoting the use of
/// standard library functions.
///
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
index 9525d5e1f24890c..99be29fb163bb6c 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
@@ -12,9 +12,16 @@ int bar(int x, int y) {
return x < y ? x : y;
}
+class MyClass {
+public:
+ int member1;
+ int member2;
+};
+
void foo() {
int value1,value2,value3;
short value4;
+ MyClass obj;
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
if (value1 < value2)
@@ -55,4 +62,60 @@ void foo() {
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
if (value1 < bar(value2, value3))
value1 = bar(value2, value3); // CHECK-FIXES: value1 = std::max(value1, bar(value2, value3));
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `<=` [readability-use-std-min-max]
+ if (value1 <= value2)
+ value2 = value1; // CHECK-FIXES: value2 = std::min(value1, value2);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<=` [readability-use-std-min-max]
+ if (value1 <= value2)
+ value1 = value2; // CHECK-FIXES: value1 = std::max(value1, value2);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `>=` [readability-use-std-min-max]
+ if (value2 >= value1)
+ value1 = value2; // CHECK-FIXES: value1 = std::max(value2, value1);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `>=` [readability-use-std-min-max]
+ if (value2 >= value1)
+ value2 = value1; // CHECK-FIXES: value2 = std::min(value2, value1);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ if (obj.member1 < obj.member2)
+ obj.member1 = obj.member2; // CHECK-FIXES: obj.member1 = std::max(obj.member1, obj.member2);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
+ if (obj.member1 < obj.member2)
+ obj.member2 = obj.member1; // CHECK-FIXES: obj.member2 = std::min(obj.member1, obj.member2);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
+ if (obj.member2 > obj.member1)
+ obj.member2 = obj.member1; // CHECK-FIXES: obj.member2 = std::min(obj.member2, obj.member1);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `>` [readability-use-std-min-max]
+ if (obj.member2 > obj.member1)
+ obj.member1 = obj.member2; // CHECK-FIXES: obj.member1 = std::max(obj.member2, obj.member1);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ if (obj.member1 < value4)
+ obj.member1 = value4; // CHECK-FIXES: obj.member1 = std::max(obj.member1, value4);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
+ if (obj.member1 + value2 < value3)
+ value3 = obj.member1 + value2; // CHECK-FIXES: value3 = std::min(obj.member1 + value2, value3);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `<=` [readability-use-std-min-max]
+ if (value1 <= obj.member2)
+ obj.member2 = value1; // CHECK-FIXES: obj.member2 = std::min(value1, obj.member2);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<=` [readability-use-std-min-max]
+ if (value1 <= obj.member2)
+ value1 = obj.member2; // CHECK-FIXES: value1 = std::max(value1, obj.member2);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `>=` [readability-use-std-min-max]
+ if (obj.member2 >= value1)
+ value1 = obj.member2; // CHECK-FIXES: value1 = std::max(obj.member2, value1);
+
+ // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `>=` [readability-use-std-min-max]
+ if (obj.member2 >= value1)
+ obj.member2 = value1; // CHECK-FIXES: obj.member2 = std::min(obj.member2, value1);
}
\ No newline at end of file
>From 6db08204966b52862ecdcf5ff829fe06e266b882 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Mon, 15 Jan 2024 21:12:41 +0530
Subject: [PATCH 17/31] formatted the code
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/UseStdMinMaxCheck.cpp | 46 +++++++++++--------
1 file changed, 26 insertions(+), 20 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 833d27d4957b38f..2f7a8d944a50458 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -7,8 +7,8 @@
//===----------------------------------------------------------------------===//
#include "UseStdMinMaxCheck.h"
-#include "clang/AST/ASTContext.h"
#include "../utils/ASTUtils.h"
+#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Preprocessor.h"
#include <optional>
@@ -60,34 +60,40 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
auto rhsVar1Str = Lexer::getSourceText(
CharSourceRange::getTokenRange(rhsVar1->getSourceRange()),
Context.getSourceManager(), Context.getLangOpts());
-
- auto replacementMax = lhsVar2Str.str() + " = std::max(" + lhsVar1Str.str() + ", " + rhsVar1Str.str() + ")";
- auto replacementMin = lhsVar2Str.str() + " = std::min(" + lhsVar1Str.str() + ", " + rhsVar1Str.str() + ")";
+
+ auto replacementMax = lhsVar2Str.str() + " = std::max(" + lhsVar1Str.str() +
+ ", " + rhsVar1Str.str() + ")";
+ auto replacementMin = lhsVar2Str.str() + " = std::min(" + lhsVar1Str.str() +
+ ", " + rhsVar1Str.str() + ")";
auto *operatorStr = binaryOp->getOpcodeStr().data();
if (binaryOp->getOpcode() == BO_LT || binaryOp->getOpcode() == BO_LE) {
- if (tidy::utils::areStatementsIdentical(lhsVar1, lhsVar2,Context) &&
- tidy::utils::areStatementsIdentical(rhsVar1, rhsVar2,Context)) {
- diag(ifStmt->getIfLoc(), "use `std::max` instead of `%0`")<< operatorStr
+ if (tidy::utils::areStatementsIdentical(lhsVar1, lhsVar2, Context) &&
+ tidy::utils::areStatementsIdentical(rhsVar1, rhsVar2, Context)) {
+ diag(ifStmt->getIfLoc(), "use `std::max` instead of `%0`")
+ << operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMax));
- } else if (tidy::utils::areStatementsIdentical(lhsVar1, rhsVar2,Context) &&
- tidy::utils::areStatementsIdentical(rhsVar1, lhsVar2,Context)) {
- diag(ifStmt->getIfLoc(), "use `std::min` instead of `%0`")<< operatorStr
+ std::move(replacementMax));
+ } else if (tidy::utils::areStatementsIdentical(lhsVar1, rhsVar2, Context) &&
+ tidy::utils::areStatementsIdentical(rhsVar1, lhsVar2, Context)) {
+ diag(ifStmt->getIfLoc(), "use `std::min` instead of `%0`")
+ << operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMin));
+ std::move(replacementMin));
}
} else if (binaryOp->getOpcode() == BO_GT || binaryOp->getOpcode() == BO_GE) {
- if (tidy::utils::areStatementsIdentical(lhsVar1, lhsVar2,Context) &&
- tidy::utils::areStatementsIdentical(rhsVar1, rhsVar2,Context)) {
- diag(ifStmt->getIfLoc(), "use `std::min` instead of `%0`")<< operatorStr
+ if (tidy::utils::areStatementsIdentical(lhsVar1, lhsVar2, Context) &&
+ tidy::utils::areStatementsIdentical(rhsVar1, rhsVar2, Context)) {
+ diag(ifStmt->getIfLoc(), "use `std::min` instead of `%0`")
+ << operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMin));
- } else if (tidy::utils::areStatementsIdentical(lhsVar1, rhsVar2,Context) &&
- tidy::utils::areStatementsIdentical(rhsVar1, lhsVar2,Context)) {
- diag(ifStmt->getIfLoc(), "use `std::max` instead of `%0`")<< operatorStr
+ std::move(replacementMin));
+ } else if (tidy::utils::areStatementsIdentical(lhsVar1, rhsVar2, Context) &&
+ tidy::utils::areStatementsIdentical(rhsVar1, lhsVar2, Context)) {
+ diag(ifStmt->getIfLoc(), "use `std::max` instead of `%0`")
+ << operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMax));
+ std::move(replacementMax));
}
}
}
>From 5073650de12a6588cd171bccfc67f6298065f82e Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Tue, 16 Jan 2024 03:38:20 +0530
Subject: [PATCH 18/31] Added Include Check
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/UseStdMinMaxCheck.cpp | 26 ++++++++++++++++---
.../readability/UseStdMinMaxCheck.h | 11 +++++---
2 files changed, 30 insertions(+), 7 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 2f7a8d944a50458..b7f9f65c71ad678 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -17,6 +17,16 @@ using namespace clang::ast_matchers;
namespace clang::tidy::readability {
+UseStdMinMaxCheck::UseStdMinMaxCheck(StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
+ utils::IncludeSorter::IS_LLVM),
+ areDiagsSelfContained()),AlgotithmHeader(Options.get("AlgorithmHeader","<algorithm>")) {}
+
+void UseStdMinMaxCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+}
+
void UseStdMinMaxCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
ifStmt(
@@ -31,6 +41,12 @@ void UseStdMinMaxCheck::registerMatchers(MatchFinder *Finder) {
this);
}
+void UseStdMinMaxCheck::registerPPCallbacks(const SourceManager &SM,
+ Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) {
+ IncludeInserter.registerPreprocessor(PP);
+}
+
void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
const auto *lhsVar1 = Result.Nodes.getNodeAs<Expr>("lhsVar1");
const auto *rhsVar1 = Result.Nodes.getNodeAs<Expr>("rhsVar1");
@@ -38,6 +54,7 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
const auto *rhsVar2 = Result.Nodes.getNodeAs<Expr>("rhsVar2");
const auto *ifStmt = Result.Nodes.getNodeAs<IfStmt>("ifStmt");
auto &Context = *Result.Context;
+ const SourceManager &Source = Context.getSourceManager();
if (!lhsVar1 || !rhsVar1 || !lhsVar2 || !rhsVar2 || !ifStmt)
return;
@@ -70,16 +87,17 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
if (binaryOp->getOpcode() == BO_LT || binaryOp->getOpcode() == BO_LE) {
if (tidy::utils::areStatementsIdentical(lhsVar1, lhsVar2, Context) &&
tidy::utils::areStatementsIdentical(rhsVar1, rhsVar2, Context)) {
+
diag(ifStmt->getIfLoc(), "use `std::max` instead of `%0`")
<< operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMax));
+ std::move(replacementMax))<<IncludeInserter.createIncludeInsertion(Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
} else if (tidy::utils::areStatementsIdentical(lhsVar1, rhsVar2, Context) &&
tidy::utils::areStatementsIdentical(rhsVar1, lhsVar2, Context)) {
diag(ifStmt->getIfLoc(), "use `std::min` instead of `%0`")
<< operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMin));
+ std::move(replacementMin))<<IncludeInserter.createIncludeInsertion(Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
}
} else if (binaryOp->getOpcode() == BO_GT || binaryOp->getOpcode() == BO_GE) {
if (tidy::utils::areStatementsIdentical(lhsVar1, lhsVar2, Context) &&
@@ -87,13 +105,13 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
diag(ifStmt->getIfLoc(), "use `std::min` instead of `%0`")
<< operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMin));
+ std::move(replacementMin))<<IncludeInserter.createIncludeInsertion(Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
} else if (tidy::utils::areStatementsIdentical(lhsVar1, rhsVar2, Context) &&
tidy::utils::areStatementsIdentical(rhsVar1, lhsVar2, Context)) {
diag(ifStmt->getIfLoc(), "use `std::max` instead of `%0`")
<< operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMax));
+ std::move(replacementMax))<<IncludeInserter.createIncludeInsertion(Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
}
}
}
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
index d6f4fdf40ea3062..c92e80a351e1bdc 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
@@ -10,7 +10,7 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USESTDMINMAXCHECK_H
#include "../ClangTidyCheck.h"
-
+#include "../utils/IncludeInserter.h"
namespace clang::tidy::readability {
/// Replaces certain conditional statements with equivalent ``std::min`` or
@@ -21,16 +21,21 @@ namespace clang::tidy::readability {
/// http://clang.llvm.org/extra/clang-tidy/checks/readability/UseStdMinMax.html
class UseStdMinMaxCheck : public ClangTidyCheck {
public:
- UseStdMinMaxCheck(StringRef Name, ClangTidyContext *Context)
- : ClangTidyCheck(Name, Context) {}
+ UseStdMinMaxCheck(StringRef Name, ClangTidyContext *Context);
bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
return LangOpts.CPlusPlus;
}
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) override;
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
std::optional<TraversalKind> getCheckTraversalKind() const override {
return TK_IgnoreUnlessSpelledInSource;
}
+ private:
+ utils::IncludeInserter IncludeInserter;
+ StringRef AlgotithmHeader;
};
} // namespace clang::tidy::readability
>From c728a39c8a11fc17130a49c6d472fff2133ce6dc Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Tue, 16 Jan 2024 03:38:52 +0530
Subject: [PATCH 19/31] Formatted the code
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/UseStdMinMaxCheck.cpp | 21 +++++++++++++------
.../readability/UseStdMinMaxCheck.h | 3 ++-
2 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index b7f9f65c71ad678..15e26f9baf68b93 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -21,7 +21,8 @@ UseStdMinMaxCheck::UseStdMinMaxCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
- areDiagsSelfContained()),AlgotithmHeader(Options.get("AlgorithmHeader","<algorithm>")) {}
+ areDiagsSelfContained()),
+ AlgotithmHeader(Options.get("AlgorithmHeader", "<algorithm>")) {}
void UseStdMinMaxCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
@@ -87,17 +88,21 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
if (binaryOp->getOpcode() == BO_LT || binaryOp->getOpcode() == BO_LE) {
if (tidy::utils::areStatementsIdentical(lhsVar1, lhsVar2, Context) &&
tidy::utils::areStatementsIdentical(rhsVar1, rhsVar2, Context)) {
-
+
diag(ifStmt->getIfLoc(), "use `std::max` instead of `%0`")
<< operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMax))<<IncludeInserter.createIncludeInsertion(Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
+ std::move(replacementMax))
+ << IncludeInserter.createIncludeInsertion(
+ Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
} else if (tidy::utils::areStatementsIdentical(lhsVar1, rhsVar2, Context) &&
tidy::utils::areStatementsIdentical(rhsVar1, lhsVar2, Context)) {
diag(ifStmt->getIfLoc(), "use `std::min` instead of `%0`")
<< operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMin))<<IncludeInserter.createIncludeInsertion(Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
+ std::move(replacementMin))
+ << IncludeInserter.createIncludeInsertion(
+ Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
}
} else if (binaryOp->getOpcode() == BO_GT || binaryOp->getOpcode() == BO_GE) {
if (tidy::utils::areStatementsIdentical(lhsVar1, lhsVar2, Context) &&
@@ -105,13 +110,17 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
diag(ifStmt->getIfLoc(), "use `std::min` instead of `%0`")
<< operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMin))<<IncludeInserter.createIncludeInsertion(Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
+ std::move(replacementMin))
+ << IncludeInserter.createIncludeInsertion(
+ Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
} else if (tidy::utils::areStatementsIdentical(lhsVar1, rhsVar2, Context) &&
tidy::utils::areStatementsIdentical(rhsVar1, lhsVar2, Context)) {
diag(ifStmt->getIfLoc(), "use `std::max` instead of `%0`")
<< operatorStr
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMax))<<IncludeInserter.createIncludeInsertion(Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
+ std::move(replacementMax))
+ << IncludeInserter.createIncludeInsertion(
+ Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
}
}
}
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
index c92e80a351e1bdc..4146d9455bcd1de 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
@@ -33,7 +33,8 @@ class UseStdMinMaxCheck : public ClangTidyCheck {
std::optional<TraversalKind> getCheckTraversalKind() const override {
return TK_IgnoreUnlessSpelledInSource;
}
- private:
+
+private:
utils::IncludeInserter IncludeInserter;
StringRef AlgotithmHeader;
};
>From b8202aefe3e5cb07f59b7fc0d7647820987bde4b Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Wed, 17 Jan 2024 16:44:02 +0530
Subject: [PATCH 20/31] Added tests for macro & if with brackets
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/UseStdMinMaxCheck.cpp | 42 +++---
.../readability/UseStdMinMaxCheck.h | 2 +-
.../checkers/readability/use-std-min-max.cpp | 132 +++++++++++-------
3 files changed, 104 insertions(+), 72 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 15e26f9baf68b93..1b0adc2ac6876a1 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -22,7 +22,7 @@ UseStdMinMaxCheck::UseStdMinMaxCheck(StringRef Name, ClangTidyContext *Context)
IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
areDiagsSelfContained()),
- AlgotithmHeader(Options.get("AlgorithmHeader", "<algorithm>")) {}
+ AlgorithmHeader(Options.get("AlgorithmHeader", "<algorithm>")) {}
void UseStdMinMaxCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
@@ -35,9 +35,13 @@ void UseStdMinMaxCheck::registerMatchers(MatchFinder *Finder) {
anyOf(hasOperatorName("<"), hasOperatorName(">"),
hasOperatorName("<="), hasOperatorName(">=")),
hasLHS(expr().bind("lhsVar1")), hasRHS(expr().bind("rhsVar1")))),
- hasThen(stmt(binaryOperator(hasOperatorName("="),
- hasLHS(expr().bind("lhsVar2")),
- hasRHS(expr().bind("rhsVar2"))))))
+ hasThen(
+ anyOf(stmt(binaryOperator(hasOperatorName("="),
+ hasLHS(expr().bind("lhsVar2")),
+ hasRHS(expr().bind("rhsVar2")))),
+ compoundStmt(has(binaryOperator(
+ hasOperatorName("="), hasLHS(expr().bind("lhsVar2")),
+ hasRHS(expr().bind("rhsVar2"))))))))
.bind("ifStmt"),
this);
}
@@ -67,22 +71,22 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
SourceLocation ifLocation = ifStmt->getIfLoc();
SourceLocation thenLocation = ifStmt->getEndLoc();
- auto lhsVar1Str = Lexer::getSourceText(
- CharSourceRange::getTokenRange(lhsVar1->getSourceRange()),
- Context.getSourceManager(), Context.getLangOpts());
+ auto lhsVar1Str =
+ Lexer::getSourceText(Source.getExpansionRange(lhsVar1->getSourceRange()),
+ Context.getSourceManager(), Context.getLangOpts());
- auto lhsVar2Str = Lexer::getSourceText(
- CharSourceRange::getTokenRange(lhsVar2->getSourceRange()),
- Context.getSourceManager(), Context.getLangOpts());
+ auto lhsVar2Str =
+ Lexer::getSourceText(Source.getExpansionRange(lhsVar2->getSourceRange()),
+ Context.getSourceManager(), Context.getLangOpts());
- auto rhsVar1Str = Lexer::getSourceText(
- CharSourceRange::getTokenRange(rhsVar1->getSourceRange()),
- Context.getSourceManager(), Context.getLangOpts());
+ auto rhsVar1Str =
+ Lexer::getSourceText(Source.getExpansionRange(rhsVar1->getSourceRange()),
+ Context.getSourceManager(), Context.getLangOpts());
auto replacementMax = lhsVar2Str.str() + " = std::max(" + lhsVar1Str.str() +
- ", " + rhsVar1Str.str() + ")";
+ ", " + rhsVar1Str.str() + ");";
auto replacementMin = lhsVar2Str.str() + " = std::min(" + lhsVar1Str.str() +
- ", " + rhsVar1Str.str() + ")";
+ ", " + rhsVar1Str.str() + ");";
auto *operatorStr = binaryOp->getOpcodeStr().data();
if (binaryOp->getOpcode() == BO_LT || binaryOp->getOpcode() == BO_LE) {
@@ -94,7 +98,7 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
std::move(replacementMax))
<< IncludeInserter.createIncludeInsertion(
- Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
+ Source.getFileID(ifStmt->getBeginLoc()), AlgorithmHeader);
} else if (tidy::utils::areStatementsIdentical(lhsVar1, rhsVar2, Context) &&
tidy::utils::areStatementsIdentical(rhsVar1, lhsVar2, Context)) {
diag(ifStmt->getIfLoc(), "use `std::min` instead of `%0`")
@@ -102,7 +106,7 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
std::move(replacementMin))
<< IncludeInserter.createIncludeInsertion(
- Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
+ Source.getFileID(ifStmt->getBeginLoc()), AlgorithmHeader);
}
} else if (binaryOp->getOpcode() == BO_GT || binaryOp->getOpcode() == BO_GE) {
if (tidy::utils::areStatementsIdentical(lhsVar1, lhsVar2, Context) &&
@@ -112,7 +116,7 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
std::move(replacementMin))
<< IncludeInserter.createIncludeInsertion(
- Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
+ Source.getFileID(ifStmt->getBeginLoc()), AlgorithmHeader);
} else if (tidy::utils::areStatementsIdentical(lhsVar1, rhsVar2, Context) &&
tidy::utils::areStatementsIdentical(rhsVar1, lhsVar2, Context)) {
diag(ifStmt->getIfLoc(), "use `std::max` instead of `%0`")
@@ -120,7 +124,7 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
<< FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
std::move(replacementMax))
<< IncludeInserter.createIncludeInsertion(
- Source.getFileID(ifStmt->getBeginLoc()), AlgotithmHeader);
+ Source.getFileID(ifStmt->getBeginLoc()), AlgorithmHeader);
}
}
}
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
index 4146d9455bcd1de..52b34fdbe2627cc 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
@@ -36,7 +36,7 @@ class UseStdMinMaxCheck : public ClangTidyCheck {
private:
utils::IncludeInserter IncludeInserter;
- StringRef AlgotithmHeader;
+ StringRef AlgorithmHeader;
};
} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
index 99be29fb163bb6c..4a43d8f3926d4f5 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
@@ -1,5 +1,7 @@
// RUN: %check_clang_tidy %s readability-use-std-min-max %t
+#define MY_MACRO_MIN(a, b) ((a) < (b) ? (a) : (b))
+
constexpr int myConstexprMin(int a, int b) {
return a < b ? a : b;
}
@@ -8,10 +10,6 @@ constexpr int myConstexprMax(int a, int b) {
return a > b ? a : b;
}
-int bar(int x, int y) {
- return x < y ? x : y;
-}
-
class MyClass {
public:
int member1;
@@ -23,99 +21,129 @@ void foo() {
short value4;
MyClass obj;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ // CHECK-FIXES: value1 = std::max(value1, value2);
if (value1 < value2)
- value1 = value2; // CHECK-FIXES: value1 = std::max(value1, value2);
+ value1 = value2;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
+ // CHECK-FIXES: value2 = std::min(value1, value2);
if (value1 < value2)
- value2 = value1; // CHECK-FIXES: value2 = std::min(value1, value2);
+ value2 = value1;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
+ // CHECK-FIXES: value2 = std::min(value2, value1);
if (value2 > value1)
- value2 = value1; // CHECK-FIXES: value2 = std::min(value2, value1);
+ value2 = value1;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `>` [readability-use-std-min-max
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>` [readability-use-std-min-max
+ // CHECK-FIXES: value1 = std::max(value2, value1);
if (value2 > value1)
- value1 = value2; // CHECK-FIXES: value1 = std::max(value2, value1);
+ value1 = value2;
// No suggestion needed here
if (value1 == value2)
value1 = value2;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ // CHECK-FIXES: value1 = std::max(value1, value4);
if(value1<value4)
- value1=value4; // CHECK-FIXES: value1 = std::max(value1, value4);
+ value1=value4;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
+ // CHECK-FIXES: value3 = std::min(value1+value2, value3);
if(value1+value2<value3)
- value3 = value1+value2; // CHECK-FIXES: value3 = std::min(value1+value2, value3);
+ value3 = value1+value2;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ // CHECK-FIXES: value1 = std::max(value1, myConstexprMin(value2, value3));
if (value1 < myConstexprMin(value2, value3))
- value1 = myConstexprMin(value2, value3); // CHECK-FIXES: value1 = std::max(value1, myConstexprMin(value2, value3));
+ value1 = myConstexprMin(value2, value3);
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
+ // CHECK-FIXES: value1 = std::min(value1, myConstexprMax(value2, value3));
if (value1 > myConstexprMax(value2, value3))
- value1 = myConstexprMax(value2, value3); // CHECK-FIXES: value1 = std::min(value1, myConstexprMax(value2, value3));
-
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
- if (value1 < bar(value2, value3))
- value1 = bar(value2, value3); // CHECK-FIXES: value1 = std::max(value1, bar(value2, value3));
+ value1 = myConstexprMax(value2, value3);
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `<=` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<=` [readability-use-std-min-max]
+ // CHECK-FIXES: value2 = std::min(value1, value2);
if (value1 <= value2)
- value2 = value1; // CHECK-FIXES: value2 = std::min(value1, value2);
+ value2 = value1;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<=` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<=` [readability-use-std-min-max]
+ // CHECK-FIXES: value1 = std::max(value1, value2);
if (value1 <= value2)
- value1 = value2; // CHECK-FIXES: value1 = std::max(value1, value2);
+ value1 = value2;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `>=` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>=` [readability-use-std-min-max]
+ // CHECK-FIXES: value1 = std::max(value2, value1);
if (value2 >= value1)
- value1 = value2; // CHECK-FIXES: value1 = std::max(value2, value1);
+ value1 = value2;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `>=` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>=` [readability-use-std-min-max]
+ // CHECK-FIXES: value2 = std::min(value2, value1);
if (value2 >= value1)
- value2 = value1; // CHECK-FIXES: value2 = std::min(value2, value1);
+ value2 = value1;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ // CHECK-FIXES: obj.member1 = std::max(obj.member1, obj.member2);
if (obj.member1 < obj.member2)
- obj.member1 = obj.member2; // CHECK-FIXES: obj.member1 = std::max(obj.member1, obj.member2);
+ obj.member1 = obj.member2;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
+ // CHECK-FIXES: obj.member2 = std::min(obj.member1, obj.member2);
if (obj.member1 < obj.member2)
- obj.member2 = obj.member1; // CHECK-FIXES: obj.member2 = std::min(obj.member1, obj.member2);
+ obj.member2 = obj.member1;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
+ // CHECK-FIXES: obj.member2 = std::min(obj.member2, obj.member1);
if (obj.member2 > obj.member1)
- obj.member2 = obj.member1; // CHECK-FIXES: obj.member2 = std::min(obj.member2, obj.member1);
+ obj.member2 = obj.member1;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `>` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>` [readability-use-std-min-max]
+ // CHECK-FIXES: obj.member1 = std::max(obj.member2, obj.member1);
if (obj.member2 > obj.member1)
- obj.member1 = obj.member2; // CHECK-FIXES: obj.member1 = std::max(obj.member2, obj.member1);
+ obj.member1 = obj.member2;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ // CHECK-FIXES: obj.member1 = std::max(obj.member1, value4);
if (obj.member1 < value4)
- obj.member1 = value4; // CHECK-FIXES: obj.member1 = std::max(obj.member1, value4);
+ obj.member1 = value4;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
+ // CHECK-FIXES: value3 = std::min(obj.member1 + value2, value3);
if (obj.member1 + value2 < value3)
- value3 = obj.member1 + value2; // CHECK-FIXES: value3 = std::min(obj.member1 + value2, value3);
+ value3 = obj.member1 + value2;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `<=` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<=` [readability-use-std-min-max]
+ // CHECK-FIXES: obj.member2 = std::min(value1, obj.member2);
if (value1 <= obj.member2)
- obj.member2 = value1; // CHECK-FIXES: obj.member2 = std::min(value1, obj.member2);
+ obj.member2 = value1;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `<=` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<=` [readability-use-std-min-max]
+ // CHECK-FIXES: value1 = std::max(value1, obj.member2);
if (value1 <= obj.member2)
- value1 = obj.member2; // CHECK-FIXES: value1 = std::max(value1, obj.member2);
+ value1 = obj.member2;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::max` instead of `>=` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>=` [readability-use-std-min-max]
+ // CHECK-FIXES: value1 = std::max(obj.member2, value1);
if (obj.member2 >= value1)
- value1 = obj.member2; // CHECK-FIXES: value1 = std::max(obj.member2, value1);
+ value1 = obj.member2;
- // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: use `std::min` instead of `>=` [readability-use-std-min-max]
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>=` [readability-use-std-min-max]
+ // CHECK-FIXES: obj.member2 = std::min(obj.member2, value1);
if (obj.member2 >= value1)
- obj.member2 = value1; // CHECK-FIXES: obj.member2 = std::min(obj.member2, value1);
+ obj.member2 = value1;
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
+ // CHECK-FIXES: value3 = std::min(MY_MACRO_MIN(value1, value2), value3);
+ if (MY_MACRO_MIN(value1, value2) < value3)
+ value3 = MY_MACRO_MIN(value1, value2);
+
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
+ // CHECK-FIXES: value2 = std::min(value1, value2);
+ if (value1 < value2){
+ value2 = value1;
+ }
+
}
\ No newline at end of file
>From 5e31665d0c449ae09d21b409bbf8b1e035f553b7 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 19 Jan 2024 13:06:27 +0530
Subject: [PATCH 21/31] Added suggested changes
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/UseStdMinMaxCheck.cpp | 136 +++++++++---------
clang-tools-extra/docs/ReleaseNotes.rst | 3 +-
.../checkers/readability/use-std-min-max.cpp | 30 +++-
3 files changed, 96 insertions(+), 73 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 1b0adc2ac6876a1..88bd2e1a941b89c 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -21,28 +21,27 @@ UseStdMinMaxCheck::UseStdMinMaxCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
utils::IncludeSorter::IS_LLVM),
- areDiagsSelfContained()),
- AlgorithmHeader(Options.get("AlgorithmHeader", "<algorithm>")) {}
+ areDiagsSelfContained()) {}
void UseStdMinMaxCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
+ Options.store(Opts, "AlgorithmHeader", Options.get("AlgorithmHeader", "<algorithm>"));
}
void UseStdMinMaxCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
ifStmt(
- has(binaryOperator(
- anyOf(hasOperatorName("<"), hasOperatorName(">"),
- hasOperatorName("<="), hasOperatorName(">=")),
- hasLHS(expr().bind("lhsVar1")), hasRHS(expr().bind("rhsVar1")))),
+ hasCondition(binaryOperator(
+ hasAnyOperatorName("<",">","<=",">="),
+ hasLHS(expr().bind("CondLhs")), hasRHS(expr().bind("CondRhs")))),
hasThen(
anyOf(stmt(binaryOperator(hasOperatorName("="),
- hasLHS(expr().bind("lhsVar2")),
- hasRHS(expr().bind("rhsVar2")))),
+ hasLHS(expr().bind("AssignLhs")),
+ hasRHS(expr().bind("AssignRhs")))),
compoundStmt(has(binaryOperator(
- hasOperatorName("="), hasLHS(expr().bind("lhsVar2")),
- hasRHS(expr().bind("rhsVar2"))))))))
- .bind("ifStmt"),
+ hasOperatorName("="), hasLHS(expr().bind("AssignLhs")),
+ hasRHS(expr().bind("AssignRhs"))))).bind("compound"))))
+ .bind("if"),
this);
}
@@ -53,79 +52,78 @@ void UseStdMinMaxCheck::registerPPCallbacks(const SourceManager &SM,
}
void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
- const auto *lhsVar1 = Result.Nodes.getNodeAs<Expr>("lhsVar1");
- const auto *rhsVar1 = Result.Nodes.getNodeAs<Expr>("rhsVar1");
- const auto *lhsVar2 = Result.Nodes.getNodeAs<Expr>("lhsVar2");
- const auto *rhsVar2 = Result.Nodes.getNodeAs<Expr>("rhsVar2");
- const auto *ifStmt = Result.Nodes.getNodeAs<IfStmt>("ifStmt");
+ const auto *CondLhs = Result.Nodes.getNodeAs<Expr>("CondLhs");
+ const auto *CondRhs = Result.Nodes.getNodeAs<Expr>("CondRhs");
+ const auto *AssignLhs = Result.Nodes.getNodeAs<Expr>("AssignLhs");
+ const auto *AssignRhs = Result.Nodes.getNodeAs<Expr>("AssignRhs");
+ const auto *If = Result.Nodes.getNodeAs<IfStmt>("if");
+ const auto *Compound = Result.Nodes.getNodeAs<CompoundStmt>("compound");
auto &Context = *Result.Context;
const SourceManager &Source = Context.getSourceManager();
- if (!lhsVar1 || !rhsVar1 || !lhsVar2 || !rhsVar2 || !ifStmt)
+ const auto *BinaryOp = dyn_cast<BinaryOperator>(If->getCond());
+ if (!BinaryOp || If->hasElseStorage())
return;
+
+ if(Compound){
+ int count = 0;
+ clang::Stmt::const_child_iterator I = Compound->child_begin();
+ clang::Stmt::const_child_iterator E = Compound->child_end();
+ for(; I != E; ++I){count++;}
+ if(count>1)
+ return;
- const auto *binaryOp = dyn_cast<BinaryOperator>(ifStmt->getCond());
- if (!binaryOp)
- return;
+ }
- SourceLocation ifLocation = ifStmt->getIfLoc();
- SourceLocation thenLocation = ifStmt->getEndLoc();
+ SourceLocation IfLocation = If->getIfLoc();
+ SourceLocation ThenLocation = If->getEndLoc();
- auto lhsVar1Str =
- Lexer::getSourceText(Source.getExpansionRange(lhsVar1->getSourceRange()),
- Context.getSourceManager(), Context.getLangOpts());
+ if(IfLocation.isMacroID() || ThenLocation.isMacroID())
+ return;
- auto lhsVar2Str =
- Lexer::getSourceText(Source.getExpansionRange(lhsVar2->getSourceRange()),
+ const auto CondLhsStr =
+ Lexer::getSourceText(Source.getExpansionRange(CondLhs->getSourceRange()),
Context.getSourceManager(), Context.getLangOpts());
- auto rhsVar1Str =
- Lexer::getSourceText(Source.getExpansionRange(rhsVar1->getSourceRange()),
+ const auto AssignLhsStr =
+ Lexer::getSourceText(Source.getExpansionRange(AssignLhs->getSourceRange()),
Context.getSourceManager(), Context.getLangOpts());
- auto replacementMax = lhsVar2Str.str() + " = std::max(" + lhsVar1Str.str() +
- ", " + rhsVar1Str.str() + ");";
- auto replacementMin = lhsVar2Str.str() + " = std::min(" + lhsVar1Str.str() +
- ", " + rhsVar1Str.str() + ");";
- auto *operatorStr = binaryOp->getOpcodeStr().data();
-
- if (binaryOp->getOpcode() == BO_LT || binaryOp->getOpcode() == BO_LE) {
- if (tidy::utils::areStatementsIdentical(lhsVar1, lhsVar2, Context) &&
- tidy::utils::areStatementsIdentical(rhsVar1, rhsVar2, Context)) {
+ const auto CondRhsStr =
+ Lexer::getSourceText(Source.getExpansionRange(CondRhs->getSourceRange()),
+ Context.getSourceManager(), Context.getLangOpts());
- diag(ifStmt->getIfLoc(), "use `std::max` instead of `%0`")
- << operatorStr
- << FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMax))
+ auto CreateMaxReplacement = [&]() {
+ return AssignLhsStr.str() + " = std::max(" + CondLhsStr.str() +
+ ", " + CondRhsStr.str() + ");";
+ };
+
+ auto CreateMinReplacement = [&]() {
+ return AssignLhsStr.str() + " = std::min(" + CondLhsStr.str() +
+ ", " + CondRhsStr.str() + ");";
+ };
+ const auto OperatorStr = BinaryOp->getOpcodeStr();
+ if(((BinaryOp->getOpcode() == BO_LT || BinaryOp->getOpcode() == BO_LE) && (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+ tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context))) || ((BinaryOp->getOpcode() == BO_GT || BinaryOp->getOpcode() == BO_GE) && (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+ tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))){
+ diag(IfLocation, "use `std::min` instead of `%0`")
+ << OperatorStr
+ << FixItHint::CreateReplacement(SourceRange(IfLocation, ThenLocation),
+ std::move(CreateMinReplacement()))
<< IncludeInserter.createIncludeInsertion(
- Source.getFileID(ifStmt->getBeginLoc()), AlgorithmHeader);
- } else if (tidy::utils::areStatementsIdentical(lhsVar1, rhsVar2, Context) &&
- tidy::utils::areStatementsIdentical(rhsVar1, lhsVar2, Context)) {
- diag(ifStmt->getIfLoc(), "use `std::min` instead of `%0`")
- << operatorStr
- << FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMin))
- << IncludeInserter.createIncludeInsertion(
- Source.getFileID(ifStmt->getBeginLoc()), AlgorithmHeader);
- }
- } else if (binaryOp->getOpcode() == BO_GT || binaryOp->getOpcode() == BO_GE) {
- if (tidy::utils::areStatementsIdentical(lhsVar1, lhsVar2, Context) &&
- tidy::utils::areStatementsIdentical(rhsVar1, rhsVar2, Context)) {
- diag(ifStmt->getIfLoc(), "use `std::min` instead of `%0`")
- << operatorStr
- << FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMin))
- << IncludeInserter.createIncludeInsertion(
- Source.getFileID(ifStmt->getBeginLoc()), AlgorithmHeader);
- } else if (tidy::utils::areStatementsIdentical(lhsVar1, rhsVar2, Context) &&
- tidy::utils::areStatementsIdentical(rhsVar1, lhsVar2, Context)) {
- diag(ifStmt->getIfLoc(), "use `std::max` instead of `%0`")
- << operatorStr
- << FixItHint::CreateReplacement(SourceRange(ifLocation, thenLocation),
- std::move(replacementMax))
+ Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
+
+ }
+ else if(((BinaryOp->getOpcode() == BO_LT || BinaryOp->getOpcode() == BO_LE) && (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+ tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context))) || ((BinaryOp->getOpcode() == BO_GT || BinaryOp->getOpcode() == BO_GE) && (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+ tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))){
+ diag(IfLocation, "use `std::max` instead of `%0`")
+ << OperatorStr
+ << FixItHint::CreateReplacement(SourceRange(IfLocation, ThenLocation),
+ std::move(CreateMaxReplacement()))
<< IncludeInserter.createIncludeInsertion(
- Source.getFileID(ifStmt->getBeginLoc()), AlgorithmHeader);
- }
+ Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
+
}
}
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 9f96001514ac30e..3592411084e6a4b 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -228,8 +228,7 @@ New checks
<clang-tidy/checks/readability/use-std-min-max>` check.
Replaces certain conditional statements with equivalent ``std::min`` or
- ``std::max`` expressions, improving readability and promoting the use of
- standard library functions.
+ ``std::max`` expressions.
- New :doc:`readability-avoid-nested-conditional-operator
<clang-tidy/checks/readability/avoid-nested-conditional-operator>` check.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
index 4a43d8f3926d4f5..03971fc4c56cd16 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
@@ -10,6 +10,11 @@ constexpr int myConstexprMax(int a, int b) {
return a > b ? a : b;
}
+#define MY_IF_MACRO(condition, statement) \
+ if (condition) { \
+ statement \
+ }
+
class MyClass {
public:
int member1;
@@ -135,8 +140,7 @@ void foo() {
if (obj.member2 >= value1)
obj.member2 = value1;
- // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: value3 = std::min(MY_MACRO_MIN(value1, value2), value3);
+ // No suggestion needed here
if (MY_MACRO_MIN(value1, value2) < value3)
value3 = MY_MACRO_MIN(value1, value2);
@@ -146,4 +150,26 @@ void foo() {
value2 = value1;
}
+ // No suggestion needed here
+ if(value1 < value2)
+ value2 = value1;
+ else
+ value2 = value3;
+
+ // No suggestion needed here
+ if(value1<value2){
+ value2 = value1;
+ }
+ else{
+ value2 = value3;
+ }
+
+ // No suggestion needed here
+ if(value1<value2){
+ value2 = value1;
+ int res = value1 + value2;
+ }
+
+ // No suggestion needed here
+ MY_IF_MACRO(value1 < value2, value1 = value2;)
}
\ No newline at end of file
>From a2cfcdcdcc14a95f89aa40378487a2812e6b04a8 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Fri, 19 Jan 2024 13:07:48 +0530
Subject: [PATCH 22/31] Formatted the code
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/UseStdMinMaxCheck.cpp | 103 ++++++++++--------
1 file changed, 58 insertions(+), 45 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 88bd2e1a941b89c..4f684f5bcc16f61 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -25,22 +25,24 @@ UseStdMinMaxCheck::UseStdMinMaxCheck(StringRef Name, ClangTidyContext *Context)
void UseStdMinMaxCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
- Options.store(Opts, "AlgorithmHeader", Options.get("AlgorithmHeader", "<algorithm>"));
+ Options.store(Opts, "AlgorithmHeader",
+ Options.get("AlgorithmHeader", "<algorithm>"));
}
void UseStdMinMaxCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
ifStmt(
- hasCondition(binaryOperator(
- hasAnyOperatorName("<",">","<=",">="),
- hasLHS(expr().bind("CondLhs")), hasRHS(expr().bind("CondRhs")))),
- hasThen(
- anyOf(stmt(binaryOperator(hasOperatorName("="),
- hasLHS(expr().bind("AssignLhs")),
- hasRHS(expr().bind("AssignRhs")))),
- compoundStmt(has(binaryOperator(
- hasOperatorName("="), hasLHS(expr().bind("AssignLhs")),
- hasRHS(expr().bind("AssignRhs"))))).bind("compound"))))
+ hasCondition(binaryOperator(hasAnyOperatorName("<", ">", "<=", ">="),
+ hasLHS(expr().bind("CondLhs")),
+ hasRHS(expr().bind("CondRhs")))),
+ hasThen(anyOf(stmt(binaryOperator(hasOperatorName("="),
+ hasLHS(expr().bind("AssignLhs")),
+ hasRHS(expr().bind("AssignRhs")))),
+ compoundStmt(has(binaryOperator(
+ hasOperatorName("="),
+ hasLHS(expr().bind("AssignLhs")),
+ hasRHS(expr().bind("AssignRhs")))))
+ .bind("compound"))))
.bind("if"),
this);
}
@@ -64,66 +66,77 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
const auto *BinaryOp = dyn_cast<BinaryOperator>(If->getCond());
if (!BinaryOp || If->hasElseStorage())
return;
-
- if(Compound){
+
+ if (Compound) {
int count = 0;
clang::Stmt::const_child_iterator I = Compound->child_begin();
clang::Stmt::const_child_iterator E = Compound->child_end();
- for(; I != E; ++I){count++;}
- if(count>1)
+ for (; I != E; ++I) {
+ count++;
+ }
+ if (count > 1)
return;
-
}
SourceLocation IfLocation = If->getIfLoc();
SourceLocation ThenLocation = If->getEndLoc();
- if(IfLocation.isMacroID() || ThenLocation.isMacroID())
+ if (IfLocation.isMacroID() || ThenLocation.isMacroID())
return;
const auto CondLhsStr =
Lexer::getSourceText(Source.getExpansionRange(CondLhs->getSourceRange()),
Context.getSourceManager(), Context.getLangOpts());
- const auto AssignLhsStr =
- Lexer::getSourceText(Source.getExpansionRange(AssignLhs->getSourceRange()),
- Context.getSourceManager(), Context.getLangOpts());
+ const auto AssignLhsStr = Lexer::getSourceText(
+ Source.getExpansionRange(AssignLhs->getSourceRange()),
+ Context.getSourceManager(), Context.getLangOpts());
const auto CondRhsStr =
Lexer::getSourceText(Source.getExpansionRange(CondRhs->getSourceRange()),
Context.getSourceManager(), Context.getLangOpts());
auto CreateMaxReplacement = [&]() {
- return AssignLhsStr.str() + " = std::max(" + CondLhsStr.str() +
- ", " + CondRhsStr.str() + ");";
+ return AssignLhsStr.str() + " = std::max(" + CondLhsStr.str() + ", " +
+ CondRhsStr.str() + ");";
};
auto CreateMinReplacement = [&]() {
- return AssignLhsStr.str() + " = std::min(" + CondLhsStr.str() +
- ", " + CondRhsStr.str() + ");";
+ return AssignLhsStr.str() + " = std::min(" + CondLhsStr.str() + ", " +
+ CondRhsStr.str() + ");";
};
const auto OperatorStr = BinaryOp->getOpcodeStr();
- if(((BinaryOp->getOpcode() == BO_LT || BinaryOp->getOpcode() == BO_LE) && (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
- tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context))) || ((BinaryOp->getOpcode() == BO_GT || BinaryOp->getOpcode() == BO_GE) && (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
- tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))){
- diag(IfLocation, "use `std::min` instead of `%0`")
- << OperatorStr
- << FixItHint::CreateReplacement(SourceRange(IfLocation, ThenLocation),
- std::move(CreateMinReplacement()))
- << IncludeInserter.createIncludeInsertion(
- Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
-
- }
- else if(((BinaryOp->getOpcode() == BO_LT || BinaryOp->getOpcode() == BO_LE) && (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
- tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context))) || ((BinaryOp->getOpcode() == BO_GT || BinaryOp->getOpcode() == BO_GE) && (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
- tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context)))){
- diag(IfLocation, "use `std::max` instead of `%0`")
- << OperatorStr
- << FixItHint::CreateReplacement(SourceRange(IfLocation, ThenLocation),
- std::move(CreateMaxReplacement()))
- << IncludeInserter.createIncludeInsertion(
- Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
-
+ if (((BinaryOp->getOpcode() == BO_LT || BinaryOp->getOpcode() == BO_LE) &&
+ (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
+ tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context))) ||
+ ((BinaryOp->getOpcode() == BO_GT || BinaryOp->getOpcode() == BO_GE) &&
+ (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
+ tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))) {
+ diag(IfLocation, "use `std::min` instead of `%0`")
+ << OperatorStr
+ << FixItHint::CreateReplacement(SourceRange(IfLocation, ThenLocation),
+ std::move(CreateMinReplacement()))
+ << IncludeInserter.createIncludeInsertion(
+ Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
+
+ } else if (((BinaryOp->getOpcode() == BO_LT ||
+ BinaryOp->getOpcode() == BO_LE) &&
+ (tidy::utils::areStatementsIdentical(CondLhs, AssignLhs,
+ Context) &&
+ tidy::utils::areStatementsIdentical(CondRhs, AssignRhs,
+ Context))) ||
+ ((BinaryOp->getOpcode() == BO_GT ||
+ BinaryOp->getOpcode() == BO_GE) &&
+ (tidy::utils::areStatementsIdentical(CondLhs, AssignRhs,
+ Context) &&
+ tidy::utils::areStatementsIdentical(CondRhs, AssignLhs,
+ Context)))) {
+ diag(IfLocation, "use `std::max` instead of `%0`")
+ << OperatorStr
+ << FixItHint::CreateReplacement(SourceRange(IfLocation, ThenLocation),
+ std::move(CreateMaxReplacement()))
+ << IncludeInserter.createIncludeInsertion(
+ Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
}
}
>From f5a0f12bbf59e141b4a0832a73d76a9be402ff14 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Sat, 20 Jan 2024 01:55:16 +0530
Subject: [PATCH 23/31] Converted to Lambdas,placed at sorted location
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/ReadabilityTidyModule.cpp | 4 +-
.../readability/UseStdMinMaxCheck.cpp | 56 +++++++++----------
clang-tools-extra/docs/ReleaseNotes.rst | 12 ++--
.../docs/clang-tidy/checks/list.rst | 2 +-
4 files changed, 35 insertions(+), 39 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index 89999e2794d2bf6..1cc520b0c005a6e 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -64,8 +64,6 @@ namespace readability {
class ReadabilityModule : public ClangTidyModule {
public:
void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
- CheckFactories.registerCheck<UseStdMinMaxCheck>(
- "readability-use-std-min-max");
CheckFactories.registerCheck<AvoidConstParamsInDecls>(
"readability-avoid-const-params-in-decls");
CheckFactories.registerCheck<AvoidNestedConditionalOperatorCheck>(
@@ -160,6 +158,8 @@ class ReadabilityModule : public ClangTidyModule {
"readability-uppercase-literal-suffix");
CheckFactories.registerCheck<UseAnyOfAllOfCheck>(
"readability-use-anyofallof");
+ CheckFactories.registerCheck<UseStdMinMaxCheck>(
+ "readability-use-std-min-max");
}
};
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 4f684f5bcc16f61..44173515842e42c 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -60,7 +60,8 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
const auto *AssignRhs = Result.Nodes.getNodeAs<Expr>("AssignRhs");
const auto *If = Result.Nodes.getNodeAs<IfStmt>("if");
const auto *Compound = Result.Nodes.getNodeAs<CompoundStmt>("compound");
- auto &Context = *Result.Context;
+ const auto &Context = *Result.Context;
+ const auto &LO = Context.getLangOpts();
const SourceManager &Source = Context.getSourceManager();
const auto *BinaryOp = dyn_cast<BinaryOperator>(If->getCond());
@@ -68,42 +69,37 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
return;
if (Compound) {
- int count = 0;
- clang::Stmt::const_child_iterator I = Compound->child_begin();
- clang::Stmt::const_child_iterator E = Compound->child_end();
- for (; I != E; ++I) {
- count++;
- }
- if (count > 1)
+ if (Compound->size() > 1)
return;
}
- SourceLocation IfLocation = If->getIfLoc();
- SourceLocation ThenLocation = If->getEndLoc();
+ const SourceLocation IfLocation = If->getIfLoc();
+ const SourceLocation ThenLocation = If->getEndLoc();
if (IfLocation.isMacroID() || ThenLocation.isMacroID())
return;
- const auto CondLhsStr =
- Lexer::getSourceText(Source.getExpansionRange(CondLhs->getSourceRange()),
- Context.getSourceManager(), Context.getLangOpts());
-
- const auto AssignLhsStr = Lexer::getSourceText(
- Source.getExpansionRange(AssignLhs->getSourceRange()),
- Context.getSourceManager(), Context.getLangOpts());
-
- const auto CondRhsStr =
- Lexer::getSourceText(Source.getExpansionRange(CondRhs->getSourceRange()),
- Context.getSourceManager(), Context.getLangOpts());
-
- auto CreateMaxReplacement = [&]() {
- return AssignLhsStr.str() + " = std::max(" + CondLhsStr.str() + ", " +
- CondRhsStr.str() + ");";
+ const auto CreateString = [&](int index) -> llvm::StringRef {
+ switch (index) {
+ case 1:
+ return Lexer::getSourceText(
+ Source.getExpansionRange(CondLhs->getSourceRange()), Source, LO);
+ case 2:
+ return Lexer::getSourceText(
+ Source.getExpansionRange(CondRhs->getSourceRange()), Source, LO);
+ case 3:
+ return Lexer::getSourceText(
+ Source.getExpansionRange(AssignLhs->getSourceRange()), Source, LO);
+ default:
+ return "Invalid index";
+ }
};
- auto CreateMinReplacement = [&]() {
- return AssignLhsStr.str() + " = std::min(" + CondLhsStr.str() + ", " +
- CondRhsStr.str() + ");";
+ const auto CreateReplacement = [&](bool useMax) {
+ std::string functionName = useMax ? "std::max" : "std::min";
+ return CreateString(/* AssignLhs */ 3).str() + " = " + functionName + "(" +
+ CreateString(/* CondLhs */ 1).str() + ", " +
+ CreateString(/* CondRhs */ 2).str() + ");";
};
const auto OperatorStr = BinaryOp->getOpcodeStr();
if (((BinaryOp->getOpcode() == BO_LT || BinaryOp->getOpcode() == BO_LE) &&
@@ -115,7 +111,7 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
diag(IfLocation, "use `std::min` instead of `%0`")
<< OperatorStr
<< FixItHint::CreateReplacement(SourceRange(IfLocation, ThenLocation),
- std::move(CreateMinReplacement()))
+ CreateReplacement(/*useMax = false*/ 0))
<< IncludeInserter.createIncludeInsertion(
Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
@@ -134,7 +130,7 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
diag(IfLocation, "use `std::max` instead of `%0`")
<< OperatorStr
<< FixItHint::CreateReplacement(SourceRange(IfLocation, ThenLocation),
- std::move(CreateMaxReplacement()))
+ CreateReplacement(/*useMax = true*/ 1))
<< IncludeInserter.createIncludeInsertion(
Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
}
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 3592411084e6a4b..e258f4978c45f98 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -224,12 +224,6 @@ New checks
Recommends the smallest possible underlying type for an ``enum`` or ``enum``
class based on the range of its enumerators.
-- New :doc:`readability-use-std-min-max
- <clang-tidy/checks/readability/use-std-min-max>` check.
-
- Replaces certain conditional statements with equivalent ``std::min`` or
- ``std::max`` expressions.
-
- New :doc:`readability-avoid-nested-conditional-operator
<clang-tidy/checks/readability/avoid-nested-conditional-operator>` check.
@@ -247,6 +241,12 @@ New checks
Detects C++ code where a reference variable is used to extend the lifetime
of a temporary object that has just been constructed.
+- New :doc:`readability-use-std-min-max
+ <clang-tidy/checks/readability/use-std-min-max>` check.
+
+ Replaces certain conditional statements with equivalent ``std::min`` or
+ ``std::max`` expressions.
+
New check aliases
^^^^^^^^^^^^^^^^^
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 3bd414f0eed897b..68360eb67ac55a7 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -336,7 +336,6 @@ Clang-Tidy Checks
:doc:`portability-restrict-system-includes <portability/restrict-system-includes>`, "Yes"
:doc:`portability-simd-intrinsics <portability/simd-intrinsics>`,
:doc:`portability-std-allocator-const <portability/std-allocator-const>`,
- :doc:`readability-use-std-min-max <readability/use-std-min-max>`, "Yes"
:doc:`readability-avoid-const-params-in-decls <readability/avoid-const-params-in-decls>`, "Yes"
:doc:`readability-avoid-nested-conditional-operator <readability/avoid-nested-conditional-operator>`,
:doc:`readability-avoid-return-with-void-value <readability/avoid-return-with-void-value>`,
@@ -384,6 +383,7 @@ Clang-Tidy Checks
:doc:`readability-uniqueptr-delete-release <readability/uniqueptr-delete-release>`, "Yes"
:doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes"
:doc:`readability-use-anyofallof <readability/use-anyofallof>`,
+ :doc:`readability-use-std-min-max <readability/use-std-min-max>`, "Yes"
:doc:`zircon-temporary-objects <zircon/temporary-objects>`,
>From e239576831f3592fd35ed4628da1809026b621f8 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Sat, 20 Jan 2024 22:54:37 +0530
Subject: [PATCH 24/31] Single Lambda
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/UseStdMinMaxCheck.cpp | 32 +++++++------------
.../checks/readability/use-std-min-max.rst | 4 +--
2 files changed, 13 insertions(+), 23 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 44173515842e42c..9d740db05001e8c 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -79,27 +79,17 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
if (IfLocation.isMacroID() || ThenLocation.isMacroID())
return;
- const auto CreateString = [&](int index) -> llvm::StringRef {
- switch (index) {
- case 1:
- return Lexer::getSourceText(
- Source.getExpansionRange(CondLhs->getSourceRange()), Source, LO);
- case 2:
- return Lexer::getSourceText(
- Source.getExpansionRange(CondRhs->getSourceRange()), Source, LO);
- case 3:
- return Lexer::getSourceText(
- Source.getExpansionRange(AssignLhs->getSourceRange()), Source, LO);
- default:
- return "Invalid index";
- }
- };
-
const auto CreateReplacement = [&](bool useMax) {
std::string functionName = useMax ? "std::max" : "std::min";
- return CreateString(/* AssignLhs */ 3).str() + " = " + functionName + "(" +
- CreateString(/* CondLhs */ 1).str() + ", " +
- CreateString(/* CondRhs */ 2).str() + ");";
+ const auto CondLhsStr = Lexer::getSourceText(
+ Source.getExpansionRange(CondLhs->getSourceRange()), Source, LO);
+ const auto CondRhsStr = Lexer::getSourceText(
+ Source.getExpansionRange(CondRhs->getSourceRange()), Source, LO);
+ const auto AssignLhsStr = Lexer::getSourceText(
+ Source.getExpansionRange(AssignLhs->getSourceRange()), Source, LO);
+ return (AssignLhsStr + " = " + functionName + "(" + CondLhsStr + ", " +
+ CondRhsStr + ");")
+ .str();
};
const auto OperatorStr = BinaryOp->getOpcodeStr();
if (((BinaryOp->getOpcode() == BO_LT || BinaryOp->getOpcode() == BO_LE) &&
@@ -111,7 +101,7 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
diag(IfLocation, "use `std::min` instead of `%0`")
<< OperatorStr
<< FixItHint::CreateReplacement(SourceRange(IfLocation, ThenLocation),
- CreateReplacement(/*useMax = false*/ 0))
+ CreateReplacement(/*useMax=*/false))
<< IncludeInserter.createIncludeInsertion(
Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
@@ -130,7 +120,7 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
diag(IfLocation, "use `std::max` instead of `%0`")
<< OperatorStr
<< FixItHint::CreateReplacement(SourceRange(IfLocation, ThenLocation),
- CreateReplacement(/*useMax = true*/ 1))
+ CreateReplacement(/*useMax=*/true))
<< IncludeInserter.createIncludeInsertion(
Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
}
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
index 7e64a05ccd8b89d..2cf6a58552cdedd 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
@@ -3,8 +3,8 @@
readability-use-std-min-max
===========================
-Replaces certain conditionals with ``std::min`` or ``std::max`` for readability,
-promoting use of standard library functions. Note: This may impact
+Replaces certain conditional statements with equivalent ``std::min`` or
+``std::max`` expressions. Note: This may impact
performance in critical code due to potential additional stores compared
to the original if statement.
>From b868d5b5c3c5057eaec066ad6efa86e39aaf63e2 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Sun, 21 Jan 2024 00:20:19 +0530
Subject: [PATCH 25/31] CamelCase,const auto*
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../clang-tidy/readability/UseStdMinMaxCheck.cpp | 10 +++++-----
.../clang-tidy/readability/UseStdMinMaxCheck.h | 4 +---
2 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 9d740db05001e8c..aa8a43631eb6f77 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -79,15 +79,15 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
if (IfLocation.isMacroID() || ThenLocation.isMacroID())
return;
- const auto CreateReplacement = [&](bool useMax) {
- std::string functionName = useMax ? "std::max" : "std::min";
+ const auto CreateReplacement = [&](bool UseMax) {
+ const auto *FunctionName = UseMax ? "std::max" : "std::min";
const auto CondLhsStr = Lexer::getSourceText(
Source.getExpansionRange(CondLhs->getSourceRange()), Source, LO);
const auto CondRhsStr = Lexer::getSourceText(
Source.getExpansionRange(CondRhs->getSourceRange()), Source, LO);
const auto AssignLhsStr = Lexer::getSourceText(
Source.getExpansionRange(AssignLhs->getSourceRange()), Source, LO);
- return (AssignLhsStr + " = " + functionName + "(" + CondLhsStr + ", " +
+ return (AssignLhsStr + " = " + FunctionName + "(" + CondLhsStr + ", " +
CondRhsStr + ");")
.str();
};
@@ -101,7 +101,7 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
diag(IfLocation, "use `std::min` instead of `%0`")
<< OperatorStr
<< FixItHint::CreateReplacement(SourceRange(IfLocation, ThenLocation),
- CreateReplacement(/*useMax=*/false))
+ CreateReplacement(/*UseMax=*/false))
<< IncludeInserter.createIncludeInsertion(
Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
@@ -120,7 +120,7 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
diag(IfLocation, "use `std::max` instead of `%0`")
<< OperatorStr
<< FixItHint::CreateReplacement(SourceRange(IfLocation, ThenLocation),
- CreateReplacement(/*useMax=*/true))
+ CreateReplacement(/*UseMax=*/true))
<< IncludeInserter.createIncludeInsertion(
Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
}
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
index 52b34fdbe2627cc..b4afe356968237e 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
@@ -14,9 +14,7 @@
namespace clang::tidy::readability {
/// Replaces certain conditional statements with equivalent ``std::min`` or
-/// ``std::max`` expressions, improving readability and promoting the use of
-/// standard library functions.
-///
+/// ``std::max`` expressions.
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/readability/UseStdMinMax.html
class UseStdMinMaxCheck : public ClangTidyCheck {
>From 0797e0c0f7a078de137e7e3e719afa9d70c061dd Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Sun, 21 Jan 2024 01:19:46 +0530
Subject: [PATCH 26/31] fixes
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/UseStdMinMaxCheck.cpp | 22 +++++---
.../readability/UseStdMinMaxCheck.h | 1 -
.../checkers/readability/use-std-min-max.cpp | 52 +++++++++----------
3 files changed, 40 insertions(+), 35 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index aa8a43631eb6f77..a870235207fddb7 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -17,6 +17,8 @@ using namespace clang::ast_matchers;
namespace clang::tidy::readability {
+static const llvm::StringRef AlgorithmHeader("<algorithm>");
+
UseStdMinMaxCheck::UseStdMinMaxCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
IncludeInserter(Options.getLocalOrGlobal("IncludeStyle",
@@ -25,8 +27,6 @@ UseStdMinMaxCheck::UseStdMinMaxCheck(StringRef Name, ClangTidyContext *Context)
void UseStdMinMaxCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle());
- Options.store(Opts, "AlgorithmHeader",
- Options.get("AlgorithmHeader", "<algorithm>"));
}
void UseStdMinMaxCheck::registerMatchers(MatchFinder *Finder) {
@@ -87,8 +87,10 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
Source.getExpansionRange(CondRhs->getSourceRange()), Source, LO);
const auto AssignLhsStr = Lexer::getSourceText(
Source.getExpansionRange(AssignLhs->getSourceRange()), Source, LO);
- return (AssignLhsStr + " = " + FunctionName + "(" + CondLhsStr + ", " +
- CondRhsStr + ");")
+ const auto AssignLhsType =
+ AssignLhs->getType().getCanonicalType().getAsString();
+ return (AssignLhsStr + " = " + FunctionName + "<" + AssignLhsType + ">(" +
+ CondLhsStr + ", " + CondRhsStr + ");")
.str();
};
const auto OperatorStr = BinaryOp->getOpcodeStr();
@@ -100,8 +102,10 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))) {
diag(IfLocation, "use `std::min` instead of `%0`")
<< OperatorStr
- << FixItHint::CreateReplacement(SourceRange(IfLocation, ThenLocation),
- CreateReplacement(/*UseMax=*/false))
+ << FixItHint::CreateReplacement(
+ SourceRange(IfLocation, Lexer::getLocForEndOfToken(
+ ThenLocation, 0, Source, LO)),
+ CreateReplacement(/*UseMax=*/false))
<< IncludeInserter.createIncludeInsertion(
Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
@@ -119,8 +123,10 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
Context)))) {
diag(IfLocation, "use `std::max` instead of `%0`")
<< OperatorStr
- << FixItHint::CreateReplacement(SourceRange(IfLocation, ThenLocation),
- CreateReplacement(/*UseMax=*/true))
+ << FixItHint::CreateReplacement(
+ SourceRange(IfLocation, Lexer::getLocForEndOfToken(
+ ThenLocation, 0, Source, LO)),
+ CreateReplacement(/*UseMax=*/true))
<< IncludeInserter.createIncludeInsertion(
Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
}
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
index b4afe356968237e..860e47794a99c1e 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.h
@@ -34,7 +34,6 @@ class UseStdMinMaxCheck : public ClangTidyCheck {
private:
utils::IncludeInserter IncludeInserter;
- StringRef AlgorithmHeader;
};
} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
index 03971fc4c56cd16..6249957e3076c13 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
@@ -27,22 +27,22 @@ void foo() {
MyClass obj;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::max(value1, value2);
+ // CHECK-FIXES: value1 = std::max<int>(value1, value2);
if (value1 < value2)
value1 = value2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: value2 = std::min(value1, value2);
+ // CHECK-FIXES: value2 = std::min<int>(value1, value2);
if (value1 < value2)
value2 = value1;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
- // CHECK-FIXES: value2 = std::min(value2, value1);
+ // CHECK-FIXES: value2 = std::min<int>(value2, value1);
if (value2 > value1)
value2 = value1;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>` [readability-use-std-min-max
- // CHECK-FIXES: value1 = std::max(value2, value1);
+ // CHECK-FIXES: value1 = std::max<int>(value2, value1);
if (value2 > value1)
value1 = value2;
@@ -51,92 +51,92 @@ void foo() {
value1 = value2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::max(value1, value4);
+ // CHECK-FIXES: value1 = std::max<int>(value1, value4);
if(value1<value4)
value1=value4;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: value3 = std::min(value1+value2, value3);
+ // CHECK-FIXES: value3 = std::min<int>(value1+value2, value3);
if(value1+value2<value3)
value3 = value1+value2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::max(value1, myConstexprMin(value2, value3));
+ // CHECK-FIXES: value1 = std::max<int>(value1, myConstexprMin(value2, value3));
if (value1 < myConstexprMin(value2, value3))
value1 = myConstexprMin(value2, value3);
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::min(value1, myConstexprMax(value2, value3));
+ // CHECK-FIXES: value1 = std::min<int>(value1, myConstexprMax(value2, value3));
if (value1 > myConstexprMax(value2, value3))
value1 = myConstexprMax(value2, value3);
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<=` [readability-use-std-min-max]
- // CHECK-FIXES: value2 = std::min(value1, value2);
+ // CHECK-FIXES: value2 = std::min<int>(value1, value2);
if (value1 <= value2)
value2 = value1;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<=` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::max(value1, value2);
+ // CHECK-FIXES: value1 = std::max<int>(value1, value2);
if (value1 <= value2)
value1 = value2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>=` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::max(value2, value1);
+ // CHECK-FIXES: value1 = std::max<int>(value2, value1);
if (value2 >= value1)
value1 = value2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>=` [readability-use-std-min-max]
- // CHECK-FIXES: value2 = std::min(value2, value1);
+ // CHECK-FIXES: value2 = std::min<int>(value2, value1);
if (value2 >= value1)
value2 = value1;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: obj.member1 = std::max(obj.member1, obj.member2);
+ // CHECK-FIXES: obj.member1 = std::max<int>(obj.member1, obj.member2);
if (obj.member1 < obj.member2)
obj.member1 = obj.member2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: obj.member2 = std::min(obj.member1, obj.member2);
+ // CHECK-FIXES: obj.member2 = std::min<int>(obj.member1, obj.member2);
if (obj.member1 < obj.member2)
obj.member2 = obj.member1;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
- // CHECK-FIXES: obj.member2 = std::min(obj.member2, obj.member1);
+ // CHECK-FIXES: obj.member2 = std::min<int>(obj.member2, obj.member1);
if (obj.member2 > obj.member1)
obj.member2 = obj.member1;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>` [readability-use-std-min-max]
- // CHECK-FIXES: obj.member1 = std::max(obj.member2, obj.member1);
+ // CHECK-FIXES: obj.member1 = std::max<int>(obj.member2, obj.member1);
if (obj.member2 > obj.member1)
obj.member1 = obj.member2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: obj.member1 = std::max(obj.member1, value4);
+ // CHECK-FIXES: obj.member1 = std::max<int>(obj.member1, value4);
if (obj.member1 < value4)
obj.member1 = value4;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: value3 = std::min(obj.member1 + value2, value3);
+ // CHECK-FIXES: value3 = std::min<int>(obj.member1 + value2, value3);
if (obj.member1 + value2 < value3)
value3 = obj.member1 + value2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<=` [readability-use-std-min-max]
- // CHECK-FIXES: obj.member2 = std::min(value1, obj.member2);
+ // CHECK-FIXES: obj.member2 = std::min<int>(value1, obj.member2);
if (value1 <= obj.member2)
obj.member2 = value1;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<=` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::max(value1, obj.member2);
+ // CHECK-FIXES: value1 = std::max<int>(value1, obj.member2);
if (value1 <= obj.member2)
value1 = obj.member2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>=` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::max(obj.member2, value1);
+ // CHECK-FIXES: value1 = std::max<int>(obj.member2, value1);
if (obj.member2 >= value1)
value1 = obj.member2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>=` [readability-use-std-min-max]
- // CHECK-FIXES: obj.member2 = std::min(obj.member2, value1);
+ // CHECK-FIXES: obj.member2 = std::min<int>(obj.member2, value1);
if (obj.member2 >= value1)
obj.member2 = value1;
@@ -144,10 +144,10 @@ void foo() {
if (MY_MACRO_MIN(value1, value2) < value3)
value3 = MY_MACRO_MIN(value1, value2);
- // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: value2 = std::min(value1, value2);
- if (value1 < value2){
- value2 = value1;
+ // CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ // CHECK-FIXES: value4 = std::max<short>(value4, value2);
+ if (value4 < value2){
+ value4 = value2;
}
// No suggestion needed here
>From c6028b0ddd8ce1ace6e6c3f14244e889250a8e34 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Sun, 21 Jan 2024 21:26:25 +0530
Subject: [PATCH 27/31] few nits
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/UseStdMinMaxCheck.cpp | 29 +++++++-------
.../checkers/readability/use-std-min-max.cpp | 40 +++++++++----------
2 files changed, 34 insertions(+), 35 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index a870235207fddb7..6e39ebeda2b2c69 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -11,7 +11,6 @@
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Preprocessor.h"
-#include <optional>
using namespace clang::ast_matchers;
@@ -38,11 +37,11 @@ void UseStdMinMaxCheck::registerMatchers(MatchFinder *Finder) {
hasThen(anyOf(stmt(binaryOperator(hasOperatorName("="),
hasLHS(expr().bind("AssignLhs")),
hasRHS(expr().bind("AssignRhs")))),
- compoundStmt(has(binaryOperator(
+ compoundStmt(statementCountIs(1),
+ has(binaryOperator(
hasOperatorName("="),
hasLHS(expr().bind("AssignLhs")),
- hasRHS(expr().bind("AssignRhs")))))
- .bind("compound"))))
+ hasRHS(expr().bind("AssignRhs"))))))))
.bind("if"),
this);
}
@@ -59,7 +58,6 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
const auto *AssignLhs = Result.Nodes.getNodeAs<Expr>("AssignLhs");
const auto *AssignRhs = Result.Nodes.getNodeAs<Expr>("AssignRhs");
const auto *If = Result.Nodes.getNodeAs<IfStmt>("if");
- const auto *Compound = Result.Nodes.getNodeAs<CompoundStmt>("compound");
const auto &Context = *Result.Context;
const auto &LO = Context.getLangOpts();
const SourceManager &Source = Context.getSourceManager();
@@ -68,11 +66,6 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
if (!BinaryOp || If->hasElseStorage())
return;
- if (Compound) {
- if (Compound->size() > 1)
- return;
- }
-
const SourceLocation IfLocation = If->getIfLoc();
const SourceLocation ThenLocation = If->getEndLoc();
@@ -87,11 +80,17 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
Source.getExpansionRange(CondRhs->getSourceRange()), Source, LO);
const auto AssignLhsStr = Lexer::getSourceText(
Source.getExpansionRange(AssignLhs->getSourceRange()), Source, LO);
- const auto AssignLhsType =
- AssignLhs->getType().getCanonicalType().getAsString();
- return (AssignLhsStr + " = " + FunctionName + "<" + AssignLhsType + ">(" +
- CondLhsStr + ", " + CondRhsStr + ");")
- .str();
+ if (CondLhs->getType() != CondRhs->getType()) {
+ return (AssignLhsStr + " = " + FunctionName + "<" +
+ AssignLhs->getType().getAsString() + ">(" + CondLhsStr + ", " +
+ CondRhsStr + ");")
+ .str();
+ } else {
+ return (AssignLhsStr + " = " + FunctionName + "(" + CondLhsStr + ", " +
+ CondRhsStr + ");")
+ .str();
+ }
+
};
const auto OperatorStr = BinaryOp->getOpcodeStr();
if (((BinaryOp->getOpcode() == BO_LT || BinaryOp->getOpcode() == BO_LE) &&
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
index 6249957e3076c13..cdb169fd42c6fb8 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
@@ -27,22 +27,22 @@ void foo() {
MyClass obj;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::max<int>(value1, value2);
+ // CHECK-FIXES: value1 = std::max(value1, value2);
if (value1 < value2)
value1 = value2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: value2 = std::min<int>(value1, value2);
+ // CHECK-FIXES: value2 = std::min(value1, value2);
if (value1 < value2)
value2 = value1;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
- // CHECK-FIXES: value2 = std::min<int>(value2, value1);
+ // CHECK-FIXES: value2 = std::min(value2, value1);
if (value2 > value1)
value2 = value1;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>` [readability-use-std-min-max
- // CHECK-FIXES: value1 = std::max<int>(value2, value1);
+ // CHECK-FIXES: value1 = std::max(value2, value1);
if (value2 > value1)
value1 = value2;
@@ -56,57 +56,57 @@ void foo() {
value1=value4;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: value3 = std::min<int>(value1+value2, value3);
+ // CHECK-FIXES: value3 = std::min(value1+value2, value3);
if(value1+value2<value3)
value3 = value1+value2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::max<int>(value1, myConstexprMin(value2, value3));
+ // CHECK-FIXES: value1 = std::max(value1, myConstexprMin(value2, value3));
if (value1 < myConstexprMin(value2, value3))
value1 = myConstexprMin(value2, value3);
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::min<int>(value1, myConstexprMax(value2, value3));
+ // CHECK-FIXES: value1 = std::min(value1, myConstexprMax(value2, value3));
if (value1 > myConstexprMax(value2, value3))
value1 = myConstexprMax(value2, value3);
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<=` [readability-use-std-min-max]
- // CHECK-FIXES: value2 = std::min<int>(value1, value2);
+ // CHECK-FIXES: value2 = std::min(value1, value2);
if (value1 <= value2)
value2 = value1;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<=` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::max<int>(value1, value2);
+ // CHECK-FIXES: value1 = std::max(value1, value2);
if (value1 <= value2)
value1 = value2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>=` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::max<int>(value2, value1);
+ // CHECK-FIXES: value1 = std::max(value2, value1);
if (value2 >= value1)
value1 = value2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>=` [readability-use-std-min-max]
- // CHECK-FIXES: value2 = std::min<int>(value2, value1);
+ // CHECK-FIXES: value2 = std::min(value2, value1);
if (value2 >= value1)
value2 = value1;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: obj.member1 = std::max<int>(obj.member1, obj.member2);
+ // CHECK-FIXES: obj.member1 = std::max(obj.member1, obj.member2);
if (obj.member1 < obj.member2)
obj.member1 = obj.member2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: obj.member2 = std::min<int>(obj.member1, obj.member2);
+ // CHECK-FIXES: obj.member2 = std::min(obj.member1, obj.member2);
if (obj.member1 < obj.member2)
obj.member2 = obj.member1;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>` [readability-use-std-min-max]
- // CHECK-FIXES: obj.member2 = std::min<int>(obj.member2, obj.member1);
+ // CHECK-FIXES: obj.member2 = std::min(obj.member2, obj.member1);
if (obj.member2 > obj.member1)
obj.member2 = obj.member1;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>` [readability-use-std-min-max]
- // CHECK-FIXES: obj.member1 = std::max<int>(obj.member2, obj.member1);
+ // CHECK-FIXES: obj.member1 = std::max(obj.member2, obj.member1);
if (obj.member2 > obj.member1)
obj.member1 = obj.member2;
@@ -116,27 +116,27 @@ void foo() {
obj.member1 = value4;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<` [readability-use-std-min-max]
- // CHECK-FIXES: value3 = std::min<int>(obj.member1 + value2, value3);
+ // CHECK-FIXES: value3 = std::min(obj.member1 + value2, value3);
if (obj.member1 + value2 < value3)
value3 = obj.member1 + value2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `<=` [readability-use-std-min-max]
- // CHECK-FIXES: obj.member2 = std::min<int>(value1, obj.member2);
+ // CHECK-FIXES: obj.member2 = std::min(value1, obj.member2);
if (value1 <= obj.member2)
obj.member2 = value1;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `<=` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::max<int>(value1, obj.member2);
+ // CHECK-FIXES: value1 = std::max(value1, obj.member2);
if (value1 <= obj.member2)
value1 = obj.member2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::max` instead of `>=` [readability-use-std-min-max]
- // CHECK-FIXES: value1 = std::max<int>(obj.member2, value1);
+ // CHECK-FIXES: value1 = std::max(obj.member2, value1);
if (obj.member2 >= value1)
value1 = obj.member2;
// CHECK-MESSAGES: :[[@LINE+2]]:3: warning: use `std::min` instead of `>=` [readability-use-std-min-max]
- // CHECK-FIXES: obj.member2 = std::min<int>(obj.member2, value1);
+ // CHECK-FIXES: obj.member2 = std::min(obj.member2, value1);
if (obj.member2 >= value1)
obj.member2 = value1;
>From 6acf645970379656373f997a37583cce1ae5e254 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Sun, 21 Jan 2024 21:32:46 +0530
Subject: [PATCH 28/31] formatted the code
Signed-off-by: 11happy <soni5happy at gmail.com>
---
clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 6e39ebeda2b2c69..4cd7898efb82af6 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -90,7 +90,6 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
CondRhsStr + ");")
.str();
}
-
};
const auto OperatorStr = BinaryOp->getOpcodeStr();
if (((BinaryOp->getOpcode() == BO_LT || BinaryOp->getOpcode() == BO_LE) &&
>From 0eb4aca8023104d228427205e762680737d7b412 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Mon, 22 Jan 2024 03:23:27 +0530
Subject: [PATCH 29/31] extra checks
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../clang-tidy/readability/UseStdMinMaxCheck.cpp | 2 +-
.../checkers/readability/use-std-min-max.cpp | 14 ++++++++++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 4cd7898efb82af6..142425f90e23485 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -30,7 +30,7 @@ void UseStdMinMaxCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
void UseStdMinMaxCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
- ifStmt(
+ ifStmt(unless(hasAncestor(ifStmt())),
hasCondition(binaryOperator(hasAnyOperatorName("<", ">", "<=", ">="),
hasLHS(expr().bind("CondLhs")),
hasRHS(expr().bind("CondRhs")))),
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
index cdb169fd42c6fb8..97b9b9924700b54 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
@@ -172,4 +172,18 @@ void foo() {
// No suggestion needed here
MY_IF_MACRO(value1 < value2, value1 = value2;)
+
+ // No suggestion needed here
+ if(value1<value2){
+ value1 = value2;
+ }
+ else if(value1>value2){
+ value2 = value1;
+ }
+
+ // No suggestions needed here
+ if(value1 == value2){
+ if(value1<value3)
+ value1 = value3;
+ }
}
\ No newline at end of file
>From d5b8dc25598b516d81f6ab49c916f2fd41ade6ca Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Mon, 22 Jan 2024 16:13:59 +0530
Subject: [PATCH 30/31] ensure if has no else if
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/UseStdMinMaxCheck.cpp | 12 ++++++++----
.../checkers/readability/use-std-min-max.cpp | 17 ++++++++++++++++-
2 files changed, 24 insertions(+), 5 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 142425f90e23485..1bc09d8563602a6 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -30,7 +30,8 @@ void UseStdMinMaxCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
void UseStdMinMaxCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
- ifStmt(unless(hasAncestor(ifStmt())),
+ ifStmt(
+ stmt().bind("if"),
hasCondition(binaryOperator(hasAnyOperatorName("<", ">", "<=", ">="),
hasLHS(expr().bind("CondLhs")),
hasRHS(expr().bind("CondRhs")))),
@@ -41,8 +42,9 @@ void UseStdMinMaxCheck::registerMatchers(MatchFinder *Finder) {
has(binaryOperator(
hasOperatorName("="),
hasLHS(expr().bind("AssignLhs")),
- hasRHS(expr().bind("AssignRhs"))))))))
- .bind("if"),
+ hasRHS(expr().bind("AssignRhs"))))))),
+ hasParent(stmt(unless(ifStmt(hasElse(
+ equalsBoundNode("if"))))))), // Ensure `if` has no `else if`
this);
}
@@ -63,12 +65,14 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
const SourceManager &Source = Context.getSourceManager();
const auto *BinaryOp = dyn_cast<BinaryOperator>(If->getCond());
- if (!BinaryOp || If->hasElseStorage())
+ // Ignore `if` statements with `else`
+ if (If->hasElseStorage())
return;
const SourceLocation IfLocation = If->getIfLoc();
const SourceLocation ThenLocation = If->getEndLoc();
+ // Ignore Macros
if (IfLocation.isMacroID() || ThenLocation.isMacroID())
return;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
index 97b9b9924700b54..4f36b1dedcbd4c1 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-std-min-max.cpp
@@ -181,9 +181,24 @@ void foo() {
value2 = value1;
}
- // No suggestions needed here
+ // CHECK-MESSAGES: :[[@LINE+3]]:5: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ // CHECK-FIXES: value1 = std::max(value1, value3);
if(value1 == value2){
if(value1<value3)
value1 = value3;
}
+
+ // CHECK-MESSAGES: :[[@LINE+5]]:7: warning: use `std::max` instead of `<` [readability-use-std-min-max]
+ // CHECK-FIXES: value1 = std::max<int>(value1, value4);
+ if(value1 == value2){
+ if(value2 == value3){
+ value3+=1;
+ if(value1<value4){
+ value1 = value4;
+ }
+ }
+ else if(value3>value2){
+ value2 = value3;
+ }
+ }
}
\ No newline at end of file
>From a92160ca6cb61f384609c7dd894bd78821c99921 Mon Sep 17 00:00:00 2001
From: 11happy <soni5happy at gmail.com>
Date: Mon, 22 Jan 2024 23:51:27 +0530
Subject: [PATCH 31/31] correct style issue
Signed-off-by: 11happy <soni5happy at gmail.com>
---
.../readability/UseStdMinMaxCheck.cpp | 61 ++++++++--------
.../checks/readability/use-std-min-max.rst | 69 ++++++++++---------
2 files changed, 64 insertions(+), 66 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 1bc09d8563602a6..a220ad36df2717a 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -29,20 +29,21 @@ void UseStdMinMaxCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
}
void UseStdMinMaxCheck::registerMatchers(MatchFinder *Finder) {
+ auto AssignOperator =
+ binaryOperator(hasOperatorName("="), hasLHS(expr().bind("AssignLhs")),
+ hasRHS(expr().bind("AssignRhs")));
+
Finder->addMatcher(
ifStmt(
stmt().bind("if"),
+ unless(hasElse(stmt())), // Ensure `if` has no `else`
hasCondition(binaryOperator(hasAnyOperatorName("<", ">", "<=", ">="),
hasLHS(expr().bind("CondLhs")),
- hasRHS(expr().bind("CondRhs")))),
- hasThen(anyOf(stmt(binaryOperator(hasOperatorName("="),
- hasLHS(expr().bind("AssignLhs")),
- hasRHS(expr().bind("AssignRhs")))),
- compoundStmt(statementCountIs(1),
- has(binaryOperator(
- hasOperatorName("="),
- hasLHS(expr().bind("AssignLhs")),
- hasRHS(expr().bind("AssignRhs"))))))),
+ hasRHS(expr().bind("CondRhs")))
+ .bind("binaryOp")),
+ hasThen(
+ anyOf(stmt(AssignOperator),
+ compoundStmt(statementCountIs(1), has(AssignOperator)))),
hasParent(stmt(unless(ifStmt(hasElse(
equalsBoundNode("if"))))))), // Ensure `if` has no `else if`
this);
@@ -55,20 +56,11 @@ void UseStdMinMaxCheck::registerPPCallbacks(const SourceManager &SM,
}
void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
- const auto *CondLhs = Result.Nodes.getNodeAs<Expr>("CondLhs");
- const auto *CondRhs = Result.Nodes.getNodeAs<Expr>("CondRhs");
- const auto *AssignLhs = Result.Nodes.getNodeAs<Expr>("AssignLhs");
- const auto *AssignRhs = Result.Nodes.getNodeAs<Expr>("AssignRhs");
const auto *If = Result.Nodes.getNodeAs<IfStmt>("if");
const auto &Context = *Result.Context;
const auto &LO = Context.getLangOpts();
const SourceManager &Source = Context.getSourceManager();
- const auto *BinaryOp = dyn_cast<BinaryOperator>(If->getCond());
- // Ignore `if` statements with `else`
- if (If->hasElseStorage())
- return;
-
const SourceLocation IfLocation = If->getIfLoc();
const SourceLocation ThenLocation = If->getEndLoc();
@@ -76,6 +68,11 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
if (IfLocation.isMacroID() || ThenLocation.isMacroID())
return;
+ const auto *CondLhs = Result.Nodes.getNodeAs<Expr>("CondLhs");
+ const auto *CondRhs = Result.Nodes.getNodeAs<Expr>("CondRhs");
+ const auto *AssignLhs = Result.Nodes.getNodeAs<Expr>("AssignLhs");
+ const auto *AssignRhs = Result.Nodes.getNodeAs<Expr>("AssignRhs");
+
const auto CreateReplacement = [&](bool UseMax) {
const auto *FunctionName = UseMax ? "std::max" : "std::min";
const auto CondLhsStr = Lexer::getSourceText(
@@ -84,22 +81,20 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
Source.getExpansionRange(CondRhs->getSourceRange()), Source, LO);
const auto AssignLhsStr = Lexer::getSourceText(
Source.getExpansionRange(AssignLhs->getSourceRange()), Source, LO);
- if (CondLhs->getType() != CondRhs->getType()) {
- return (AssignLhsStr + " = " + FunctionName + "<" +
- AssignLhs->getType().getAsString() + ">(" + CondLhsStr + ", " +
- CondRhsStr + ");")
- .str();
- } else {
- return (AssignLhsStr + " = " + FunctionName + "(" + CondLhsStr + ", " +
- CondRhsStr + ");")
- .str();
- }
+ return (AssignLhsStr + " = " + FunctionName +
+ ((CondLhs->getType() != CondRhs->getType())
+ ? "<" + AssignLhs->getType().getAsString() + ">("
+ : "(") +
+ CondLhsStr + ", " + CondRhsStr + ");")
+ .str();
};
+ const auto *BinaryOp = Result.Nodes.getNodeAs<BinaryOperator>("binaryOp");
+ const auto BinaryOpcode = BinaryOp->getOpcode();
const auto OperatorStr = BinaryOp->getOpcodeStr();
- if (((BinaryOp->getOpcode() == BO_LT || BinaryOp->getOpcode() == BO_LE) &&
+ if (((BinaryOpcode == BO_LT || BinaryOpcode == BO_LE) &&
(tidy::utils::areStatementsIdentical(CondLhs, AssignRhs, Context) &&
tidy::utils::areStatementsIdentical(CondRhs, AssignLhs, Context))) ||
- ((BinaryOp->getOpcode() == BO_GT || BinaryOp->getOpcode() == BO_GE) &&
+ ((BinaryOpcode == BO_GT || BinaryOpcode == BO_GE) &&
(tidy::utils::areStatementsIdentical(CondLhs, AssignLhs, Context) &&
tidy::utils::areStatementsIdentical(CondRhs, AssignRhs, Context)))) {
diag(IfLocation, "use `std::min` instead of `%0`")
@@ -111,14 +106,12 @@ void UseStdMinMaxCheck::check(const MatchFinder::MatchResult &Result) {
<< IncludeInserter.createIncludeInsertion(
Source.getFileID(If->getBeginLoc()), AlgorithmHeader);
- } else if (((BinaryOp->getOpcode() == BO_LT ||
- BinaryOp->getOpcode() == BO_LE) &&
+ } else if (((BinaryOpcode == BO_LT || BinaryOpcode == BO_LE) &&
(tidy::utils::areStatementsIdentical(CondLhs, AssignLhs,
Context) &&
tidy::utils::areStatementsIdentical(CondRhs, AssignRhs,
Context))) ||
- ((BinaryOp->getOpcode() == BO_GT ||
- BinaryOp->getOpcode() == BO_GE) &&
+ ((BinaryOpcode == BO_GT || BinaryOpcode == BO_GE) &&
(tidy::utils::areStatementsIdentical(CondLhs, AssignRhs,
Context) &&
tidy::utils::areStatementsIdentical(CondRhs, AssignLhs,
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
index 2cf6a58552cdedd..5b4ea9fbcbce2e7 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-std-min-max.rst
@@ -1,32 +1,37 @@
-.. title:: clang-tidy - readability-use-std-min-max
-
-readability-use-std-min-max
-===========================
-
-Replaces certain conditional statements with equivalent ``std::min`` or
-``std::max`` expressions. Note: This may impact
-performance in critical code due to potential additional stores compared
-to the original if statement.
-
-
-Examples:
-
-Before:
-
-.. code-block:: c++
-
- void foo() {
- int a = 2, b = 3;
- if (a < b)
- a = b;
- }
-
-
-After:
-
-.. code-block:: c++
-
- void foo() {
- int a = 2, b = 3;
- a = std::max(a, b);
- }
+..title::clang - tidy - readability - use - std - min -
+ max
+
+ readability -
+ use - std - min - max ==
+ == == == == == == == == == == == ==
+ =
+
+ Replaces certain conditional statements with equivalent ``std::min`` or
+``std::max`` expressions
+ .Note
+ : This may impact performance in critical code due to potential additional stores compared to the
+ original if statement
+ .
+
+ Before :
+
+ ..code -
+ block::c++
+
+ void
+ foo() {
+ int a = 2, b = 3;
+ if (a < b)
+ a = b;
+}
+
+After :
+
+ ..code -
+ block::c++
+
+ void
+ foo() {
+ int a = 2, b = 3;
+ a = std::max(a, b);
+}
More information about the llvm-commits
mailing list