Skip to content

[Clang] Warning as error Array Comparisons from C++26 #118872

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Dec 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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;

Expand Down
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------------------------

Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -10274,6 +10274,11 @@ def warn_array_comparison : Warning<
"to compare array addresses, use unary '+' to decay operands to pointers">,
InGroup<DiagGroup<"array-compare">>;

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<DiagGroup<"array-compare-cxx26">>, DefaultError;

def warn_stringcompare : Warning<
"result of comparison against %select{a string literal|@encode}0 is "
"unspecified (use an explicit string comparison function instead)">,
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
9 changes: 5 additions & 4 deletions clang/test/Sema/warn-stringcompare.c
Original file line number Diff line number Diff line change
@@ -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 "."
Expand All @@ -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}}
}
6 changes: 4 additions & 2 deletions clang/test/SemaCXX/warn-array-comparion.cpp
Original file line number Diff line number Diff line change
@@ -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];
Expand All @@ -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}}
}
2 changes: 2 additions & 0 deletions clang/test/SemaCXX/warn-self-comparisons.cpp
Original file line number Diff line number Diff line change
@@ -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}}
}
2 changes: 1 addition & 1 deletion clang/www/cxx_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ <h2 id="cxx26">C++2c implementation status</h2>
<tr>
<td>Remove Deprecated Array Comparisons from C++26</td>
<td><a href="https://wg21.link/P2865R6">P2865R6</a></td>
<td class="none" align="center">No</td>
<td class="unreleased" align="center">Clang 20</td>
</tr>
<tr>
<td>Structured Bindings can introduce a Pack</td>
Expand Down
Loading