llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Aditya Medhane (flash1729) <details> <summary>Changes</summary> Look through a reference-to-function in `DiagnoseAlwaysNonNullPointer` so `-Wtautological-pointer-compare` and `-Wpointer-bool-conversion` fire for it, as they already do for a bare function name. Fixes #<!-- -->46362 cc @<!-- -->Endilll @<!-- -->shafik --- Full diff: https://github.com/llvm/llvm-project/pull/204944.diff 3 Files Affected: - (modified) clang/lib/Sema/SemaChecking.cpp (+9) - (modified) clang/test/SemaCXX/warn-bool-conversion.cpp (+9) - (modified) clang/test/SemaCXX/warn-tautological-compare.cpp (+19) ``````````diff diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index b8a3f48a32f24..552f6842f8a5f 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -14256,6 +14256,11 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E, } QualType T = D->getType(); + // A reference to a function is never null either; look through it. + const bool IsFunctionReference = + T->isReferenceType() && T->getPointeeType()->isFunctionType(); + if (IsFunctionReference) + T = T->getPointeeType(); const bool IsArray = T->isArrayType(); const bool IsFunction = T->isFunctionType(); @@ -14294,6 +14299,10 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E, if (!IsFunction) return; + // The fix-it notes below only apply to a bare function name, not a reference. + if (IsFunctionReference) + return; + // Suggest '&' to silence the function warning. Diag(E->getExprLoc(), diag::note_function_warning_silence) << FixItHint::CreateInsertion(E->getBeginLoc(), "&"); diff --git a/clang/test/SemaCXX/warn-bool-conversion.cpp b/clang/test/SemaCXX/warn-bool-conversion.cpp index 18c35776b17bc..8cf2a7a5816f5 100644 --- a/clang/test/SemaCXX/warn-bool-conversion.cpp +++ b/clang/test/SemaCXX/warn-bool-conversion.cpp @@ -132,6 +132,15 @@ void bar() { b = S2::f4; if (S2::f4) {} } + +// GH46362: a reference to a function is never null, like a bare function name. +void func_ref(void (&f)(), int *&ptr) { + bool b; + b = f; // expected-warning {{address of function 'f' will always evaluate to 'true'}} + if (f) {} // expected-warning {{address of function 'f' will always evaluate to 'true'}} + b = ptr; + if (ptr) {} +} } namespace Array { diff --git a/clang/test/SemaCXX/warn-tautological-compare.cpp b/clang/test/SemaCXX/warn-tautological-compare.cpp index 7d5b4b14e9981..3028a9cf935cd 100644 --- a/clang/test/SemaCXX/warn-tautological-compare.cpp +++ b/clang/test/SemaCXX/warn-tautological-compare.cpp @@ -110,6 +110,25 @@ namespace FunctionCompare { } } +namespace FunctionReferenceCompare { + // GH46362: a reference to a function is never null, like a bare function name. + // No fix-it note is emitted, since prefixing '&' would not silence it. + void test(void (&f)(), int *&ptr) { + if (f == 0) {} + // expected-warning@-1{{comparison of function 'f' equal to a null pointer is always false}} + if (f != 0) {} + // expected-warning@-1{{comparison of function 'f' not equal to a null pointer is always true}} + if (f == nullptr) {} + // expected-warning@-1{{comparison of function 'f' equal to a null pointer is always false}} + if (nullptr != f) {} + // expected-warning@-1{{comparison of function 'f' not equal to a null pointer is always true}} + + // A reference to a pointer can be null: no warning. + if (ptr == nullptr) {} + if (ptr != nullptr) {} + } +} + namespace PointerCompare { extern int a __attribute__((weak)); int b; `````````` </details> https://github.com/llvm/llvm-project/pull/204944 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
