adriandole created this revision.
Herald added a project: All.
adriandole requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
Using `icf=all` with lld can cause comparisons between function pointers that 
previously compared as unequal to compare as equal. This warning is disabled by 
default, since it's only relevant if ICF is explicitly enabled.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D141310

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaExpr.cpp
  clang/test/SemaCXX/compare-function-pointer.cpp


Index: clang/test/SemaCXX/compare-function-pointer.cpp
===================================================================
--- clang/test/SemaCXX/compare-function-pointer.cpp
+++ clang/test/SemaCXX/compare-function-pointer.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify 
-Wcompare-function-pointers %s
 
 using fp0_t = void (*)();
 using fp1_t = int (*)();
@@ -6,16 +6,16 @@
 extern fp0_t a, b;
 extern fp1_t c;
 
-bool eq0 = a == b;
-bool ne0 = a != b;
+bool eq0 = a == b;  // expected-warning {{comparison of function pointers}}
+bool ne0 = a != b;  // expected-warning {{comparison of function pointers}}
 bool lt0 = a < b;   // expected-warning {{ordered comparison of function 
pointers ('fp0_t' (aka 'void (*)()') and 'fp0_t')}}
 bool le0 = a <= b;  // expected-warning {{ordered comparison of function 
pointers}}
 bool gt0 = a > b;   // expected-warning {{ordered comparison of function 
pointers}}
 bool ge0 = a >= b;  // expected-warning {{ordered comparison of function 
pointers}}
 auto tw0 = a <=> b; // expected-error {{ordered comparison of function 
pointers}}
 
-bool eq1 = a == c;  // expected-error {{comparison of distinct pointer types}}
-bool ne1 = a != c;  // expected-error {{comparison of distinct pointer types}}
+bool eq1 = a == c;  // expected-error {{comparison of distinct pointer types}} 
expected-warning {{comparison of function pointers}}
+bool ne1 = a != c;  // expected-error {{comparison of distinct pointer types}} 
expected-warning {{comparison of function pointers}}
 bool lt1 = a < c;   // expected-warning {{ordered comparison of function 
pointers ('fp0_t' (aka 'void (*)()') and 'fp1_t' (aka 'int (*)()'))}}
                     // expected-error@-1 {{comparison of distinct pointer 
types}}
 bool le1 = a <= c;  // expected-warning {{ordered comparison of function 
pointers}}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -12711,6 +12711,13 @@
                                    LHS.get()->getSourceRange());
   }
 
+  if (!IsOrdered && LHSType->isFunctionPointerType() &&
+      RHSType->isFunctionPointerType() && !LHSIsNull && !RHSIsNull) {
+    Diag(Loc, diag::warn_typecheck_comparison_of_function_pointers)
+          << LHSType << 0
+          << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
+  }
+
   if (IsOrdered && LHSType->isFunctionPointerType() &&
       RHSType->isFunctionPointerType()) {
     // Valid unless a relational comparison of function pointers
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7002,6 +7002,9 @@
   "%0 is %select{|in}2complete and "
   "%1 is %select{|in}3complete">,
   InGroup<C11>;
+def warn_typecheck_comparison_of_function_pointers : Warning<
+  "comparison of function pointers (%0 and %1)">,
+  InGroup<CompareFunctionPointers>, DefaultIgnore;
 def warn_typecheck_ordered_comparison_of_function_pointers : Warning<
   "ordered comparison of function pointers (%0 and %1)">,
   InGroup<OrderedCompareFunctionPointers>;
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -561,6 +561,7 @@
 def UnderalignedExceptionObject : DiagGroup<"underaligned-exception-object">;
 def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">;
 def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
+def CompareFunctionPointers : DiagGroup<"compare-function-pointers">;
 def OrderedCompareFunctionPointers : 
DiagGroup<"ordered-compare-function-pointers">;
 def PackedNonPod : DiagGroup<"packed-non-pod">;
 def Packed : DiagGroup<"packed", [PackedNonPod]>;


Index: clang/test/SemaCXX/compare-function-pointer.cpp
===================================================================
--- clang/test/SemaCXX/compare-function-pointer.cpp
+++ clang/test/SemaCXX/compare-function-pointer.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++20 -verify -Wcompare-function-pointers %s
 
 using fp0_t = void (*)();
 using fp1_t = int (*)();
@@ -6,16 +6,16 @@
 extern fp0_t a, b;
 extern fp1_t c;
 
-bool eq0 = a == b;
-bool ne0 = a != b;
+bool eq0 = a == b;  // expected-warning {{comparison of function pointers}}
+bool ne0 = a != b;  // expected-warning {{comparison of function pointers}}
 bool lt0 = a < b;   // expected-warning {{ordered comparison of function pointers ('fp0_t' (aka 'void (*)()') and 'fp0_t')}}
 bool le0 = a <= b;  // expected-warning {{ordered comparison of function pointers}}
 bool gt0 = a > b;   // expected-warning {{ordered comparison of function pointers}}
 bool ge0 = a >= b;  // expected-warning {{ordered comparison of function pointers}}
 auto tw0 = a <=> b; // expected-error {{ordered comparison of function pointers}}
 
-bool eq1 = a == c;  // expected-error {{comparison of distinct pointer types}}
-bool ne1 = a != c;  // expected-error {{comparison of distinct pointer types}}
+bool eq1 = a == c;  // expected-error {{comparison of distinct pointer types}} expected-warning {{comparison of function pointers}}
+bool ne1 = a != c;  // expected-error {{comparison of distinct pointer types}} expected-warning {{comparison of function pointers}}
 bool lt1 = a < c;   // expected-warning {{ordered comparison of function pointers ('fp0_t' (aka 'void (*)()') and 'fp1_t' (aka 'int (*)()'))}}
                     // expected-error@-1 {{comparison of distinct pointer types}}
 bool le1 = a <= c;  // expected-warning {{ordered comparison of function pointers}}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -12711,6 +12711,13 @@
                                    LHS.get()->getSourceRange());
   }
 
+  if (!IsOrdered && LHSType->isFunctionPointerType() &&
+      RHSType->isFunctionPointerType() && !LHSIsNull && !RHSIsNull) {
+    Diag(Loc, diag::warn_typecheck_comparison_of_function_pointers)
+          << LHSType << 0
+          << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
+  }
+
   if (IsOrdered && LHSType->isFunctionPointerType() &&
       RHSType->isFunctionPointerType()) {
     // Valid unless a relational comparison of function pointers
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -7002,6 +7002,9 @@
   "%0 is %select{|in}2complete and "
   "%1 is %select{|in}3complete">,
   InGroup<C11>;
+def warn_typecheck_comparison_of_function_pointers : Warning<
+  "comparison of function pointers (%0 and %1)">,
+  InGroup<CompareFunctionPointers>, DefaultIgnore;
 def warn_typecheck_ordered_comparison_of_function_pointers : Warning<
   "ordered comparison of function pointers (%0 and %1)">,
   InGroup<OrderedCompareFunctionPointers>;
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -561,6 +561,7 @@
 def UnderalignedExceptionObject : DiagGroup<"underaligned-exception-object">;
 def DeprecatedObjCIsaUsage : DiagGroup<"deprecated-objc-isa-usage">;
 def ExplicitInitializeCall : DiagGroup<"explicit-initialize-call">;
+def CompareFunctionPointers : DiagGroup<"compare-function-pointers">;
 def OrderedCompareFunctionPointers : DiagGroup<"ordered-compare-function-pointers">;
 def PackedNonPod : DiagGroup<"packed-non-pod">;
 def Packed : DiagGroup<"packed", [PackedNonPod]>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to