llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: None (Ralender) <details> <summary>Changes</summary> This emits warnings for this code instead of silently creating a new B in place. ```c++ struct B { B(bool V) {} }; void test(const B& b); void test0(B* b) { test(b); // HERE } ``` --- Full diff: https://github.com/llvm/llvm-project/pull/143990.diff 3 Files Affected: - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+3) - (modified) clang/lib/Sema/SemaChecking.cpp (+19) - (modified) clang/test/SemaCXX/warn-bool-conversion.cpp (+31) ``````````diff diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 0f77083dac9df..8a17b04ad91ed 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4397,6 +4397,9 @@ def ext_ms_impcast_fn_obj : ExtWarn< "implicit conversion between pointer-to-function and pointer-to-object is a " "Microsoft extension">, InGroup<MicrosoftCast>; +def warn_imp_constructor_pointer_to_bool : Warning< + "implicit conversion from %0 to %1 calls %q2; maybe you intended to dereference">, + InGroup<PointerBoolConversion>; def warn_impcast_pointer_to_bool : Warning< "address of %select{'%1'|function '%1'|array '%1'|lambda function pointer " "conversion operator}0 will always evaluate to 'true'">, diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 8f8e1ceb7197e..d0d52f3a1fe87 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -11767,6 +11767,25 @@ static void CheckImplicitArgumentConversions(Sema &S, const CallExpr *TheCall, SourceLocation CC) { for (unsigned I = 0, N = TheCall->getNumArgs(); I < N; ++I) { const Expr *CurrA = TheCall->getArg(I); + + if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(CurrA)) + // We shouldnt skip over any node here as it may be an attempt to silence + // the warning + if (auto *CCE = dyn_cast<CXXConstructExpr>(MTE->getSubExpr())) + if (CCE->getNumArgs() == 1) { + Expr *Inner = CCE->getArg(0)->IgnoreImpCasts(); + if ((Inner->getType()->isAnyPointerType() && + Inner->getType()->getPointeeType().getUnqualifiedType() == + CCE->getType().getUnqualifiedType())) { + S.Diag(CCE->getLocation(), + diag::warn_imp_constructor_pointer_to_bool) + << Inner->getType() << CCE->getType() << CCE->getConstructor(); + S.Diag(CCE->getConstructor()->getLocation(), + diag::note_entity_declared_at) + << CCE->getConstructor(); + } + } + if (!IsImplicitBoolFloatConversion(S, CurrA, true)) continue; diff --git a/clang/test/SemaCXX/warn-bool-conversion.cpp b/clang/test/SemaCXX/warn-bool-conversion.cpp index 18c35776b17bc..52d5315e7cb3b 100644 --- a/clang/test/SemaCXX/warn-bool-conversion.cpp +++ b/clang/test/SemaCXX/warn-bool-conversion.cpp @@ -234,3 +234,34 @@ namespace Template { template void h<d>(); } #endif // __cplusplus < 201703L + +namespace implicit_constructor_bool { + +struct B { + bool a; + B(bool V) : a(V) {} // expected-note {{'B' declared here}} +}; + +void test(const B& b); + +void test0(B* b) { + test(b); // expected-warning {{implicit conversion from 'B *' to 'const B' calls}} + test((const B&)b); + test(B(b)); + test((bool)b); + test(static_cast<bool>(b)); + test(*b); +} + +struct C { + bool a; + explicit C(bool V) : a(V) {} +}; + +void testC(const C& b); // expected-note {{candidate function not viable: no known conversion from 'C *' to 'const C'}} + +void testC0(C* b) { + testC(b); // expected-error {{no matching function for call to 'testC'}} +} + +} `````````` </details> https://github.com/llvm/llvm-project/pull/143990 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits