diff options
author | Marek Polacek <polacek@redhat.com> | 2021-09-29 11:45:24 -0400 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2021-10-04 12:33:57 -0400 |
commit | 2dda00b734888d3b53ac91160083b5c6cd5ca5c8 (patch) | |
tree | 979400d2829948a66cb67287d39474967cadb837 /gcc/c-family/c-warn.c | |
parent | d362b91fa655fb02a4214e28eb33b8b60a0e1ace (diff) | |
download | gcc-2dda00b734888d3b53ac91160083b5c6cd5ca5c8.zip gcc-2dda00b734888d3b53ac91160083b5c6cd5ca5c8.tar.gz gcc-2dda00b734888d3b53ac91160083b5c6cd5ca5c8.tar.bz2 |
c-family: Implement -Warray-compare [PR97573]
This patch addresses one of my leftovers from GCC 11. C++20 introduced
[depr.array.comp]: "Equality and relational comparisons between two operands
of array type are deprecated." so this patch adds -Warray-compare. Since the
code in question is dubious (the comparison doesn't actually compare the array
elements), I've added this warning for C too, and enabled it in all C++ modes.
PR c++/97573
gcc/c-family/ChangeLog:
* c-common.h (do_warn_array_compare): Declare.
* c-warn.c (do_warn_array_compare): New.
* c.opt (Warray-compare): New option.
gcc/c/ChangeLog:
* c-typeck.c (parser_build_binary_op): Call do_warn_array_compare.
gcc/cp/ChangeLog:
* typeck.c (cp_build_binary_op): Call do_warn_array_compare.
gcc/ChangeLog:
* doc/invoke.texi: Document -Warray-compare.
gcc/testsuite/ChangeLog:
* c-c++-common/Warray-compare-1.c: New test.
* c-c++-common/Warray-compare-2.c: New test.
Diffstat (limited to 'gcc/c-family/c-warn.c')
-rw-r--r-- | gcc/c-family/c-warn.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index 84ad663..99cde4a 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -3726,3 +3726,35 @@ maybe_warn_sizeof_array_div (location_t loc, tree arr, tree arr_type, } } } + +/* Warn about C++20 [depr.array.comp] array comparisons: "Equality + and relational comparisons between two operands of array type are + deprecated." We also warn in C and earlier C++ standards. CODE is + the code for this comparison, OP0 and OP1 are the operands. */ + +void +do_warn_array_compare (location_t location, tree_code code, tree op0, tree op1) +{ + STRIP_NOPS (op0); + STRIP_NOPS (op1); + if (TREE_CODE (op0) == ADDR_EXPR) + op0 = TREE_OPERAND (op0, 0); + if (TREE_CODE (op1) == ADDR_EXPR) + op1 = TREE_OPERAND (op1, 0); + + auto_diagnostic_group d; + if (warning_at (location, OPT_Warray_compare, + (c_dialect_cxx () && cxx_dialect >= cxx20) + ? G_("comparison between two arrays is deprecated in C++20") + : G_("comparison between two arrays"))) + { + /* C doesn't allow +arr. */ + if (c_dialect_cxx ()) + inform (location, "use unary %<+%> which decays operands to pointers " + "or %<&%D[0] %s &%D[0]%> to compare the addresses", + op0, op_symbol_code (code), op1); + else + inform (location, "use %<&%D[0] %s &%D[0]%> to compare the addresses", + op0, op_symbol_code (code), op1); + } +} |