]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Add warning options -W[no-]compare-distinct-pointer-types
authorJose E. Marchesi <jose.marchesi@oracle.com>
Thu, 17 Aug 2023 13:36:26 +0000 (15:36 +0200)
committerJose E. Marchesi <jose.marchesi@oracle.com>
Thu, 17 Aug 2023 15:35:57 +0000 (17:35 +0200)
GCC emits pedwarns unconditionally when comparing pointers of
different types, for example:

  int xdp_context (struct xdp_md *xdp)
    {
        void *data = (void *)(long)xdp->data;
        __u32 *metadata = (void *)(long)xdp->data_meta;
        __u32 ret;

        if (metadata + 1 > data)
          return 0;
        return 1;
   }

  /home/jemarch/foo.c: In function ‘xdp_context’:
  /home/jemarch/foo.c:15:20: warning: comparison of distinct pointer types lacks a cast
         15 |   if (metadata + 1 > data)
                 |                    ^

LLVM supports an option -W[no-]compare-distinct-pointer-types that can
be used in order to enable or disable the emission of such warnings.
It is enabled by default.

This patch adds the same options to GCC.

Documentation and testsuite updated included.
Regtested in x86_64-linu-gnu.
No regressions observed.

gcc/ChangeLog:

PR c/106537
* doc/invoke.texi (Option Summary): Mention
-Wcompare-distinct-pointer-types under `Warning Options'.
(Warning Options): Document -Wcompare-distinct-pointer-types.

gcc/c-family/ChangeLog:

PR c/106537
* c.opt (Wcompare-distinct-pointer-types): New option.

gcc/c/ChangeLog:

PR c/106537
* c-typeck.cc (build_binary_op): Warning on comparing distinct
pointer types only when -Wcompare-distinct-pointer-types.

gcc/testsuite/ChangeLog:

PR c/106537
* gcc.c-torture/compile/pr106537-1.c: New test.
* gcc.c-torture/compile/pr106537-2.c: Likewise.
* gcc.c-torture/compile/pr106537-3.c: Likewise.

gcc/c-family/c.opt
gcc/c/c-typeck.cc
gcc/doc/invoke.texi
gcc/testsuite/gcc.c-torture/compile/pr106537-1.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/pr106537-2.c [new file with mode: 0644]
gcc/testsuite/gcc.c-torture/compile/pr106537-3.c [new file with mode: 0644]

index c7b567ba7abd12be6e7887b5ea44c0501c312413..2242524cd3e20eb2edb3ed0ea894b5f23a5203a1 100644 (file)
@@ -1935,6 +1935,10 @@ Winvalid-imported-macros
 C++ ObjC++ Var(warn_imported_macros) Warning
 Warn about macros that have conflicting header units definitions.
 
+Wcompare-distinct-pointer-types
+C ObjC Var(warn_compare_distinct_pointer_types) Warning Init(1)
+Warn if pointers of distinct types are compared without a cast.
+
 flang-info-include-translate
 C++ Var(note_include_translate_yes)
 Note #include directives translated to import declarations.
index 6f2fff51683a449d528ee18421897b5c343f52d2..e6ddf37d41200de8011934fa31aea5fad3d8516c 100644 (file)
@@ -12772,7 +12772,7 @@ build_binary_op (location_t location, enum tree_code code,
          else
            /* Avoid warning about the volatile ObjC EH puts on decls.  */
            if (!objc_ok)
-             pedwarn (location, 0,
+             pedwarn (location, OPT_Wcompare_distinct_pointer_types,
                       "comparison of distinct pointer types lacks a cast");
 
          if (result_type == NULL_TREE)
@@ -12912,8 +12912,8 @@ build_binary_op (location_t location, enum tree_code code,
              int qual = ENCODE_QUAL_ADDR_SPACE (as_common);
              result_type = build_pointer_type
                              (build_qualified_type (void_type_node, qual));
-             pedwarn (location, 0,
-                      "comparison of distinct pointer types lacks a cast");
+              pedwarn (location, OPT_Wcompare_distinct_pointer_types,
+                       "comparison of distinct pointer types lacks a cast");
            }
        }
       else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
index 3380ed8bd6f99de5255b6959807ecf919a491fd2..01aa9efebce5a669299f83c42dbb9fb3e5a0d0b0 100644 (file)
@@ -345,6 +345,7 @@ Objective-C and Objective-C++ Dialects}.
 -Wcast-align  -Wcast-align=strict  -Wcast-function-type  -Wcast-qual
 -Wchar-subscripts
 -Wclobbered  -Wcomment
+-Wcompare-distinct-pointer-types
 -Wno-complain-wrong-lang
 -Wconversion  -Wno-coverage-mismatch  -Wno-cpp
 -Wdangling-else  -Wdangling-pointer  -Wdangling-pointer=@var{n}
@@ -9106,6 +9107,11 @@ The latter front end diagnoses
 @samp{f951: Warning: command-line option '-fno-rtti' is valid for C++/D/ObjC++ but not for Fortran},
 which may be disabled with @option{-Wno-complain-wrong-lang}.
 
+@opindex Wcompare-distinct-pointer-types
+@item -Wcompare-distinct-pointer-types @r{(C and Objective-C only)}
+Warn if pointers of distinct types are compared without a cast.  This
+warning is enabled by default.
+
 @opindex Wconversion
 @opindex Wno-conversion
 @item -Wconversion
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr106537-1.c b/gcc/testsuite/gcc.c-torture/compile/pr106537-1.c
new file mode 100644 (file)
index 0000000..3f3b065
--- /dev/null
@@ -0,0 +1,34 @@
+/* { dg-do compile }
+   { dg-options "-O0" }
+   This testcase checks that warn_compare_distinct_pointer_types is enabled by
+   default.  */
+
+typedef int __u32;
+
+struct xdp_md
+{
+  char *data;
+  char *data_meta;
+};
+
+int xdp_context (struct xdp_md *xdp)
+{
+  void *data = (void *)(long)xdp->data;
+  __u32 *metadata = (void *)(long)xdp->data_meta;
+  __u32 ret;
+
+  if (metadata + 1 > data) /* { dg-warning "comparison of distinct pointer types" } */
+    return 1;
+  if (metadata + 1 >= data) /* { dg-warning "comparison of distinct pointer types" } */
+    return 2;
+  if (metadata + 1 < data) /* { dg-warning "comparison of distinct pointer types" } */
+    return 3;
+  if (metadata + 1 <= data) /* { dg-warning "comparison of distinct pointer types" } */
+    return 4;
+  if (metadata + 1 == data) /* { dg-warning "comparison of distinct pointer types" } */
+    return 5;
+  if (metadata + 1 != data) /* { dg-warning "comparison of distinct pointer types" } */
+    return 5;
+
+  return 1;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr106537-2.c b/gcc/testsuite/gcc.c-torture/compile/pr106537-2.c
new file mode 100644 (file)
index 0000000..6876adf
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-Wcompare-distinct-pointer-types" } */
+
+typedef int __u32;
+
+struct xdp_md
+{
+  char *data;
+  char *data_meta;
+};
+
+int xdp_context (struct xdp_md *xdp)
+{
+  void *data = (void *)(long)xdp->data;
+  __u32 *metadata = (void *)(long)xdp->data_meta;
+  __u32 ret;
+
+  if (metadata + 1 > data) /* { dg-warning "comparison of distinct pointer types" } */
+    return 1;
+  if (metadata + 1 >= data) /* { dg-warning "comparison of distinct pointer types" } */
+    return 2;
+  if (metadata + 1 < data) /* { dg-warning "comparison of distinct pointer types" } */
+    return 3;
+  if (metadata + 1 <= data) /* { dg-warning "comparison of distinct pointer types" } */
+    return 4;
+  if (metadata + 1 == data) /* { dg-warning "comparison of distinct pointer types" } */
+    return 5;
+  if (metadata + 1 != data) /* { dg-warning "comparison of distinct pointer types" } */
+    return 5;
+
+  return 1;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr106537-3.c b/gcc/testsuite/gcc.c-torture/compile/pr106537-3.c
new file mode 100644 (file)
index 0000000..73c9b25
--- /dev/null
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -Wno-compare-distinct-pointer-types" } */
+
+typedef int __u32;
+
+struct xdp_md
+{
+  char *data;
+  char *data_meta;
+};
+
+int xdp_context (struct xdp_md *xdp)
+{
+  void *data = (void *)(long)xdp->data;
+  __u32 *metadata = (void *)(long)xdp->data_meta;
+  __u32 ret;
+
+  if (metadata + 1 > data) /* There shouldn't be a warning here.  */
+    return 1;
+  if (metadata + 1 >= data) /* There shouldn't be a warning here. */
+    return 2;
+  if (metadata + 1 < data) /* There shouldn't be a warning here.  */
+    return 3;
+  if (metadata + 1 <= data) /* There shouldn't be a warning here.  */
+    return 4;
+  if (metadata + 1 == data) /* There shouldn't be a warning here.  */
+    return 5;
+  if (metadata + 1 != data) /* There shouldn't be a warning here.  */
+    return 5;
+
+  return 1;
+}