Skip to content

Commit c65c6a3

Browse files
committed
[Clang][Sema]: Diagnose lambda to bool implicit casts
1 parent 9e14320 commit c65c6a3

File tree

5 files changed

+45
-4
lines changed

5 files changed

+45
-4
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,9 @@ Improvements to Clang's diagnostics
192192

193193
- Clang now diagnoses declarative nested name specifiers that name alias templates.
194194

195+
- Clang now diagnoses lambda function expressions being implicitly cast to boolean values, under ``-Wpointer-bool-conversion``.
196+
Fixes `#82512 <https://github.com/llvm/llvm-project/issues/82512>`_.
197+
195198
Improvements to Clang's time-trace
196199
----------------------------------
197200

clang/lib/Sema/SemaChecking.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16538,6 +16538,24 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
1653816538
}
1653916539
}
1654016540

16541+
// Complain if we are converting a lambda expression to a boolean value
16542+
if (const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(E)) {
16543+
if (MCallExpr->getObjectType()->isRecordType()) {
16544+
if (const auto *MRecordDecl = MCallExpr->getRecordDecl()) {
16545+
if (MRecordDecl->isLambda()) {
16546+
std::string Str;
16547+
llvm::raw_string_ostream S(Str);
16548+
16549+
E->printPretty(S, nullptr, getPrintingPolicy());
16550+
Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool)
16551+
<< /*FunctionPointerType*/ 1 << S.str() << E->getSourceRange()
16552+
<< Range << IsEqual;
16553+
return;
16554+
}
16555+
}
16556+
}
16557+
}
16558+
1654116559
// Expect to find a single Decl. Skip anything more complicated.
1654216560
ValueDecl *D = nullptr;
1654316561
if (DeclRefExpr *R = dyn_cast<DeclRefExpr>(E)) {

clang/test/CXX/drs/dr18xx.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,11 @@ namespace dr1837 { // dr1837: 3.3
287287
};
288288
};
289289
};
290+
/* since-cxx11-warning@-6{{address of function '[] {
291+
struct Local {
292+
static_assert(sizeof (this->f()) == sizeof(int), "");
293+
};
294+
}' will always evaluate to 'true'}} */
290295
#endif
291296
}
292297

clang/test/CXX/expr/expr.prim/expr.prim.lambda/blocks.mm

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ void nesting() {
6565

6666
namespace overloading {
6767
void bool_conversion() {
68-
if ([](){}) {
68+
if ([](){}) { // expected-warning{{address of function '[]() {\n}' will always evaluate to 'true'}}
6969
}
7070

71-
bool b = []{};
71+
bool b = []{}; // expected-warning{{address of function '[] {\n}' will always evaluate to 'true'}}
7272
b = (bool)[]{};
7373
}
7474

@@ -108,8 +108,9 @@ void call_with_lambda() {
108108
using decltype(a)::operator id<void(*)()>; // expected-note {{here}}
109109
} extern d;
110110

111-
bool r1 = c;
112-
bool r2 = d; // expected-error {{private}}
111+
bool r1 = c; // expected-warning{{address of function 'c' will always evaluate to 'true'}}
112+
bool r2 = d; // expected-error {{private}} \
113+
expected-warning{{address of function 'd' will always evaluate to 'true'}}
113114
}
114115

115116
namespace PR13117 {

clang/test/SemaCXX/warn-bool-conversion.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,20 @@ struct S2 {
8181

8282
bool f5();
8383
bool f6(int);
84+
#if __cplusplus >= 201103L
85+
auto f7 = []{};
86+
auto f8 = [](){};
87+
88+
void foo() {
89+
bool b;
90+
b = f7; // expected-warning {{address of function 'f7' will always evaluate to 'true'}}
91+
b = f8; // expected-warning {{address of function 'f8' will always evaluate to 'true'}}
92+
bool is_true = [](){ return true; };
93+
/* expected-cxx11-warning@-1{{address of function '[]() {
94+
return true;
95+
}' will always evaluate to 'true'}} */
96+
}
97+
#endif
8498

8599
void bar() {
86100
bool b;

0 commit comments

Comments
 (0)