pestctrl created this revision.
pestctrl added a reviewer: rsmith.
pestctrl added a project: clang.

Clang is missing one of the conditions for C99 6.5.9p2, where comparison 
between pointers must either both point to incomplete types or both point to 
complete types. This patch adds an extra check to the clause where two pointers 
are of compatible types.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D79945

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaExpr.cpp
  clang/test/Sema/compare.c


Index: clang/test/Sema/compare.c
===================================================================
--- clang/test/Sema/compare.c
+++ clang/test/Sema/compare.c
@@ -405,3 +405,12 @@
   if (x == y) x = y; // no warning
   if (y == x) y = x; // no warning
 }
+
+int incomplete[];
+int complete[5];
+
+void test13() {
+  if (&incomplete < &complete) { // expected-error {{ordered comparison of 
complete and incomplete pointers}}
+    return;
+  }
+}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -11426,8 +11426,15 @@
     // C99 6.5.9p2 and C99 6.5.8p2
     if (Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(),
                                    RCanPointeeTy.getUnqualifiedType())) {
-      // Valid unless a relational comparison of function pointers
-      if (IsRelational && LCanPointeeTy->isFunctionType()) {
+      // Pointers both need to point to complete or incomplete types
+      if (LCanPointeeTy->isIncompleteType() !=
+          RCanPointeeTy->isIncompleteType()) {
+        Diag(Loc,
+             diag::err_typecheck_comparison_of_complete_and_incomplete_types)
+            << LHSType << RHSType << LHS.get()->getSourceRange()
+            << RHS.get()->getSourceRange();
+      } else if (IsRelational && LCanPointeeTy->isFunctionType()) {
+        // Valid unless a relational comparison of function pointers
         Diag(Loc, diag::ext_typecheck_ordered_comparison_of_function_pointers)
           << LHSType << RHSType << LHS.get()->getSourceRange()
           << RHS.get()->getSourceRange();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6461,6 +6461,8 @@
   "ordered comparison between pointer and zero (%0 and %1)">;
 def err_typecheck_three_way_comparison_of_pointer_and_zero : Error<
   "three-way comparison between pointer and zero">;
+def err_typecheck_comparison_of_complete_and_incomplete_types : Error<
+  "ordered comparison of complete and incomplete pointers (%0 and %1)">;
 def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
   "ordered comparison of function pointers (%0 and %1)">,
   InGroup<DiagGroup<"ordered-compare-function-pointers">>;


Index: clang/test/Sema/compare.c
===================================================================
--- clang/test/Sema/compare.c
+++ clang/test/Sema/compare.c
@@ -405,3 +405,12 @@
   if (x == y) x = y; // no warning
   if (y == x) y = x; // no warning
 }
+
+int incomplete[];
+int complete[5];
+
+void test13() {
+  if (&incomplete < &complete) { // expected-error {{ordered comparison of complete and incomplete pointers}}
+    return;
+  }
+}
Index: clang/lib/Sema/SemaExpr.cpp
===================================================================
--- clang/lib/Sema/SemaExpr.cpp
+++ clang/lib/Sema/SemaExpr.cpp
@@ -11426,8 +11426,15 @@
     // C99 6.5.9p2 and C99 6.5.8p2
     if (Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(),
                                    RCanPointeeTy.getUnqualifiedType())) {
-      // Valid unless a relational comparison of function pointers
-      if (IsRelational && LCanPointeeTy->isFunctionType()) {
+      // Pointers both need to point to complete or incomplete types
+      if (LCanPointeeTy->isIncompleteType() !=
+          RCanPointeeTy->isIncompleteType()) {
+        Diag(Loc,
+             diag::err_typecheck_comparison_of_complete_and_incomplete_types)
+            << LHSType << RHSType << LHS.get()->getSourceRange()
+            << RHS.get()->getSourceRange();
+      } else if (IsRelational && LCanPointeeTy->isFunctionType()) {
+        // Valid unless a relational comparison of function pointers
         Diag(Loc, diag::ext_typecheck_ordered_comparison_of_function_pointers)
           << LHSType << RHSType << LHS.get()->getSourceRange()
           << RHS.get()->getSourceRange();
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -6461,6 +6461,8 @@
   "ordered comparison between pointer and zero (%0 and %1)">;
 def err_typecheck_three_way_comparison_of_pointer_and_zero : Error<
   "three-way comparison between pointer and zero">;
+def err_typecheck_comparison_of_complete_and_incomplete_types : Error<
+  "ordered comparison of complete and incomplete pointers (%0 and %1)">;
 def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
   "ordered comparison of function pointers (%0 and %1)">,
   InGroup<DiagGroup<"ordered-compare-function-pointers">>;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to