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

Reply via email to