[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-29 Thread Fangrui Song via cfe-commits

MaskRay wrote:

Created #83497 as a follow-up to suppress the diagnostic for certain template 
instantiation uses.

I made one change to unblock our internal users
```
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpointer-bool-conversion"
#endif
// functor_ may be a lambda, which is convertible to bool, leading to a
// -Wpointer-bool-conversion warning because the value is always true.
return functor_ == nullptr;
#ifdef __clang__
#pragma clang diagnostic pop
#endif
```

and then (when I saw another instance of wrapping a callable object) realized 
we probably should suppress the diagnostic for instantiation. This is similar 
to how we suppress the diagnostic for instantiations for -Wtautological-compare

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-29 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman closed 
https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits

vinayakdsci wrote:

@shafik I have made the change in the code as you suggested. If everything 
seems alright, could you land this for me?

Thanks a lot!

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits

https://github.com/vinayakdsci updated 
https://github.com/llvm/llvm-project/pull/83152

>From 3d6100ae6fa291db24f26e2ccbce88293810e168 Mon Sep 17 00:00:00 2001
From: Vinayak Dev 
Date: Tue, 27 Feb 2024 18:05:29 +0530
Subject: [PATCH] [Clang][Sema]: Diagnose lambda to bool implicit casts

---
 clang/docs/ReleaseNotes.rst  |  3 +++
 clang/include/clang/Basic/DiagnosticSemaKinds.td |  4 ++--
 clang/lib/Sema/SemaChecking.cpp  | 11 +++
 clang/test/CXX/drs/dr18xx.cpp|  1 +
 .../CXX/expr/expr.prim/expr.prim.lambda/blocks.mm|  9 +
 clang/test/SemaCXX/warn-bool-conversion.cpp  | 12 
 6 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7e16b9f0c67dbd..a5c6b80c4e99e1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -192,6 +192,9 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses declarative nested name specifiers that name alias 
templates.
 
+- Clang now diagnoses lambda function expressions being implicitly cast to 
boolean values, under ``-Wpointer-bool-conversion``.
+  Fixes `#82512 `_.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f726805dc02bd9..60ec9a259a48ff 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4127,8 +4127,8 @@ def ext_ms_impcast_fn_obj : ExtWarn<
   "Microsoft extension">, InGroup;
 
 def warn_impcast_pointer_to_bool : Warning<
-"address of%select{| function| array}0 '%1' will always evaluate to "
-"'true'">,
+"address of %select{'%1'|function '%1'|array '%1'|lambda function pointer "
+"conversion operator}0 will always evaluate to 'true'">,
 InGroup;
 def warn_cast_nonnull_to_bool : Warning<
 "nonnull %select{function call|parameter}0 '%1' will evaluate to "
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 979b63884359fc..35d453e013e84b 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16544,6 +16544,17 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (const auto *MRecordDecl = MCallExpr->getRecordDecl();
+MRecordDecl && MRecordDecl->isLambda()) {
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*LambdaPointerConversionOperatorType=*/3
+  << MRecordDecl->getSourceRange() << Range << IsEqual;
+  return;
+}
+  }
+
   // Expect to find a single Decl.  Skip anything more complicated.
   ValueDecl *D = nullptr;
   if (DeclRefExpr *R = dyn_cast(E)) {
diff --git a/clang/test/CXX/drs/dr18xx.cpp b/clang/test/CXX/drs/dr18xx.cpp
index a7cee4ef8902f9..e78730e8992cf8 100644
--- a/clang/test/CXX/drs/dr18xx.cpp
+++ b/clang/test/CXX/drs/dr18xx.cpp
@@ -282,6 +282,7 @@ namespace dr1837 { // dr1837: 3.3
   struct A {
 int f();
 bool b = [] {
+  // since-cxx11-warning@-1 {{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
   struct Local {
 static_assert(sizeof(this->f()) == sizeof(int), "");
   };
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm 
b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
index cb56f6816ad036..e93c37f3b9ae12 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
@@ -65,10 +65,10 @@ void nesting() {
 
 namespace overloading {
   void bool_conversion() {
-if ([](){}) {
+if ([](){}) { // expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
 }
 
-bool b = []{};
+bool b = []{}; // expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
 b = (bool)[]{};
   }
 
@@ -108,8 +108,9 @@ void call_with_lambda() {
 using decltype(a)::operator id; // expected-note {{here}}
   } extern d;
 
-  bool r1 = c;
-  bool r2 = d; // expected-error {{private}}
+  bool r1 = c; // expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
+  bool r2 = d; // expected-error {{private}} \
+  expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
 }
 
 namespace PR13117 {
diff --git a/clang/test/SemaCXX/warn-bool-conversion.cpp 
b/clang/test/SemaCXX/warn-bool-conversion.cpp
index c81d52d864f2d2..9e8cf0e4f8944a 100644
--- a/clang/test/SemaCXX/warn-bool-conversion.cpp
+++ b/clang/test/SemaCXX/warn-bool-conversion.cpp

[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread via cfe-commits

github-actions[bot] wrote:




:warning: C/C++ code formatter, clang-format found issues in your code. 
:warning:



You can test this locally with the following command:


``bash
git-clang-format --diff 14d8c4563e045fc3da82cb7268b1066cfd1bb6f0 
60620d14509b4d097a56d0b61177dfe9c5a72b63 -- clang/lib/Sema/SemaChecking.cpp 
clang/test/CXX/drs/dr18xx.cpp clang/test/SemaCXX/warn-bool-conversion.cpp
``





View the diff from clang-format here.


``diff
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 2926a81fe7..35d453e013 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16549,7 +16549,7 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 if (const auto *MRecordDecl = MCallExpr->getRecordDecl();
 MRecordDecl && MRecordDecl->isLambda()) {
   Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
-  << /*LambdaPointerConversionOperatorType=*/ 3
+  << /*LambdaPointerConversionOperatorType=*/3
   << MRecordDecl->getSourceRange() << Range << IsEqual;
   return;
 }

``




https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits

https://github.com/vinayakdsci updated 
https://github.com/llvm/llvm-project/pull/83152

>From 60620d14509b4d097a56d0b61177dfe9c5a72b63 Mon Sep 17 00:00:00 2001
From: Vinayak Dev 
Date: Tue, 27 Feb 2024 18:05:29 +0530
Subject: [PATCH] [Clang][Sema]: Diagnose lambda to bool implicit casts

---
 clang/docs/ReleaseNotes.rst  |  3 +++
 clang/include/clang/Basic/DiagnosticSemaKinds.td |  4 ++--
 clang/lib/Sema/SemaChecking.cpp  | 11 +++
 clang/test/CXX/drs/dr18xx.cpp|  1 +
 .../CXX/expr/expr.prim/expr.prim.lambda/blocks.mm|  9 +
 clang/test/SemaCXX/warn-bool-conversion.cpp  | 12 
 6 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7e16b9f0c67dbd..a5c6b80c4e99e1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -192,6 +192,9 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses declarative nested name specifiers that name alias 
templates.
 
+- Clang now diagnoses lambda function expressions being implicitly cast to 
boolean values, under ``-Wpointer-bool-conversion``.
+  Fixes `#82512 `_.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f726805dc02bd9..60ec9a259a48ff 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4127,8 +4127,8 @@ def ext_ms_impcast_fn_obj : ExtWarn<
   "Microsoft extension">, InGroup;
 
 def warn_impcast_pointer_to_bool : Warning<
-"address of%select{| function| array}0 '%1' will always evaluate to "
-"'true'">,
+"address of %select{'%1'|function '%1'|array '%1'|lambda function pointer "
+"conversion operator}0 will always evaluate to 'true'">,
 InGroup;
 def warn_cast_nonnull_to_bool : Warning<
 "nonnull %select{function call|parameter}0 '%1' will evaluate to "
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 979b63884359fc..2926a81fe7b8a6 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16544,6 +16544,17 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (const auto *MRecordDecl = MCallExpr->getRecordDecl();
+MRecordDecl && MRecordDecl->isLambda()) {
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*LambdaPointerConversionOperatorType=*/ 3
+  << MRecordDecl->getSourceRange() << Range << IsEqual;
+  return;
+}
+  }
+
   // Expect to find a single Decl.  Skip anything more complicated.
   ValueDecl *D = nullptr;
   if (DeclRefExpr *R = dyn_cast(E)) {
diff --git a/clang/test/CXX/drs/dr18xx.cpp b/clang/test/CXX/drs/dr18xx.cpp
index a7cee4ef8902f9..e78730e8992cf8 100644
--- a/clang/test/CXX/drs/dr18xx.cpp
+++ b/clang/test/CXX/drs/dr18xx.cpp
@@ -282,6 +282,7 @@ namespace dr1837 { // dr1837: 3.3
   struct A {
 int f();
 bool b = [] {
+  // since-cxx11-warning@-1 {{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
   struct Local {
 static_assert(sizeof(this->f()) == sizeof(int), "");
   };
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm 
b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
index cb56f6816ad036..e93c37f3b9ae12 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
@@ -65,10 +65,10 @@ void nesting() {
 
 namespace overloading {
   void bool_conversion() {
-if ([](){}) {
+if ([](){}) { // expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
 }
 
-bool b = []{};
+bool b = []{}; // expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
 b = (bool)[]{};
   }
 
@@ -108,8 +108,9 @@ void call_with_lambda() {
 using decltype(a)::operator id; // expected-note {{here}}
   } extern d;
 
-  bool r1 = c;
-  bool r2 = d; // expected-error {{private}}
+  bool r1 = c; // expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
+  bool r2 = d; // expected-error {{private}} \
+  expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
 }
 
 namespace PR13117 {
diff --git a/clang/test/SemaCXX/warn-bool-conversion.cpp 
b/clang/test/SemaCXX/warn-bool-conversion.cpp
index c81d52d864f2d2..9e8cf0e4f8944a 100644
--- a/clang/test/SemaCXX/warn-bool-conversion.cpp
+++ b/clang/test/SemaCXX/warn-bool-conversion.cpp

[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Shafik Yaghmour via cfe-commits

https://github.com/shafik edited https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Shafik Yaghmour via cfe-commits


@@ -16538,6 +16538,17 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (const auto *MRecordDecl = MCallExpr->getRecordDecl();
+MRecordDecl && MRecordDecl->isLambda()) {
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*LambdaPointerConversionOperatorType*/ 3

shafik wrote:

```suggestion
  << /*LambdaPointerConversionOperatorType=*/ 3
```

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Shafik Yaghmour via cfe-commits


@@ -16538,6 +16538,17 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (const auto *MRecordDecl = MCallExpr->getRecordDecl();
+MRecordDecl && MRecordDecl->isLambda()) {
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*LambdaPointerConversionOperatorType*/ 3

shafik wrote:

nitpick just to be consistent w/ 
[bugprone-argument-comment](https://clang.llvm.org/extra/clang-tidy/checks/bugprone/argument-comment.html),
 although I don't think it actually catches these cases.

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Shafik Yaghmour via cfe-commits

https://github.com/shafik commented:

Thank you for this fix. I am happy the changes were not too different from my 
suggestion. Sometimes problems end up being more difficult then they seem 
initially.

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll approved this pull request.

DR test changes look good, save for a nit.

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vlad Serebrennikov via cfe-commits


@@ -281,7 +281,7 @@ namespace dr1837 { // dr1837: 3.3
 
   struct A {
 int f();
-bool b = [] {
+bool b = [] { // since-cxx11-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}

Endilll wrote:

Convert this to `// since-cxx11-warning@-1` style, to follow the rest of the 
file.

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll edited 
https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman approved this pull request.

LGTM! @Endilll, do you have any concerns?

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> @AaronBallman sorry for repeating the same mistake twice, I was unable to 
> correctly interpret what you wanted to say when you meant removing the lambda 
> body from the diagnostic. I have made all the suggested changes and updated 
> the tests. I hope I don't come across as dumb :-) ! I will be more mindful of 
> what changes I have made before pushing them to the remote in the future.

No worries at all, your contribution is *very* appreciated! Also, it's not like 
I have room to judge -- I suggested breaking code and making a useless test! We 
all make mistakes. ;-)

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits

vinayakdsci wrote:

@AaronBallman sorry for repeating the same mistake twice, I was unable to 
correctly interpret what you wanted to say when you meant removing the lambda 
body from the diagnostic.
I have made all the suggested changes and updated the tests. I hope I don't 
come across as dumb :-) ! I will be more mindful of what changes I have made 
before pushing them to the remote in the future.

Thanks!

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits

https://github.com/vinayakdsci updated 
https://github.com/llvm/llvm-project/pull/83152

>From 640cbf94879217526e27884beefcbffa404fc082 Mon Sep 17 00:00:00 2001
From: Vinayak Dev 
Date: Tue, 27 Feb 2024 18:05:29 +0530
Subject: [PATCH] [Clang][Sema]: Diagnose lambda to bool implicit casts

---
 clang/docs/ReleaseNotes.rst  |  3 +++
 clang/include/clang/Basic/DiagnosticSemaKinds.td |  4 ++--
 clang/lib/Sema/SemaChecking.cpp  | 11 +++
 clang/test/CXX/drs/dr18xx.cpp|  2 +-
 .../CXX/expr/expr.prim/expr.prim.lambda/blocks.mm|  9 +
 clang/test/SemaCXX/warn-bool-conversion.cpp  | 12 
 6 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7e16b9f0c67dbd..a5c6b80c4e99e1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -192,6 +192,9 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses declarative nested name specifiers that name alias 
templates.
 
+- Clang now diagnoses lambda function expressions being implicitly cast to 
boolean values, under ``-Wpointer-bool-conversion``.
+  Fixes `#82512 `_.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c8141fefb8edba..72d8a60bec118e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4127,8 +4127,8 @@ def ext_ms_impcast_fn_obj : ExtWarn<
   "Microsoft extension">, InGroup;
 
 def warn_impcast_pointer_to_bool : Warning<
-"address of%select{| function| array}0 '%1' will always evaluate to "
-"'true'">,
+"address of %select{'%1'|function '%1'|array '%1'|lambda function pointer "
+"conversion operator}0 will always evaluate to 'true'">,
 InGroup;
 def warn_cast_nonnull_to_bool : Warning<
 "nonnull %select{function call|parameter}0 '%1' will evaluate to "
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0de76ee119cf81..d27f14715a1b20 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16538,6 +16538,17 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (const auto *MRecordDecl = MCallExpr->getRecordDecl();
+MRecordDecl && MRecordDecl->isLambda()) {
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*LambdaPointerConversionOperatorType*/ 3
+  << MRecordDecl->getSourceRange() << Range << IsEqual;
+  return;
+}
+  }
+
   // Expect to find a single Decl.  Skip anything more complicated.
   ValueDecl *D = nullptr;
   if (DeclRefExpr *R = dyn_cast(E)) {
diff --git a/clang/test/CXX/drs/dr18xx.cpp b/clang/test/CXX/drs/dr18xx.cpp
index a7cee4ef8902f9..52601153eb6312 100644
--- a/clang/test/CXX/drs/dr18xx.cpp
+++ b/clang/test/CXX/drs/dr18xx.cpp
@@ -281,7 +281,7 @@ namespace dr1837 { // dr1837: 3.3
 
   struct A {
 int f();
-bool b = [] {
+bool b = [] { // since-cxx11-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
   struct Local {
 static_assert(sizeof(this->f()) == sizeof(int), "");
   };
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm 
b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
index cb56f6816ad036..e93c37f3b9ae12 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
@@ -65,10 +65,10 @@ void nesting() {
 
 namespace overloading {
   void bool_conversion() {
-if ([](){}) {
+if ([](){}) { // expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
 }
 
-bool b = []{};
+bool b = []{}; // expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
 b = (bool)[]{};
   }
 
@@ -108,8 +108,9 @@ void call_with_lambda() {
 using decltype(a)::operator id; // expected-note {{here}}
   } extern d;
 
-  bool r1 = c;
-  bool r2 = d; // expected-error {{private}}
+  bool r1 = c; // expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
+  bool r2 = d; // expected-error {{private}} \
+  expected-warning{{address of lambda function pointer 
conversion operator will always evaluate to 'true'}}
 }
 
 namespace PR13117 {
diff --git a/clang/test/SemaCXX/warn-bool-conversion.cpp 
b/clang/test/SemaCXX/warn-bool-conversion.cpp
index c81d52d864f2d2..9e8cf0e4f8944a 100644
--- a/clang/test/SemaCXX/warn-bool-conversion.cpp
+++ 

[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits

https://github.com/vinayakdsci deleted 
https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits


@@ -16538,6 +16538,21 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (const auto *MRecordDecl = MCallExpr->getRecordDecl();
+MRecordDecl && MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*LambdaPointerConversionOperatorType*/ 3 << S.str()
+  << MRecordDecl->getSourceRange() << Range << IsEqual;

vinayakdsci wrote:

Whoops, I accidentally missed that! Thanks for pointing out the mistakes. Since 
we don't use `S` anyway, can I omit the call to `printPretty()` altogether?

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Aaron Ballman via cfe-commits


@@ -4127,8 +4127,8 @@ def ext_ms_impcast_fn_obj : ExtWarn<
   "Microsoft extension">, InGroup;
 
 def warn_impcast_pointer_to_bool : Warning<
-"address of%select{| function| array}0 '%1' will always evaluate to "
-"'true'">,
+"address of%select{| function| array| lambda function pointer conversion 
operator}0 '%1' "
+"will always evaluate to 'true'">,

AaronBallman wrote:

```suggestion
"address of %select{'%1'|function '%1'|array '%1'|lambda function pointer "
"conversion operator}0 will always evaluate to 'true'">,
```
Wrapping to 80-col limits, moves %1 so it's not used for lambda conversion 
operators.

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Aaron Ballman via cfe-commits


@@ -16538,6 +16538,21 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (const auto *MRecordDecl = MCallExpr->getRecordDecl();
+MRecordDecl && MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*LambdaPointerConversionOperatorType*/ 3 << S.str()
+  << MRecordDecl->getSourceRange() << Range << IsEqual;

AaronBallman wrote:

```suggestion
  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
  << /*LambdaPointerConversionOperatorType*/ 3
  << MRecordDecl->getSourceRange() << Range << IsEqual;
```
This way we don't pretty print the entire lambda body in the diagnostic message.

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits

vinayakdsci wrote:

Done! I added the diagnostic to the TableGen file, and passed in only the 
Record's source range instead of the whole expression's. Now only the lambda's 
initializer is highlighted in the diagnostic. I hope this does it!

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits

https://github.com/vinayakdsci updated 
https://github.com/llvm/llvm-project/pull/83152

>From 613e7c0698f16292bb408be832c7ab3647f17195 Mon Sep 17 00:00:00 2001
From: Vinayak Dev 
Date: Tue, 27 Feb 2024 18:05:29 +0530
Subject: [PATCH] [Clang][Sema]: Diagnose lambda to bool implicit casts

---
 clang/docs/ReleaseNotes.rst   |  3 +++
 clang/include/clang/Basic/DiagnosticSemaKinds.td  |  4 ++--
 clang/lib/Sema/SemaChecking.cpp   | 15 +++
 clang/test/CXX/drs/dr18xx.cpp |  7 ++-
 .../CXX/expr/expr.prim/expr.prim.lambda/blocks.mm |  9 +
 clang/test/SemaCXX/warn-bool-conversion.cpp   | 14 ++
 6 files changed, 45 insertions(+), 7 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7e16b9f0c67dbd..a5c6b80c4e99e1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -192,6 +192,9 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses declarative nested name specifiers that name alias 
templates.
 
+- Clang now diagnoses lambda function expressions being implicitly cast to 
boolean values, under ``-Wpointer-bool-conversion``.
+  Fixes `#82512 `_.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index c8141fefb8edba..1fd450237e0266 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4127,8 +4127,8 @@ def ext_ms_impcast_fn_obj : ExtWarn<
   "Microsoft extension">, InGroup;
 
 def warn_impcast_pointer_to_bool : Warning<
-"address of%select{| function| array}0 '%1' will always evaluate to "
-"'true'">,
+"address of%select{| function| array| lambda function pointer conversion 
operator}0 '%1' "
+"will always evaluate to 'true'">,
 InGroup;
 def warn_cast_nonnull_to_bool : Warning<
 "nonnull %select{function call|parameter}0 '%1' will evaluate to "
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0de76ee119cf81..1ce7f0044103fc 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16538,6 +16538,21 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (const auto *MRecordDecl = MCallExpr->getRecordDecl();
+MRecordDecl && MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*LambdaPointerConversionOperatorType*/ 3 << S.str()
+  << MRecordDecl->getSourceRange() << Range << IsEqual;
+  return;
+}
+  }
+
   // Expect to find a single Decl.  Skip anything more complicated.
   ValueDecl *D = nullptr;
   if (DeclRefExpr *R = dyn_cast(E)) {
diff --git a/clang/test/CXX/drs/dr18xx.cpp b/clang/test/CXX/drs/dr18xx.cpp
index a7cee4ef8902f9..d69698c5e27fdb 100644
--- a/clang/test/CXX/drs/dr18xx.cpp
+++ b/clang/test/CXX/drs/dr18xx.cpp
@@ -281,12 +281,17 @@ namespace dr1837 { // dr1837: 3.3
 
   struct A {
 int f();
-bool b = [] {
+bool b = [] { // #dr1837-a
   struct Local {
 static_assert(sizeof(this->f()) == sizeof(int), "");
   };
 };
   };
+  /* since-cxx11-warning@#dr1837-a{{address of lambda function pointer 
conversion operator '[] {
+struct Local {
+static_assert(sizeof (this->f()) == sizeof(int), "");
+};
+}' will always evaluate to 'true'}} */
 #endif
 }
 
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm 
b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
index cb56f6816ad036..0e27075a2a2597 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
@@ -65,10 +65,10 @@ void nesting() {
 
 namespace overloading {
   void bool_conversion() {
-if ([](){}) {
+if ([](){}) { // expected-warning{{address of lambda function pointer 
conversion operator '[]() {\n}' will always evaluate to 'true'}}
 }
 
-bool b = []{};
+bool b = []{}; // expected-warning{{address of lambda function pointer 
conversion operator '[] {\n}' will always evaluate to 'true'}}
 b = (bool)[]{};
   }
 
@@ -108,8 +108,9 @@ void call_with_lambda() {
 using decltype(a)::operator id; // expected-note {{here}}
   } extern d;
 
-  bool r1 = c;
-  bool r2 = d; // expected-error {{private}}
+  bool r1 = c; // expected-warning{{address of lambda function pointer 
conversion operator 'c' will always evaluate to 'true'}}
+  bool r2 = d; // expected-error {{private}} \
+  expected-warning{{address of lambda function pointer 
conversion 

[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Aaron Ballman via cfe-commits


@@ -16538,6 +16538,24 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (MCallExpr->getObjectType()->isRecordType()) {
+  if (const auto *MRecordDecl = MCallExpr->getRecordDecl()) {
+if (MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*FunctionPointerType*/ 1 << S.str() << E->getSourceRange()
+  << Range << IsEqual;
+  return;
+}
+  }
+}
+  }

AaronBallman wrote:

> Should I modify the code to do this instead??

Yes please!

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits


@@ -16538,6 +16538,24 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (MCallExpr->getObjectType()->isRecordType()) {
+  if (const auto *MRecordDecl = MCallExpr->getRecordDecl()) {
+if (MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*FunctionPointerType*/ 1 << S.str() << E->getSourceRange()
+  << Range << IsEqual;
+  return;
+}
+  }
+}
+  }

vinayakdsci wrote:

That is actually a great idea! and then the diagnostic would simply say address 
of lambda function {..} will always evaluate to true. Would actually be more 
informative than printing the entire expression in my opinion. Should I modify 
the code to do this instead??

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Aaron Ballman via cfe-commits


@@ -16538,6 +16538,24 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (MCallExpr->getObjectType()->isRecordType()) {
+  if (const auto *MRecordDecl = MCallExpr->getRecordDecl()) {
+if (MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*FunctionPointerType*/ 1 << S.str() << E->getSourceRange()
+  << Range << IsEqual;
+  return;
+}
+  }
+}
+  }

AaronBallman wrote:

Do you actually need the call to `isRecordType()`? I would have thought this 
was equivalent.
```suggestion
  if (const auto *MCallExpr = dyn_cast(E)) {
if (const auto *MRecordDecl = MCallExpr->getRecordDecl(); MRecordDecl && 
MRecordDecl->isLambda()) {
  std::string Str;
  llvm::raw_string_ostream S(Str);

  E->printPretty(S, nullptr, getPrintingPolicy());
  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
  << /*FunctionPointerType*/ 1 << S.str() << E->getSourceRange()
  << Range << IsEqual;
  return;
}
  }
```

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Aaron Ballman via cfe-commits


@@ -16538,6 +16538,24 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (MCallExpr->getObjectType()->isRecordType()) {
+  if (const auto *MRecordDecl = MCallExpr->getRecordDecl()) {
+if (MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*FunctionPointerType*/ 1 << S.str() << E->getSourceRange()
+  << Range << IsEqual;
+  return;
+}
+  }
+}
+  }

AaronBallman wrote:

Actually, I'm not convinced we *should* print the entire expression in this 
case. Lambdas usually aren't nearly as trivial as the ones we have in our test 
cases, and can be arbitrarily long. e.g.,
```
C:\Users\aballman\OneDrive - Intel Corporation\Desktop\test.cpp:2:7: warning: 
address of function '[]() {
int foo = 0;
return foo;
}' will always evaluate to 'true' [-Wpointer-bool-conversion]
2 |   if ([](){
  |   ~~  ^
3 | // This is a comment
  | 
4 | // intended to make the lambda
  | ~~
5 | // longer so that it shows
  | ~~
6 | // what the diagnostic behavior is
  | ~~
7 | int foo = 0;
  | 
8 | // of really large lambdas, and whether
  | ~~~
9 | // it is worth it to print out the entire
  | ~
   10 | // expression in this case.
  | ~~~
   11 | return foo;
  | ~~~
   12 |   }) {
  |   ~
1 warning generated.
```
This has two problems: 1) it repeats the user's code in both the diagnostic and 
in the highlighting, 2) the amount of context is huge and distracts from the 
diagnostic.

I think we should modify `warn_impcast_pointer_to_bool` to something along 
these lines:
```
def warn_impcast_pointer_to_bool : Warning<
"address of%select{| function| array| lambda function pointer conversion 
operator}0 '%1' will always evaluate to 'true'">, 
InGroup;
```
(Will need to be reformatted for the usual 80-col limits.) And when passing the 
source range for the lambda expression, I think we should pass only the lambda 
introducer as the source range so that we highlight far less code.

WDYT?

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll requested changes to this pull request.


https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vlad Serebrennikov via cfe-commits


@@ -287,6 +287,11 @@ namespace dr1837 { // dr1837: 3.3
   };
 };
   };
+  /* since-cxx11-warning@-6{{address of function '[] {

Endilll wrote:

Can you convert this to use a marker? We don't want readers to count relative 
offsets. In other words, it should read `since-cxx11-warning@#dr1837-lambda 
{{address of function ...`

You can see an example in the test for 1890.

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vlad Serebrennikov via cfe-commits

https://github.com/Endilll edited 
https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits

https://github.com/vinayakdsci updated 
https://github.com/llvm/llvm-project/pull/83152

>From c65c6a379db75eb4bf38578106ba2aa4e894e3d8 Mon Sep 17 00:00:00 2001
From: Vinayak Dev 
Date: Tue, 27 Feb 2024 18:05:29 +0530
Subject: [PATCH] [Clang][Sema]: Diagnose lambda to bool implicit casts

---
 clang/docs/ReleaseNotes.rst|  3 +++
 clang/lib/Sema/SemaChecking.cpp| 18 ++
 clang/test/CXX/drs/dr18xx.cpp  |  5 +
 .../expr/expr.prim/expr.prim.lambda/blocks.mm  |  9 +
 clang/test/SemaCXX/warn-bool-conversion.cpp| 14 ++
 5 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7e16b9f0c67dbd..a5c6b80c4e99e1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -192,6 +192,9 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses declarative nested name specifiers that name alias 
templates.
 
+- Clang now diagnoses lambda function expressions being implicitly cast to 
boolean values, under ``-Wpointer-bool-conversion``.
+  Fixes `#82512 `_.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0de76ee119cf81..ea0a739af0cca1 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16538,6 +16538,24 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (MCallExpr->getObjectType()->isRecordType()) {
+  if (const auto *MRecordDecl = MCallExpr->getRecordDecl()) {
+if (MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*FunctionPointerType*/ 1 << S.str() << E->getSourceRange()
+  << Range << IsEqual;
+  return;
+}
+  }
+}
+  }
+
   // Expect to find a single Decl.  Skip anything more complicated.
   ValueDecl *D = nullptr;
   if (DeclRefExpr *R = dyn_cast(E)) {
diff --git a/clang/test/CXX/drs/dr18xx.cpp b/clang/test/CXX/drs/dr18xx.cpp
index a7cee4ef8902f9..6fd063e043517b 100644
--- a/clang/test/CXX/drs/dr18xx.cpp
+++ b/clang/test/CXX/drs/dr18xx.cpp
@@ -287,6 +287,11 @@ namespace dr1837 { // dr1837: 3.3
   };
 };
   };
+  /* since-cxx11-warning@-6{{address of function '[] {
+struct Local {
+static_assert(sizeof (this->f()) == sizeof(int), "");
+};
+}' will always evaluate to 'true'}} */
 #endif
 }
 
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm 
b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
index cb56f6816ad036..9041d07e02a5bc 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
@@ -65,10 +65,10 @@ void nesting() {
 
 namespace overloading {
   void bool_conversion() {
-if ([](){}) {
+if ([](){}) { // expected-warning{{address of function '[]() {\n}' will 
always evaluate to 'true'}}
 }
 
-bool b = []{};
+bool b = []{}; // expected-warning{{address of function '[] {\n}' will 
always evaluate to 'true'}}
 b = (bool)[]{};
   }
 
@@ -108,8 +108,9 @@ void call_with_lambda() {
 using decltype(a)::operator id; // expected-note {{here}}
   } extern d;
 
-  bool r1 = c;
-  bool r2 = d; // expected-error {{private}}
+  bool r1 = c; // expected-warning{{address of function 'c' will always 
evaluate to 'true'}}
+  bool r2 = d; // expected-error {{private}} \
+  expected-warning{{address of function 'd' will always 
evaluate to 'true'}}
 }
 
 namespace PR13117 {
diff --git a/clang/test/SemaCXX/warn-bool-conversion.cpp 
b/clang/test/SemaCXX/warn-bool-conversion.cpp
index c81d52d864f2d2..f95627b8ac0ca5 100644
--- a/clang/test/SemaCXX/warn-bool-conversion.cpp
+++ b/clang/test/SemaCXX/warn-bool-conversion.cpp
@@ -81,6 +81,20 @@ struct S2 {
 
 bool f5();
 bool f6(int);
+#if __cplusplus >= 201103L
+auto f7 = []{};
+auto f8 = [](){};
+
+void foo() {
+  bool b;
+  b = f7; // expected-warning {{address of function 'f7' will always evaluate 
to 'true'}}
+  b = f8; // expected-warning {{address of function 'f8' will always evaluate 
to 'true'}}
+  bool is_true = [](){ return true; };
+/* expected-cxx11-warning@-1{{address of function '[]() {
+return true;
+}' will always evaluate to 'true'}} */
+}
+#endif
 
 void bar() {
   bool b;

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


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits

https://github.com/vinayakdsci updated 
https://github.com/llvm/llvm-project/pull/83152

>From 0e9d7e7ed96feb8c32be33ca9b1262bba32ab8b4 Mon Sep 17 00:00:00 2001
From: Vinayak Dev 
Date: Tue, 27 Feb 2024 18:05:29 +0530
Subject: [PATCH] [Clang][Sema]: Diagnose lambda to bool implicit casts

---
 clang/docs/ReleaseNotes.rst|  3 +++
 clang/lib/Sema/SemaChecking.cpp| 18 ++
 clang/test/CXX/drs/dr18xx.cpp  |  5 +
 .../expr/expr.prim/expr.prim.lambda/blocks.mm  |  9 +
 clang/test/SemaCXX/warn-bool-conversion.cpp| 14 ++
 5 files changed, 45 insertions(+), 4 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7e16b9f0c67dbd..a5c6b80c4e99e1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -192,6 +192,9 @@ Improvements to Clang's diagnostics
 
 - Clang now diagnoses declarative nested name specifiers that name alias 
templates.
 
+- Clang now diagnoses lambda function expressions being implicitly cast to 
boolean values, under ``-Wpointer-bool-conversion``.
+  Fixes `#82512 `_.
+
 Improvements to Clang's time-trace
 --
 
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0de76ee119cf81..ea0a739af0cca1 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16538,6 +16538,24 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (const auto *MCallExpr = dyn_cast(E)) {
+if (MCallExpr->getObjectType()->isRecordType()) {
+  if (const auto *MRecordDecl = MCallExpr->getRecordDecl()) {
+if (MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
+  << /*FunctionPointerType*/ 1 << S.str() << E->getSourceRange()
+  << Range << IsEqual;
+  return;
+}
+  }
+}
+  }
+
   // Expect to find a single Decl.  Skip anything more complicated.
   ValueDecl *D = nullptr;
   if (DeclRefExpr *R = dyn_cast(E)) {
diff --git a/clang/test/CXX/drs/dr18xx.cpp b/clang/test/CXX/drs/dr18xx.cpp
index a7cee4ef8902f9..6fd063e043517b 100644
--- a/clang/test/CXX/drs/dr18xx.cpp
+++ b/clang/test/CXX/drs/dr18xx.cpp
@@ -287,6 +287,11 @@ namespace dr1837 { // dr1837: 3.3
   };
 };
   };
+  /* since-cxx11-warning@-6{{address of function '[] {
+struct Local {
+static_assert(sizeof (this->f()) == sizeof(int), "");
+};
+}' will always evaluate to 'true'}} */
 #endif
 }
 
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm 
b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
index cb56f6816ad036..9041d07e02a5bc 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm
@@ -65,10 +65,10 @@ void nesting() {
 
 namespace overloading {
   void bool_conversion() {
-if ([](){}) {
+if ([](){}) { // expected-warning{{address of function '[]() {\n}' will 
always evaluate to 'true'}}
 }
 
-bool b = []{};
+bool b = []{}; // expected-warning{{address of function '[] {\n}' will 
always evaluate to 'true'}}
 b = (bool)[]{};
   }
 
@@ -108,8 +108,9 @@ void call_with_lambda() {
 using decltype(a)::operator id; // expected-note {{here}}
   } extern d;
 
-  bool r1 = c;
-  bool r2 = d; // expected-error {{private}}
+  bool r1 = c; // expected-warning{{address of function 'c' will always 
evaluate to 'true'}}
+  bool r2 = d; // expected-error {{private}} \
+  expected-warning{{address of function 'd' will always 
evaluate to 'true'}}
 }
 
 namespace PR13117 {
diff --git a/clang/test/SemaCXX/warn-bool-conversion.cpp 
b/clang/test/SemaCXX/warn-bool-conversion.cpp
index c81d52d864f2d2..f95627b8ac0ca5 100644
--- a/clang/test/SemaCXX/warn-bool-conversion.cpp
+++ b/clang/test/SemaCXX/warn-bool-conversion.cpp
@@ -81,6 +81,20 @@ struct S2 {
 
 bool f5();
 bool f6(int);
+#if __cplusplus >= 201103L
+auto f7 = []{};
+auto f8 = [](){};
+
+void foo() {
+  bool b;
+  b = f7; // expected-warning {{address of function 'f7' will always evaluate 
to 'true'}}
+  b = f8; // expected-warning {{address of function 'f8' will always evaluate 
to 'true'}}
+  bool is_true = [](){ return true; };
+/* expected-cxx11-warning@-1{{address of function '[]() {
+return true;
+}' will always evaluate to 'true'}} */
+}
+#endif
 
 void bar() {
   bool b;

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


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Aaron Ballman via cfe-commits

AaronBallman wrote:

> > There are some related test failures caught by precommit CI that need to be 
> > addressed.
> > The issue in dr18xx.cpp looks to be a case where we should replace `bool b 
> > = ` with `auto b = ` (it doesn't change the testing for what's discussed in 
> > http://wg21.link/cwg1837).
> 
> Changing `bool b = ` to `auto b =` does not compile, as the compiler 
> complains that `auto` is not allowed in non-static struct members. `b` cannot 
> be declared as `static` either, which would cause an invalid use of `this` 
> outside of a non-static member function. It looks like type deduction using 
> auto for member variables is not allowed.

Yeah, another think-o on my part. I think it's fine to add the expected 
diagnostic to the file instead of silencing the warning.

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Aaron Ballman via cfe-commits


@@ -16538,6 +16538,27 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (auto *MCallExpr = dyn_cast(E)) {
+if (MCallExpr->getObjectType()->isRecordType()) {
+  if (auto *MRecordDecl = MCallExpr->getRecordDecl()) {
+if (MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+  const unsigned DiagID = diag::warn_impcast_pointer_to_bool;
+  // For lambdas, the pointer type is function, which corresponds to 1.
+  const unsigned FunctionPointerType = 1;
+  // Pretty print the diagnostic for the warning
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), DiagID)
+  << FunctionPointerType << S.str() << E->getSourceRange() << Range
+  << IsEqual;
+  return;

AaronBallman wrote:

Oh gosh, this was a think-o on my part, you're right, that is being passed 
through the diagnostics engine. Sorry for the noise, I must have been tired. :-)

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits


@@ -16538,6 +16538,27 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (auto *MCallExpr = dyn_cast(E)) {
+if (MCallExpr->getObjectType()->isRecordType()) {
+  if (auto *MRecordDecl = MCallExpr->getRecordDecl()) {
+if (MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+  const unsigned DiagID = diag::warn_impcast_pointer_to_bool;
+  // For lambdas, the pointer type is function, which corresponds to 1.
+  const unsigned FunctionPointerType = 1;
+  // Pretty print the diagnostic for the warning
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), DiagID)
+  << FunctionPointerType << S.str() << E->getSourceRange() << Range
+  << IsEqual;
+  return;

vinayakdsci wrote:

Removing the call to `printPretty` will not populate `S`, so the diagnostic 
will not have the name for the identifier describing the error-causing function 
but instead display `' '`. Is there a workaround for this? Or should I leave it 
be? Thanks!

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits

vinayakdsci wrote:

> There are some related test failures caught by precommit CI that need to be 
> addressed.
> 
> The issue in dr18xx.cpp looks to be a case where we should replace `bool b = 
> ` with `auto b = ` (it doesn't change the testing for what's discussed in 
> http://wg21.link/cwg1837).

Changing `bool b = ` to `auto b =` does not compile, as the compiler complains 
that `auto` is not allowed in non-static struct members. `b` cannot be declared 
as `static` either, which would cause an invalid use of `this` outside of a 
non-static member function. It looks like type deduction using auto for member 
variables is not allowed.

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-28 Thread Vinayak Dev via cfe-commits


@@ -16538,6 +16538,27 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (auto *MCallExpr = dyn_cast(E)) {
+if (MCallExpr->getObjectType()->isRecordType()) {
+  if (auto *MRecordDecl = MCallExpr->getRecordDecl()) {
+if (MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+  const unsigned DiagID = diag::warn_impcast_pointer_to_bool;
+  // For lambdas, the pointer type is function, which corresponds to 1.
+  const unsigned FunctionPointerType = 1;
+  // Pretty print the diagnostic for the warning
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), DiagID)
+  << FunctionPointerType << S.str() << E->getSourceRange() << Range
+  << IsEqual;
+  return;

vinayakdsci wrote:

OK, understood. I will make the required changes, and force push again. Thanks 
for the  review!

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-27 Thread Aaron Ballman via cfe-commits


@@ -16538,6 +16538,27 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (auto *MCallExpr = dyn_cast(E)) {
+if (MCallExpr->getObjectType()->isRecordType()) {
+  if (auto *MRecordDecl = MCallExpr->getRecordDecl()) {
+if (MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+  const unsigned DiagID = diag::warn_impcast_pointer_to_bool;
+  // For lambdas, the pointer type is function, which corresponds to 1.
+  const unsigned FunctionPointerType = 1;
+  // Pretty print the diagnostic for the warning
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), DiagID)
+  << FunctionPointerType << S.str() << E->getSourceRange() << Range
+  << IsEqual;
+  return;

AaronBallman wrote:

```suggestion
  Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
  << /*FunctionPointerType*/ 1 << S.str() << E->getSourceRange() << 
Range
  << IsEqual;
   return;
```
Two changes happening here: 1) moves some constant variables inline, 2) removes 
the call to `printPretty()`.

(2) is because we expect diagnostic output to all be piped through the 
diagnostics engine, so that we can do things like format it differently (e.g., 
perhaps print it as SARIF rather than text)

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-27 Thread Aaron Ballman via cfe-commits


@@ -16538,6 +16538,27 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (auto *MCallExpr = dyn_cast(E)) {
+if (MCallExpr->getObjectType()->isRecordType()) {
+  if (auto *MRecordDecl = MCallExpr->getRecordDecl()) {

AaronBallman wrote:

```suggestion
  if (const auto *MCallExpr = dyn_cast(E)) {
if (MCallExpr->getObjectType()->isRecordType()) {
  if (const auto *MRecordDecl = MCallExpr->getRecordDecl()) {
```
Aiming for better const correctness, but if this doesn't work, don't worry 
about making the changes.

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-27 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman requested changes to this pull request.

Thank you for the fix!

There are some related test failures caught by precommit CI that need to be 
addressed.

The issue in dr18xx.cpp looks to be a case where we should replace `bool b = ` 
with `auto b = ` (it doesn't change the testing for what's discussed in 
http://wg21.link/cwg1837).

The issues in blocks.mm should get new expected warning markings for the 
improved diagnostics.

You should also add a release note to `clang/docs/ReleaseNotes.rst` so users 
know about the fix (and mention the issue number as well).

The changes should come with new test coverage, probably in one of the existing 
tests in `clang/test/SemaCXX/`.

https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-27 Thread Aaron Ballman via cfe-commits

https://github.com/AaronBallman edited 
https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-27 Thread via cfe-commits

llvmbot wrote:




@llvm/pr-subscribers-clang

Author: Vinayak Dev (vinayakdsci)


Changes

Fixes #82512 

Adds diagnostics for lambda expressions being cast to boolean values, which 
results in the expression always evaluating to true.
Earlier, Clang allowed compilation of such erroneous programs, but now emits a 
warning through `-Wpointer-bool-conversion`.

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


1 Files Affected:

- (modified) clang/lib/Sema/SemaChecking.cpp (+21) 


``diff
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0de76ee119cf81..3b03036587baeb 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16538,6 +16538,27 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (auto *MCallExpr = dyn_cast(E)) {
+if (MCallExpr->getObjectType()->isRecordType()) {
+  if (auto *MRecordDecl = MCallExpr->getRecordDecl()) {
+if (MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+  const unsigned DiagID = diag::warn_impcast_pointer_to_bool;
+  // For lambdas, the pointer type is function, which corresponds to 1.
+  const unsigned FunctionPointerType = 1;
+  // Pretty print the diagnostic for the warning
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), DiagID)
+  << FunctionPointerType << S.str() << E->getSourceRange() << Range
+  << IsEqual;
+  return;
+}
+  }
+}
+  }
+
   // Expect to find a single Decl.  Skip anything more complicated.
   ValueDecl *D = nullptr;
   if (DeclRefExpr *R = dyn_cast(E)) {

``




https://github.com/llvm/llvm-project/pull/83152
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [Clang][Sema]: Diagnose lambda to bool implicit casts (PR #83152)

2024-02-27 Thread Vinayak Dev via cfe-commits

https://github.com/vinayakdsci created 
https://github.com/llvm/llvm-project/pull/83152

Fixes #82512 

Adds diagnostics for lambda expressions being cast to boolean values, which 
results in the expression always evaluating to true.
Earlier, Clang allowed compilation of such erroneous programs, but now emits a 
warning through `-Wpointer-bool-conversion`.

>From 859ce0b2acbeb65543e891e5e5a9b519c0c504b5 Mon Sep 17 00:00:00 2001
From: Vinayak Dev 
Date: Tue, 27 Feb 2024 18:05:29 +0530
Subject: [PATCH] [Clang][Sema]: Diagnose lambda to bool implicit casts

---
 clang/lib/Sema/SemaChecking.cpp | 21 +
 1 file changed, 21 insertions(+)

diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 0de76ee119cf81..3b03036587baeb 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -16538,6 +16538,27 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
 }
   }
 
+  // Complain if we are converting a lambda expression to a boolean value
+  if (auto *MCallExpr = dyn_cast(E)) {
+if (MCallExpr->getObjectType()->isRecordType()) {
+  if (auto *MRecordDecl = MCallExpr->getRecordDecl()) {
+if (MRecordDecl->isLambda()) {
+  std::string Str;
+  llvm::raw_string_ostream S(Str);
+  const unsigned DiagID = diag::warn_impcast_pointer_to_bool;
+  // For lambdas, the pointer type is function, which corresponds to 1.
+  const unsigned FunctionPointerType = 1;
+  // Pretty print the diagnostic for the warning
+  E->printPretty(S, nullptr, getPrintingPolicy());
+  Diag(E->getExprLoc(), DiagID)
+  << FunctionPointerType << S.str() << E->getSourceRange() << Range
+  << IsEqual;
+  return;
+}
+  }
+}
+  }
+
   // Expect to find a single Decl.  Skip anything more complicated.
   ValueDecl *D = nullptr;
   if (DeclRefExpr *R = dyn_cast(E)) {

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