From 3f458cd9abbf99cddcded076b5e7b4049607b7b4 Mon Sep 17 00:00:00 2001
From: Amr Hesham
Date: Sat, 7 Dec 2024 18:28:09 +0100
Subject: [PATCH] [Clang] Warning as error Array Comparisons from C++26
(#118872)
Starting from C++26 the array comparison warning should converted to an
error.
Fixes: #117859
---
.../clang-tidy/checkers/misc/redundant-expression.cpp | 2 +-
clang/docs/ReleaseNotes.rst | 3 +++
clang/include/clang/Basic/DiagnosticSemaKinds.td | 5 +++++
clang/lib/Sema/SemaExpr.cpp | 4 +++-
clang/test/Sema/warn-stringcompare.c | 9 +++++----
clang/test/SemaCXX/warn-array-comparion.cpp | 6 ++++--
clang/test/SemaCXX/warn-self-comparisons.cpp | 2 ++
clang/www/cxx_status.html | 2 +-
8 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp
index 1b271630e0d1..7396d2dce76c 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -fno-delayed-template-parsing
+// RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -fno-delayed-template-parsing -Wno-array-compare-cxx26
typedef __INT64_TYPE__ I64;
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 59e3a6609123..12d8ebf3251b 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -428,6 +428,9 @@ New Compiler Flags
- The ``-Warray-compare`` warning has been added to warn about array comparison
on versions older than C++20.
+- The ``-Warray-compare-cxx26`` warning has been added to warn about array comparison
+ starting from C++26, this warning is enabled as an error by default.
+
Deprecated Compiler Flags
-------------------------
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 61dd0c53581a..f185a98720f5 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10274,6 +10274,11 @@ def warn_array_comparison : Warning<
"to compare array addresses, use unary '+' to decay operands to pointers">,
InGroup>;
+def warn_array_comparison_cxx26 : Warning<
+ "comparison between two arrays is ill-formed in C++26; "
+ "to compare array addresses, use unary '+' to decay operands to pointers">,
+ InGroup>, DefaultError;
+
def warn_stringcompare : Warning<
"result of comparison against %select{a string literal|@encode}0 is "
"unspecified (use an explicit string comparison function instead)">,
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 4ffce2c12366..14564b99de44 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -11843,7 +11843,9 @@ static void diagnoseTautologicalComparison(Sema &S, SourceLocation Loc,
RHSStripped->getType()->isArrayType()) {
auto IsDeprArrayComparionIgnored =
S.getDiagnostics().isIgnored(diag::warn_depr_array_comparison, Loc);
- auto DiagID = !S.getLangOpts().CPlusPlus20 || IsDeprArrayComparionIgnored
+ auto DiagID = S.getLangOpts().CPlusPlus26
+ ? diag::warn_array_comparison_cxx26
+ : !S.getLangOpts().CPlusPlus20 || IsDeprArrayComparionIgnored
? diag::warn_array_comparison
: diag::warn_depr_array_comparison;
S.Diag(Loc, DiagID) << LHS->getSourceRange() << RHS->getSourceRange()
diff --git a/clang/test/Sema/warn-stringcompare.c b/clang/test/Sema/warn-stringcompare.c
index 78145cf42578..44dc0a5de3a4 100644
--- a/clang/test/Sema/warn-stringcompare.c
+++ b/clang/test/Sema/warn-stringcompare.c
@@ -1,5 +1,6 @@
// RUN: %clang_cc1 -x c -fsyntax-only -verify %s
// RUN: %clang_cc1 -x c++ -fsyntax-only -verify=expected,cxx %s
+// RUN: %clang_cc1 -x c++ -std=c++26 -fsyntax-only -verify=expected,cxx26 %s
#define DELIM "/"
#define DOT "."
@@ -15,15 +16,15 @@ void test(const char *d) {
if (NULL == "/")
return;
if ("/" != DELIM) // expected-warning {{result of comparison against a string literal is unspecified (use an explicit string comparison function instead)}}
- return; // cxx-warning@-1 {{comparison between two arrays}}
+ return; // cxx-warning@-1 {{comparison between two arrays}} cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}}
if (DELIM == "/") // expected-warning {{result of comparison against a string literal is unspecified (use an explicit string comparison function instead)}}
- return; // cxx-warning@-1 {{comparison between two arrays}}
+ return; // cxx-warning@-1 {{comparison between two arrays}} cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}}
if (DELIM != NULL)
return;
if (NULL == DELIM)
return;
if (DOT != DELIM) // expected-warning {{result of comparison against a string literal is unspecified (use an explicit string comparison function instead)}}
- return; // cxx-warning@-1 {{comparison between two arrays}}
+ return; // cxx-warning@-1 {{comparison between two arrays}} cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}}
if (DELIM == DOT) // expected-warning {{result of comparison against a string literal is unspecified (use an explicit string comparison function instead)}}
- return; // cxx-warning@-1 {{comparison between two arrays}}
+ return; // cxx-warning@-1 {{comparison between two arrays}} cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}}
}
diff --git a/clang/test/SemaCXX/warn-array-comparion.cpp b/clang/test/SemaCXX/warn-array-comparion.cpp
index a6eaaab22fc1..2bd4218f3a27 100644
--- a/clang/test/SemaCXX/warn-array-comparion.cpp
+++ b/clang/test/SemaCXX/warn-array-comparion.cpp
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s -verify=expected,not-cxx20
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -Wno-deprecated-array-compare -verify %s -verify=expected,not-cxx20
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -Wdeprecated -verify %s -verify=expected,cxx20
+// RUN: %clang_cc1 -std=c++26 -fsyntax-only -Wdeprecated -verify %s -verify=expected,cxx26
typedef struct {
char str[16];
@@ -9,13 +10,14 @@ typedef struct {
bool object_equal(const Object &obj1, const Object &obj2) {
if (obj1.str != obj2.str) // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}}
- return false;
+ return false; // cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}}
if (obj1.id != obj2.id) // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}}
- return false;
+ return false; // cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}}
return true;
}
void foo(int (&array1)[2], int (&array2)[2]) {
if (array1 == array2) { } // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}}
+ // cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}}
}
diff --git a/clang/test/SemaCXX/warn-self-comparisons.cpp b/clang/test/SemaCXX/warn-self-comparisons.cpp
index 3847c2d918bf..1ea8b971fcd5 100644
--- a/clang/test/SemaCXX/warn-self-comparisons.cpp
+++ b/clang/test/SemaCXX/warn-self-comparisons.cpp
@@ -1,6 +1,8 @@
// RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s -verify=expected,not-cxx20
// RUN: %clang_cc1 -std=c++20 -fsyntax-only -Wdeprecated -verify %s -verify=expected,cxx20
+// RUN: %clang_cc1 -std=c++26 -fsyntax-only -Wdeprecated -verify %s -verify=expected,cxx26
void f(int (&array1)[2], int (&array2)[2]) {
if (array1 == array2) { } // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}}
+ // cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}}
}
diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index fdb9807b1168..a8e79cd3475a 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -239,7 +239,7 @@ C++23, informally referred to as C++26.
| Remove Deprecated Array Comparisons from C++26 |
P2865R6 |
- No |
+ Clang 20 |
| Structured Bindings can introduce a Pack |