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 <vinayakdev....@gmail.com> 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 <https://github.com/llvm/llvm-project/issues/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<CXXMemberCallExpr>(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<DeclRefExpr>(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<void(*)()>; // 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