[clang-tools-extra] Added option to readability-implicit-bool-conversion check to allow implicit conversion *to bool* (PR #120087)

via cfe-commits cfe-commits at lists.llvm.org
Mon Dec 16 06:23:21 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-tools-extra

@llvm/pr-subscribers-clang-tidy

Author: None (4m4n-x-B4w4ne)

<details>
<summary>Changes</summary>

As given in the issue #<!-- -->36323 , I added two new options in the clang-tools-extra/clan-tidy/readibility/ImplicitBoolConversionCheck.cpp and header file.
I have also written new test cases to test these new options in test/readibility directory.

---
Full diff: https://github.com/llvm/llvm-project/pull/120087.diff


3 Files Affected:

- (modified) clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp (+9-6) 
- (modified) clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h (+2) 
- (added) clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-check.cpp (+92) 


``````````diff
diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
index f9fd1d903e231e..517a5d2b982751 100644
--- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
@@ -258,14 +258,17 @@ ImplicitBoolConversionCheck::ImplicitBoolConversionCheck(
     : ClangTidyCheck(Name, Context),
       AllowIntegerConditions(Options.get("AllowIntegerConditions", false)),
       AllowPointerConditions(Options.get("AllowPointerConditions", false)),
-      UseUpperCaseLiteralSuffix(
-          Options.get("UseUpperCaseLiteralSuffix", false)) {}
+      UseUpperCaseLiteralSuffix(Options.get("UseUpperCaseLiteralSuffix", false)),
+      CheckConversionsToBool(Options.get("CheckConversionsToBool",true)),
+      CheckConversionsFromBool(Options.get("CheckConversionsFromBool",true)) {}
 
 void ImplicitBoolConversionCheck::storeOptions(
     ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "AllowIntegerConditions", AllowIntegerConditions);
   Options.store(Opts, "AllowPointerConditions", AllowPointerConditions);
   Options.store(Opts, "UseUpperCaseLiteralSuffix", UseUpperCaseLiteralSuffix);
+  Options.store(Opts,"CheckConversionsToBool",CheckConversionsToBool);
+  Options.store(Opts,"CheckConversionsFromBool",CheckConversionsFromBool);
 }
 
 void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
@@ -358,14 +361,14 @@ void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
 void ImplicitBoolConversionCheck::check(
     const MatchFinder::MatchResult &Result) {
 
-  if (const auto *CastToBool =
-          Result.Nodes.getNodeAs<ImplicitCastExpr>("implicitCastToBool")) {
+  if (CheckConversionsToBool && (const auto *CastToBool =
+          Result.Nodes.getNodeAs<ImplicitCastExpr>("implicitCastToBool"))) {
     const auto *Parent = Result.Nodes.getNodeAs<Stmt>("parentStmt");
     return handleCastToBool(CastToBool, Parent, *Result.Context);
   }
 
-  if (const auto *CastFromBool =
-          Result.Nodes.getNodeAs<ImplicitCastExpr>("implicitCastFromBool")) {
+  if (CheckConversionsFromBool && (const auto *CastFromBool =
+          Result.Nodes.getNodeAs<ImplicitCastExpr>("implicitCastFromBool"))) {
     const auto *NextImplicitCast =
         Result.Nodes.getNodeAs<ImplicitCastExpr>("furtherImplicitCast");
     return handleCastFromBool(CastFromBool, NextImplicitCast, *Result.Context);
diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h
index 5947f7316e67cc..b0c3c2943e649c 100644
--- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h
@@ -37,6 +37,8 @@ class ImplicitBoolConversionCheck : public ClangTidyCheck {
   const bool AllowIntegerConditions;
   const bool AllowPointerConditions;
   const bool UseUpperCaseLiteralSuffix;
+  const bool CheckConversionsToBool;
+  const bool CheckConversionsFromBool;
 };
 
 } // namespace clang::tidy::readability
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-check.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-check.cpp
new file mode 100644
index 00000000000000..506769d5a57322
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-check.cpp
@@ -0,0 +1,92 @@
+// RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t
+
+// RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t \
+// RUN: -- -config='{CheckOptions: [{key: readability-implicit-bool-conversion.CheckConversionsToBool, value: false}, {key: readability-implicit-bool-conversion.CheckConversionsFromBool, value: true}]}'
+
+// RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t \
+// RUN: -- -config='{CheckOptions: [{key: readability-implicit-bool-conversion.CheckConversionsToBool, value: true}, {key: readability-implicit-bool-conversion.CheckConversionsFromBool, value: false}]}'
+
+// RUN: %check_clang_tidy %s readability-implicit-bool-conversion %t \
+// RUN: -- -config='{CheckOptions: [{key: readability-implicit-bool-conversion.CheckConversionsToBool, value: false}, {key: readability-implicit-bool-conversion.CheckConversionsFromBool, value: false}]}'
+
+// ==========================================================
+// Test Case: Conversions to bool (CheckConversionsToBool=true)
+// ==========================================================
+void TestConversionsToBool() {
+  int x = 42;
+  if (x) // CHECK-MESSAGES: :[[@LINE]]:8: warning: implicit conversion 'int' -> 'bool'
+    (void)0;
+
+  float f = 3.14;
+  if (f) // CHECK-MESSAGES: :[[@LINE]]:8: warning: implicit conversion 'float' -> 'bool'
+    (void)0;
+
+  int *p = nullptr;
+  if (p) // CHECK-MESSAGES: :[[@LINE]]:8: warning: implicit conversion 'int *' -> 'bool'
+    (void)0;
+
+  // Pointer-to-member
+  struct S {
+    int member;
+  };
+  int S::*ptr = nullptr;
+  if (ptr) // CHECK-MESSAGES: :[[@LINE]]:8: warning: implicit conversion 'int S::*' -> 'bool'
+    (void)0;
+}
+
+// ==========================================================
+// Test Case: Conversions from bool (CheckConversionsFromBool=true)
+// ==========================================================
+void TestConversionsFromBool() {
+  bool b = true;
+
+  int x = b; // CHECK-MESSAGES: :[[@LINE]]:12: warning: implicit conversion 'bool' -> 'int'
+  float f = b; // CHECK-MESSAGES: :[[@LINE]]:12: warning: implicit conversion 'bool' -> 'float'
+  int *p = b;  // CHECK-MESSAGES: :[[@LINE]]:12: warning: implicit conversion 'bool' -> 'int *'
+
+  struct S {
+    int member;
+  };
+  int S::*ptr = b; // CHECK-MESSAGES: :[[@LINE]]:16: warning: implicit conversion 'bool' -> 'int S::*'
+}
+
+// ==========================================================
+// Test Case: Mixed Configurations (ToBool=false, FromBool=true)
+// ==========================================================
+void TestMixedConfig() {
+  int x = 42;
+  if (x) // No warning: CheckConversionsToBool=false
+    (void)0;
+
+  bool b = true;
+  int y = b; // CHECK-MESSAGES: :[[@LINE]]:12: warning: implicit conversion 'bool' -> 'int'
+}
+
+// ==========================================================
+// Test Case: No Diagnostics (ToBool=false, FromBool=false)
+// ==========================================================
+void TestNoDiagnostics() {
+  int x = 42;
+  if (x) // No warning: CheckConversionsToBool=false
+    (void)0;
+
+  bool b = true;
+  int y = b; // No warning: CheckConversionsFromBool=false
+}
+
+// ==========================================================
+// Test Case: Edge Cases and Complex Expressions
+// ==========================================================
+void TestEdgeCases() {
+  bool b = true;
+
+  // Nested implicit casts
+  int x = (b ? 1 : 0); // CHECK-MESSAGES: :[[@LINE]]:12: warning: implicit conversion 'bool' -> 'int'
+
+  // Function returns implicit bool
+  auto ReturnBool = []() -> bool { return true; };
+  int y = ReturnBool(); // CHECK-MESSAGES: :[[@LINE]]:12: warning: implicit conversion 'bool' -> 'int'
+
+  // Explicit casts (no diagnostics)
+  int z = static_cast<int>(b); // No warning: explicit cast
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/120087


More information about the cfe-commits mailing list