[clang] Implement Wpointer-bool-conversion-strict (PR #131523)

via cfe-commits cfe-commits at lists.llvm.org
Sun Mar 16 08:27:55 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Yutong Zhu (YutongZhuu)

<details>
<summary>Changes</summary>

This PR implements the feature request from issue #<!-- -->9500. From the original issue:

```c
_Bool foo(void) {
  _Bool x = (void *)0; // warn on this
  return (void *)0; // warn on this
}
```

However, I believe that using null checks like if ``(!p) return;`` is a common practice in C/C++ code. Because of this, I made the option ignored by default.

Additionally, the issue creator appears to be requesting more than just pointer-to-bool conversion checks. Please let me know your thoughts on this.

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


6 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+2) 
- (modified) clang/include/clang/Basic/DiagnosticGroups.td (+1) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+4) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+3) 
- (added) clang/test/Sema/warn-pointer-bool-conversion-strict.c (+13) 
- (added) clang/test/Sema/warn-pointer-bool-conversion-strict.cpp (+12) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7859871b0493a..5c9783d051de5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -136,6 +136,8 @@ New Compiler Flags
   The feature has `existed <https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#running-the-instrumented-program>`_)
   for a while and this is just a user facing option.
 
+- New Option ``-Wpointer-bool-conversion-strict`` has been added to warn about all implicit pointer-to-bool conversions (#GH9500). This option is ignored by default.
+
 Deprecated Compiler Flags
 -------------------------
 
diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index fac80fb4009aa..4b2baa898a918 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -74,6 +74,7 @@ def LiteralConversion : DiagGroup<"literal-conversion">;
 def StringConversion : DiagGroup<"string-conversion">;
 def SignConversion : DiagGroup<"sign-conversion">;
 def PointerBoolConversion : DiagGroup<"pointer-bool-conversion">;
+def PointerBoolConversionStrict : DiagGroup<"pointer-bool-conversion-strict">;
 def UndefinedBoolConversion : DiagGroup<"undefined-bool-conversion">;
 def BitwiseInsteadOfLogical : DiagGroup<"bitwise-instead-of-logical">;
 def BoolOperation : DiagGroup<"bool-operation", [BitwiseInsteadOfLogical]>;
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 14b0051709625..7f81b8ece55b5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4337,6 +4337,10 @@ def warn_impcast_pointer_to_bool : Warning<
     "address of %select{'%1'|function '%1'|array '%1'|lambda function pointer "
     "conversion operator}0 will always evaluate to 'true'">,
     InGroup<PointerBoolConversion>;
+def warn_impcast_pointer_to_bool_strict: Warning<
+    "implicit conversion of pointer to bool">,
+    InGroup<PointerBoolConversionStrict>,
+    DefaultIgnore;
 def warn_cast_nonnull_to_bool : Warning<
     "nonnull %select{function call|parameter}0 '%1' will evaluate to "
     "'true' on first encounter">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 9cac9cf5c4df7..fee5611873232 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -11699,6 +11699,9 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC,
       DiagnoseAlwaysNonNullPointer(E, Expr::NPCK_NotNull, /*IsEqual*/ false,
                                    SourceRange(CC));
     }
+    if (Source->isPointerType()) {
+      Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool_strict);
+    }
   }
 
   // If the we're converting a constant to an ObjC BOOL on a platform where BOOL
diff --git a/clang/test/Sema/warn-pointer-bool-conversion-strict.c b/clang/test/Sema/warn-pointer-bool-conversion-strict.c
new file mode 100644
index 0000000000000..5620f054d4354
--- /dev/null
+++ b/clang/test/Sema/warn-pointer-bool-conversion-strict.c
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -Wpointer-bool-conversion %s
+#include <stddef.h>
+_Bool f() {
+  int *p;
+  if (p) {} // expected-warning {{implicit conversion of pointer to bool}}
+  return (void *)0; // expected-warning {{implicit conversion of pointer to bool}}
+}
+
+_Bool g() {
+  int *p = (void *)0;
+  if (p == NULL) {} // no-warning
+  return (void *)0 == NULL; // no-warning
+}
diff --git a/clang/test/Sema/warn-pointer-bool-conversion-strict.cpp b/clang/test/Sema/warn-pointer-bool-conversion-strict.cpp
new file mode 100644
index 0000000000000..8e612d2459705
--- /dev/null
+++ b/clang/test/Sema/warn-pointer-bool-conversion-strict.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -Wpointer-bool-conversion %s
+bool f() {
+    int *p;
+    if (p) {} // expected-warning {{implicit conversion of pointer to bool}}
+    return (void *)0; // expected-warning {{implicit conversion of pointer to bool}}
+}
+
+bool g() {
+    int *p = nullptr;
+    if (p == nullptr) {} // no-warning
+    return (void *)0 == nullptr; // no-warning
+}

``````````

</details>


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


More information about the cfe-commits mailing list