https://github.com/Ralender updated 
https://github.com/llvm/llvm-project/pull/143990

>From f2744c89892d2803a36d03579b1fd278cfd1bb44 Mon Sep 17 00:00:00 2001
From: tyker <tyk...@outlook.com>
Date: Fri, 13 Jun 2025 00:49:00 +0200
Subject: [PATCH 1/2] [clang] Add diagnostic for usage of implicit constructor
 with pointer to bool convertion

Like
```c++
struct B {
   B(bool V) {}
};

void test(const B& b);

void test0(B* b) {
   test(b); // HERE
}
```
---
 .../clang/Basic/DiagnosticSemaKinds.td        |  3 ++
 clang/lib/Sema/SemaChecking.cpp               | 19 ++++++++++++
 clang/test/SemaCXX/warn-bool-conversion.cpp   | 31 +++++++++++++++++++
 3 files changed, 53 insertions(+)

diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 0f77083dac9df..8a17b04ad91ed 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4397,6 +4397,9 @@ def ext_ms_impcast_fn_obj : ExtWarn<
   "implicit conversion between pointer-to-function and pointer-to-object is a "
   "Microsoft extension">, InGroup<MicrosoftCast>;
 
+def warn_imp_constructor_pointer_to_bool : Warning<
+    "implicit conversion from %0 to %1 calls %q2; maybe you intended to 
dereference">,
+    InGroup<PointerBoolConversion>;
 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'">,
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 8f8e1ceb7197e..d0d52f3a1fe87 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -11767,6 +11767,25 @@ static void CheckImplicitArgumentConversions(Sema &S, 
const CallExpr *TheCall,
                                              SourceLocation CC) {
   for (unsigned I = 0, N = TheCall->getNumArgs(); I < N; ++I) {
     const Expr *CurrA = TheCall->getArg(I);
+
+    if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(CurrA))
+      // We shouldnt skip over any node here as it may be an attempt to silence
+      // the warning
+      if (auto *CCE = dyn_cast<CXXConstructExpr>(MTE->getSubExpr()))
+        if (CCE->getNumArgs() == 1) {
+          Expr *Inner = CCE->getArg(0)->IgnoreImpCasts();
+          if ((Inner->getType()->isAnyPointerType() &&
+               Inner->getType()->getPointeeType().getUnqualifiedType() ==
+                   CCE->getType().getUnqualifiedType())) {
+            S.Diag(CCE->getLocation(),
+                   diag::warn_imp_constructor_pointer_to_bool)
+                << Inner->getType() << CCE->getType() << CCE->getConstructor();
+            S.Diag(CCE->getConstructor()->getLocation(),
+                   diag::note_entity_declared_at)
+                << CCE->getConstructor();
+          }
+        }
+
     if (!IsImplicitBoolFloatConversion(S, CurrA, true))
       continue;
 
diff --git a/clang/test/SemaCXX/warn-bool-conversion.cpp 
b/clang/test/SemaCXX/warn-bool-conversion.cpp
index 18c35776b17bc..52d5315e7cb3b 100644
--- a/clang/test/SemaCXX/warn-bool-conversion.cpp
+++ b/clang/test/SemaCXX/warn-bool-conversion.cpp
@@ -234,3 +234,34 @@ namespace Template {
   template void h<d>();
 }
 #endif // __cplusplus < 201703L
+
+namespace implicit_constructor_bool {
+
+struct B {
+  bool a;
+  B(bool V) : a(V) {} // expected-note {{'B' declared here}}
+};
+
+void test(const B& b);
+
+void test0(B* b) {
+  test(b); // expected-warning {{implicit conversion from 'B *' to 'const B' 
calls}}
+  test((const B&)b);
+  test(B(b));
+  test((bool)b);
+  test(static_cast<bool>(b));
+  test(*b);
+}
+
+struct C {
+  bool a;
+  explicit C(bool V) : a(V) {}
+};
+
+void testC(const C& b); // expected-note {{candidate function not viable: no 
known conversion from 'C *' to 'const C'}}
+
+void testC0(C* b) {
+  testC(b); // expected-error {{no matching function for call to 'testC'}}
+}
+
+}

>From 56bfa00fd3ceb4029f48b24a04a164ec689111a6 Mon Sep 17 00:00:00 2001
From: tyker <tyk...@outlook.com>
Date: Thu, 26 Jun 2025 20:10:28 +0200
Subject: [PATCH 2/2] Address review comments + add fixit

---
 clang/docs/ReleaseNotes.rst                      | 13 +++++++++++++
 clang/include/clang/Basic/DiagnosticSemaKinds.td |  2 +-
 clang/lib/Sema/SemaChecking.cpp                  | 13 ++++++++-----
 clang/test/SemaCXX/warn-bool-conversion.cpp      |  6 ++++--
 4 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index b42d5f8425af6..0aa8a48eaab93 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -622,6 +622,19 @@ Improvements to Clang's diagnostics
 
 - Improved the FixIts for unused lambda captures.
 
+- ``-Wpointer-bool-conversion`` will now also warn in the following case
+
+  .. code-block:: c
+
+    struct B {
+      B(bool V) {}
+    };
+    void test(const B& b);
+    void test0(B* b) {
+      test(b); // this will call B::B(bool) and create a new B
+    }
+
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 8a17b04ad91ed..cb8662f2bc09b 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4398,7 +4398,7 @@ def ext_ms_impcast_fn_obj : ExtWarn<
   "Microsoft extension">, InGroup<MicrosoftCast>;
 
 def warn_imp_constructor_pointer_to_bool : Warning<
-    "implicit conversion from %0 to %1 calls %q2; maybe you intended to 
dereference">,
+    "implicit conversion from %0 to %1 calls %q2; did you intend to 
dereference ?">,
     InGroup<PointerBoolConversion>;
 def warn_impcast_pointer_to_bool : Warning<
     "address of %select{'%1'|function '%1'|array '%1'|lambda function pointer "
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index d0d52f3a1fe87..10fa2b6588ae5 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -11768,18 +11768,21 @@ static void CheckImplicitArgumentConversions(Sema &S, 
const CallExpr *TheCall,
   for (unsigned I = 0, N = TheCall->getNumArgs(); I < N; ++I) {
     const Expr *CurrA = TheCall->getArg(I);
 
-    if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(CurrA))
+    if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(CurrA))
       // We shouldnt skip over any node here as it may be an attempt to silence
       // the warning
-      if (auto *CCE = dyn_cast<CXXConstructExpr>(MTE->getSubExpr()))
-        if (CCE->getNumArgs() == 1) {
-          Expr *Inner = CCE->getArg(0)->IgnoreImpCasts();
+      if (const auto *CCE = dyn_cast<CXXConstructExpr>(MTE->getSubExpr()))
+        if (CCE->getNumArgs() == 1 &&
+            CCE->getArg(0)->getType()->isBooleanType() &&
+            !CCE->getConstructor()->isExplicit()) {
+          const Expr *Inner = CCE->getArg(0)->IgnoreImpCasts();
           if ((Inner->getType()->isAnyPointerType() &&
                Inner->getType()->getPointeeType().getUnqualifiedType() ==
                    CCE->getType().getUnqualifiedType())) {
             S.Diag(CCE->getLocation(),
                    diag::warn_imp_constructor_pointer_to_bool)
-                << Inner->getType() << CCE->getType() << CCE->getConstructor();
+                << Inner->getType() << CCE->getType() << CCE->getConstructor()
+                << FixItHint::CreateInsertion(Inner->getBeginLoc(), "*");
             S.Diag(CCE->getConstructor()->getLocation(),
                    diag::note_entity_declared_at)
                 << CCE->getConstructor();
diff --git a/clang/test/SemaCXX/warn-bool-conversion.cpp 
b/clang/test/SemaCXX/warn-bool-conversion.cpp
index 52d5315e7cb3b..93090553db8fa 100644
--- a/clang/test/SemaCXX/warn-bool-conversion.cpp
+++ b/clang/test/SemaCXX/warn-bool-conversion.cpp
@@ -1,6 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -verify=expected,expected-cxx11 %s
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
 // RUN: %clang_cc1 -fsyntax-only -verify=expected,expected-cxx11 -std=c++11 %s
+// RUN: not %clang_cc1 -fsyntax-only %s -fdiagnostics-parseable-fixits 2>&1 | 
FileCheck %s
 
 namespace BooleanFalse {
 int* j = false;
@@ -245,7 +246,8 @@ struct B {
 void test(const B& b);
 
 void test0(B* b) {
-  test(b); // expected-warning {{implicit conversion from 'B *' to 'const B' 
calls}}
+  test(b); // expected-warning {{implicit conversion from 'B *' to 'const B' 
calls 'implicit_constructor_bool::B::B'; did you intend to dereference ?}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:8-[[@LINE-1]]:8}:"*"
   test((const B&)b);
   test(B(b));
   test((bool)b);
@@ -258,7 +260,7 @@ struct C {
   explicit C(bool V) : a(V) {}
 };
 
-void testC(const C& b); // expected-note {{candidate function not viable: no 
known conversion from 'C *' to 'const C'}}
+void testC(const C& b); // expected-note {{candidate function not viable: no 
known conversion from 'C *' to 'const C' for 1st argument; dereference the 
argument with *}}
 
 void testC0(C* b) {
   testC(b); // expected-error {{no matching function for call to 'testC'}}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to