Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
PR c++/97573
gcc/c-family/ChangeLog:
* c-opts.c (c_common_post_options): In C++20, turn on
-Wdeprecated-array-compare.
* c.opt (Wdeprecated-array-compare): New option.
gcc/cp/ChangeLog:
* typeck.c (do_warn_deprecated_array_compare): New.
(cp_build_binary_op): Call it for equality and relational comparisons.
gcc/ChangeLog:
* doc/invoke.texi: Document -Wdeprecated-array-compare.
gcc/testsuite/ChangeLog:
* g++.dg/tree-ssa/pr15791-1.C: Add dg-warning.
* g++.dg/cpp2a/array-comp1.C: New test.
* g++.dg/cpp2a/array-comp2.C: New test.
* g++.dg/cpp2a/array-comp3.C: New test.
---
gcc/c-family/c-opts.c | 5 ++++
gcc/c-family/c.opt | 4 +++
gcc/cp/typeck.c | 28 +++++++++++++++++++
gcc/doc/invoke.texi | 19 ++++++++++++-
gcc/testsuite/g++.dg/cpp2a/array-comp1.C | 34 +++++++++++++++++++++++
gcc/testsuite/g++.dg/cpp2a/array-comp2.C | 31 +++++++++++++++++++++
gcc/testsuite/g++.dg/cpp2a/array-comp3.C | 29 +++++++++++++++++++
gcc/testsuite/g++.dg/tree-ssa/pr15791-1.C | 2 +-
8 files changed, 150 insertions(+), 2 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp2a/array-comp1.C
create mode 100644 gcc/testsuite/g++.dg/cpp2a/array-comp2.C
create mode 100644 gcc/testsuite/g++.dg/cpp2a/array-comp3.C
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 3eaab5e1530..00b52cc5e12 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -962,6 +962,11 @@ c_common_post_options (const char **pfilename)
warn_deprecated_enum_float_conv,
cxx_dialect >= cxx20 && warn_deprecated);
+ /* -Wdeprecated-array-compare is enabled by default in C++20. */
+ SET_OPTION_IF_UNSET (&global_options, &global_options_set,
+ warn_deprecated_array_compare,
+ cxx_dialect >= cxx20 && warn_deprecated);
+
/* Declone C++ 'structors if -Os. */
if (flag_declone_ctor_dtor == -1)
flag_declone_ctor_dtor = optimize_size;
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 9c151d19870..a4f0ea68594 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -540,6 +540,10 @@ Wdeprecated
C C++ ObjC ObjC++ CPP(cpp_warn_deprecated) CppReason(CPP_W_DEPRECATED)
; Documented in common.opt
+Wdeprecated-array-compare
+C++ ObjC++ Var(warn_deprecated_array_compare) Warning
+Warn about deprecated comparisons between two operands of array type.
+
Wdeprecated-copy
C++ ObjC++ Var(warn_deprecated_copy) Warning LangEnabledBy(C++ ObjC++,
Wextra)
Mark implicitly-declared copy operations as deprecated if the class has a
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index a2398dbe660..1e3a41104d6 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -40,6 +40,7 @@ along with GCC; see the file COPYING3. If not see
#include "attribs.h"
#include "asan.h"
#include "gimplify.h"
+#include "tree-pretty-print.h"
static tree cp_build_addr_expr_strict (tree, tsubst_flags_t);
static tree cp_build_function_call (tree, tree, tsubst_flags_t);
@@ -4725,6 +4726,21 @@ do_warn_enum_conversions (location_t loc, enum tree_code
code, tree type0,
}
}
+/* Warn about C++20 [depr.array.comp] array comparisons: "Equality
+ and relational comparisons between two operands of array type are
+ deprecated." */
+
+static inline void
+do_warn_deprecated_array_compare (location_t location, tree_code code,
+ tree op0, tree op1)
+{
+ if (warning_at (location, OPT_Wdeprecated_array_compare,
+ "comparison between two arrays is deprecated"))
+ 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);
+}
+
/* Build a binary-operation expression without default conversions.
CODE is the kind of expression to build.
LOCATION is the location_t of the operator in the source code.
@@ -5289,6 +5305,11 @@ cp_build_binary_op (const op_location_t &location,
warning_at (location, OPT_Waddress,
"comparison with string literal results in "
"unspecified behavior");
+ else if (TREE_CODE (TREE_TYPE (orig_op0)) == ARRAY_TYPE
+ && TREE_CODE (TREE_TYPE (orig_op1)) == ARRAY_TYPE)
+ do_warn_deprecated_array_compare (location, code,
+ stripped_orig_op0,
+ stripped_orig_op1);
}
build_type = boolean_type_node;
@@ -5559,6 +5580,13 @@ cp_build_binary_op (const op_location_t &location,
"comparison with string literal results "
"in unspecified behavior");
}
+ else if (TREE_CODE (TREE_TYPE (orig_op0)) == ARRAY_TYPE
+ && TREE_CODE (TREE_TYPE (orig_op1)) == ARRAY_TYPE
+ && code != SPACESHIP_EXPR