[V3] Add warning options -W[no-]compare-distinct-pointer-types

Message ID 87pmgl94l2.fsf@oracle.com
State New, archived
Headers
Series [V3] Add warning options -W[no-]compare-distinct-pointer-types |

Commit Message

Jose E. Marchesi Aug. 27, 2022, 1:52 p.m. UTC
  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                            |  4 ++++
 gcc/c/c-typeck.cc                             |  6 ++---
 gcc/doc/invoke.texi                           |  6 +++++
 .../gcc.c-torture/compile/pr106537-1.c        | 23 +++++++++++++++++++
 .../gcc.c-torture/compile/pr106537-2.c        | 21 +++++++++++++++++
 .../gcc.c-torture/compile/pr106537-3.c        | 21 +++++++++++++++++
 6 files changed, 78 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr106537-1.c
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr106537-2.c
 create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr106537-3.c
  

Comments

Joseph Myers Aug. 30, 2022, 10:09 p.m. UTC | #1
On Sat, 27 Aug 2022, Jose E. Marchesi via Gcc-patches wrote:

> +  if (metadata + 1 > data) /* { dg-warning "comparison of distinct pointer types" } */

> +  if (metadata + 1 > data) /* { dg-warning "comparison of distinct pointer types" } */

> +  if (metadata + 1 > data) /* There shouldn't be a warning here.  */

It seems the tests are only testing the '>' comparison operator.  I think 
all six comparison operators should be tested (in particular, you're 
changing two pedwarns - separate code paths for ordered and equality 
comparisons - but the tests only appear to cover one of the two).
  

Patch

diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index f776efd39d8..729b86c0287 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1848,6 +1848,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.
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index ee891ee33c2..dc7e8514c47 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -12422,7 +12422,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)
@@ -12562,8 +12562,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))
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 6131bfa7acf..5ef9dbe4bbe 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -341,6 +341,7 @@  Objective-C and Objective-C++ Dialects}.
 -Wcast-align  -Wcast-align=strict  -Wcast-function-type  -Wcast-qual  @gol
 -Wchar-subscripts @gol
 -Wclobbered  -Wcomment @gol
+-Wcompare-distinct-pointer-types @gol
 -Wconversion  -Wno-coverage-mismatch  -Wno-cpp @gol
 -Wdangling-else  -Wdangling-pointer  -Wdangling-pointer=@var{n}  @gol
 -Wdate-time @gol
@@ -8648,6 +8649,11 @@  programs.
 Warn for variables that might be changed by @code{longjmp} or
 @code{vfork}.  This warning is also enabled by @option{-Wextra}.
 
+@item -Wcompare-distinct-pointer-types
+@opindex Wcompare-distinct-pointer-types
+Warn if pointers of distinct types are compared without a cast.  This
+warning is enabled by default.
+
 @item -Wconversion
 @opindex Wconversion
 @opindex Wno-conversion
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
index 00000000000..56c8deeb4fe
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr106537-1.c
@@ -0,0 +1,23 @@ 
+/* { dg-do compile }
+   { dg-options "" }
+   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 0;
+  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
index 00000000000..7a9b2aec0b8
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr106537-2.c
@@ -0,0 +1,21 @@ 
+/* { 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 0;
+  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
index 00000000000..dc5dd46e3cb
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr106537-3.c
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-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 0;
+  return 1;
+}