[clang-tools-extra] Add clang-tidy check to suggest replacement of conditional statement with std::min/std::max (PR #77816)

Bhuminjay Soni via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 11 10:42:06 PST 2024


https://github.com/11happy created https://github.com/llvm/llvm-project/pull/77816

**Overview:**
This pull request fixes #64914 where author suggests adding a readability check to propose the replacement of conditional statements with std::min/std::max for improved code readability. Additionally, reference is made to PyLint's similar checks: [consider-using-min-builtin](https://pylint.pycqa.org/en/latest/user_guide/messages/refactor/consider-using-min-builtin.html) and [consider-using-max-builtin](https://pylint.pycqa.org/en/latest/user_guide/messages/refactor/consider-using-max-builtin.html)

**Testing:**
- Tested the updated code.
- Verified that other functionalities remain unaffected.
![Screenshot from 2024-01-12 00-09-35](https://github.com/llvm/llvm-project/assets/76656712/bd81a8ea-bf07-4bda-a7ed-13e12f69ea82)


**Dependencies:**
- No dependencies on other pull requests.

**CC:**
- @AaronBallman , @EugeneZelenko , @PiotrZSL , @carlosgalvezp 


>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 1/2] 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 408c822b861c5f..4bc373bb69bb84 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 00000000000000..fba8c68f737450
--- /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 00000000000000..b7eabcc7d16d41
--- /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 0b0aad7c0dcb36..63f8f03be6bb91 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 b4d87e0ed2a67a..c3fb990ad6a738 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 2f86121ad87299..c2eac55425c69e 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 00000000000000..e95858999b2772
--- /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 00000000000000..d29e9aa9fec708
--- /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 2/2] 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 fba8c68f737450..86420765d6f6c6 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 b7eabcc7d16d41..02ebed83fed6c8 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



More information about the cfe-commits mailing list