diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 7be2b31df2413..9f9b0a0baba66 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -16588,13 +16588,16 @@ 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; + // outside of instantiation. + if (!inTemplateInstantiation()) { + 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; + } } } diff --git a/clang/test/SemaCXX/warn-bool-conversion.cpp b/clang/test/SemaCXX/warn-bool-conversion.cpp index 9e8cf0e4f8944..18c35776b17bc 100644 --- a/clang/test/SemaCXX/warn-bool-conversion.cpp +++ b/clang/test/SemaCXX/warn-bool-conversion.cpp @@ -92,6 +92,21 @@ void foo() { bool is_true = [](){ return true; }; // expected-warning@-1{{address of lambda function pointer conversion operator will always evaluate to 'true'}} } + +template +static bool IsFalse(const Ts&...) { return false; } +template +static bool IsFalse(const T& p) { + bool b; + b = f7; // expected-warning {{address of lambda function pointer conversion operator will always evaluate to 'true'}} + // Intentionally not warned on because p could be a lambda type in one + // instantiation, but a pointer type in another. + return p ? false : true; +} + +bool use_instantiation() { + return IsFalse([]() { return 0; }); +} #endif void bar() {