diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index c7b567ba7abd12be6e7887b5ea44c0501c312413..2242524cd3e20eb2edb3ed0ea894b5f23a5203a1 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -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. diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 6f2fff51683a449d528ee18421897b5c343f52d2..e6ddf37d41200de8011934fa31aea5fad3d8516c 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -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)) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 3380ed8bd6f99de5255b6959807ecf919a491fd2..01aa9efebce5a669299f83c42dbb9fb3e5a0d0b0 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 index 0000000000000000000000000000000000000000..3f3b06577d52f4acd06d4cf9e97075898e2b8a47 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr106537-1.c @@ -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 index 0000000000000000000000000000000000000000..6876adf3aab1090a9a90e454faecbd47609f341a --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr106537-2.c @@ -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 index 0000000000000000000000000000000000000000..73c9b251824d4b8e819ea2895018a91333f3c0eb --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr106537-3.c @@ -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; +}