https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/83497
I have seen internal pieces of code that uses a template type parameter to accept std::function, a closure type, or any callable type. The diagnostic added in #83152 would require adaptation to the template, which is difficult and also seems unnecessary. ```cpp template <typename... Ts> static bool IsFalse(const Ts&...) { return false; } template <typename T, typename... Ts, typename = typename std::enable_if<std::is_constructible<bool, const T&>::value>::type> static bool IsFalse(const Partial&, const T& p, const Ts&...) { return p ? false : true; } template <typename... Args> void Init(Args&&... args) { if (IsFalse(absl::implicit_cast<const typename std::decay<Args>::type&>( args)...)) { // A callable object convertible to false is either a null pointer or a // null functor (e.g., a default-constructed std::function). empty_ = true; } else { empty_ = false; new (&factory_) Factory(std::forward<Args>(args)...); } } ``` >From d7a168190f2fdf3b4f8ec1457400ad8e03bc3f3a Mon Sep 17 00:00:00 2001 From: Fangrui Song <i...@maskray.me> Date: Thu, 29 Feb 2024 14:40:00 -0800 Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?= =?UTF-8?q?l=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.4 --- clang/lib/Sema/SemaChecking.cpp | 17 ++++++++++------- clang/test/SemaCXX/warn-bool-conversion.cpp | 13 +++++++++++++ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 690bdaa63d058b..3533b5c8e0d235 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -16586,13 +16586,16 @@ 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 (const auto *MRecordDecl = MCallExpr->getRecordDecl(); - MRecordDecl && MRecordDecl->isLambda()) { - Diag(E->getExprLoc(), diag::warn_impcast_pointer_to_bool) - << /*LambdaPointerConversionOperatorType=*/3 - << MRecordDecl->getSourceRange() << Range << IsEqual; - return; + // outside of instantiation. + if (!inTemplateInstantiation()) { + if (const auto *MCallExpr = dyn_cast<CXXMemberCallExpr>(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; + } } } diff --git a/clang/test/SemaCXX/warn-bool-conversion.cpp b/clang/test/SemaCXX/warn-bool-conversion.cpp index 9e8cf0e4f8944a..8b1bf80af79d26 100644 --- a/clang/test/SemaCXX/warn-bool-conversion.cpp +++ b/clang/test/SemaCXX/warn-bool-conversion.cpp @@ -92,6 +92,19 @@ void foo() { bool is_true = [](){ return true; }; // expected-warning@-1{{address of lambda function pointer conversion operator will always evaluate to 'true'}} } + +template <typename... Ts> +static bool IsFalse(const Ts&...) { return false; } +template <typename T> +static bool IsFalse(const T& p) { + bool b; + b = f7; // expected-warning {{address of lambda function pointer conversion operator will always evaluate to 'true'}} + return p ? false : true; +} + +bool use_instantiation() { + return IsFalse([]() { return 0; }); +} #endif void bar() { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits