Skip to content
Open
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
2 changes: 2 additions & 0 deletions src/error_msg.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3679,5 +3679,7 @@ ec_exp_interpolator;;"expected an interpolator (\"\\[\", \"\\[:\", \"\\{\", \"\\
ec_interpolated_id_is_not_identifier;;"%sq does not spell an identifier"
ec_interpolated_operand_is_not_token_sequence;;"the operand of a \"\\{...}\" interpolator is not a token sequence"
ec_tag_redefined_differently;;"this declaration of %n does not declare the same type as the declaration %p"
ec_array_comparison_deprecated;;"comparison between two arrays is deprecated"
ec_array_comparison_not_allowed;;"comparison between two arrays is not allowed"
###############################################################################

26 changes: 26 additions & 0 deletions src/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -32399,6 +32399,30 @@ different enum types (or, in C, have different affiliated enum types).
} /* diagnose_comparison_if_different_enum_types */


static void check_for_array_comparison(an_operand *opnd1,
an_operand *opnd2,
a_source_position *operator_pos)
/*
opnd1 and opnd2 are the operands of a built-in equality or relational
operator at operator_pos, before the array-to-pointer conversion. If both
have array type, issue a diagnostic: such comparisons are deprecated in C++20
and not allowed in C++26 (P2865).
*/
{
if (cpp20_mode && is_array_type(opnd1->type) &&
is_array_type(opnd2->type)) {
if (cpp26_mode && !gpp_version_is(<150000) &&
!clangcpp_version_is(<200000)) {
/* GCC 15 and Clang 20 implement P2865. Earlier versions only issue a
deprecation warning. */
expr_pos_error(ec_array_comparison_not_allowed, operator_pos);
} else {
expr_pos_warning(ec_array_comparison_deprecated, operator_pos);
} /* if */
} /* if */
} /* check_for_array_comparison */


static void process_rel_operator(an_operand *opnd1,
an_operand *opnd2,
a_token_kind operator_token,
Expand Down Expand Up @@ -32444,6 +32468,7 @@ describe the location of the operator.
} /* if */
if (!processed) {
/* Non-operator-function cases. */
check_for_array_comparison(opnd1, opnd2, operator_pos);
/* The first operand must be an arithmetic or enum type or a pointer. */
do_operand_transformations(opnd1, TOPT_NO_OPTIONS);
opnd1_is_pointer = FALSE;
Expand Down Expand Up @@ -32948,6 +32973,7 @@ operator_tsn describe the location of the operator.
} /* if */
if (!processed) {
/* Non-operator-function cases. */
check_for_array_comparison(opnd1, opnd2, operator_pos);
/* The first operand must be an arithmetic or enum type or a pointer. */
do_operand_transformations(opnd1, TOPT_NO_OPTIONS);
if (is_arithmetic_or_enum_type(opnd1->type)) {
Expand Down
12 changes: 12 additions & 0 deletions src/pending_changes/gh-370-array-comparisons.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[GH #370]
C++26: comparison between two arrays is not allowed

A comparison between two arrays using an equality or relational operator is
deprecated in C++20 and not allowed in C++26 (P2865). The front end did not
diagnose it. It is now a warning in C++20 and C++23, and an error in C++26
(only a warning when emulating GCC versions before 15 or Clang versions before
20, which do the same). For example, with --c++26:

int a[2], b[2];
bool x = a == b; // Now an error.
bool y = a == &b[0]; // Okay: one operand is a pointer.
2 changes: 0 additions & 2 deletions tests/expectations/edg_x86_64/imported.log
Original file line number Diff line number Diff line change
Expand Up @@ -1443,7 +1443,6 @@ clang/cpp/SemaCXX/vtordisp-mode.sft.cpp:fp:-DTEST_NUMBER=3 --c++11 -DVTORDISP_MO
clang/cpp/SemaCXX/warn-array-comparion.sft.cpp:fn:-DTEST_NUMBER=1 --c++17:FAIL:
clang/cpp/SemaCXX/warn-array-comparion.sft.cpp:fn:-DTEST_NUMBER=2 --c++20:FAIL:
clang/cpp/SemaCXX/warn-array-comparion.sft.cpp:fn:-DTEST_NUMBER=3 --c++20:FAIL:
clang/cpp/SemaCXX/warn-array-comparion.sft.cpp:fn:-DTEST_NUMBER=4 --c++26:FAIL:
clang/cpp/SemaCXX/warn-bool-conversion.sft.cpp:fn:-DTEST_NUMBER=1 --c++03:FAIL:
clang/cpp/SemaCXX/warn-cast-function-type-strict.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:
clang/cpp/SemaCXX/warn-cast-function-type.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:
Expand All @@ -1455,7 +1454,6 @@ clang/cpp/SemaCXX/warn-memsize-comparison.sft.cpp:fn:-DTEST_NUMBER=1:FAIL:
clang/cpp/SemaCXX/warn-nrvo.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:
clang/cpp/SemaCXX/warn-self-comparisons.sft.cpp:fn:-DTEST_NUMBER=1 --c++17:FAIL:
clang/cpp/SemaCXX/warn-self-comparisons.sft.cpp:fn:-DTEST_NUMBER=2 --c++20:FAIL:
clang/cpp/SemaCXX/warn-self-comparisons.sft.cpp:fn:-DTEST_NUMBER=3 --c++26:FAIL:
clang/cpp/SemaCXX/warn-static-const-float.sft.cpp:fn:-DTEST_NUMBER=1 --c++03 -DEXT --c++03 -DNONE --c++03 -DNONE --c++03 -DNONE:FAIL:
clang/cpp/SemaCXX/warn-static-const-float.sft.cpp:fn:-DTEST_NUMBER=2 --c++11 -DERR:FAIL:
clang/cpp/SemaCXX/warn-static-const-float.sft.cpp:fn:-DTEST_NUMBER=3 --c++11 -DERR:FAIL:
Expand Down
18 changes: 18 additions & 0 deletions tests/tests/changes/.GH370.rto/default.1.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
fe_only -DTEST_NUMBER=1 --c++26 Test_name.c
"Test_name.c", line 10: error: comparison between two arrays is not allowed
bool x1 = a == b; // Two arrays: diagnosed.
^

"Test_name.c", line 11: error: comparison between two arrays is not allowed
bool x2 = a != b;
^

"Test_name.c", line 12: error: comparison between two arrays is not allowed
bool x3 = a < b;
^

"Test_name.c", line 13: error: comparison between two arrays is not allowed
bool x4 = a >= b;
^

4 errors detected in the compilation of "Test_name.c".
18 changes: 18 additions & 0 deletions tests/tests/changes/.GH370.rto/default.2.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
fe_only -DTEST_NUMBER=2 --c++26 --gnu_version 150000 Test_name.c
"Test_name.c", line 10: error: comparison between two arrays is not allowed
bool x1 = a == b; // Two arrays: diagnosed.
^

"Test_name.c", line 11: error: comparison between two arrays is not allowed
bool x2 = a != b;
^

"Test_name.c", line 12: error: comparison between two arrays is not allowed
bool x3 = a < b;
^

"Test_name.c", line 13: error: comparison between two arrays is not allowed
bool x4 = a >= b;
^

4 errors detected in the compilation of "Test_name.c".
18 changes: 18 additions & 0 deletions tests/tests/changes/.GH370.rto/default.3.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
fe_only -DTEST_NUMBER=3 --c++26 --clang_version 200000 Test_name.c
"Test_name.c", line 10: error: comparison between two arrays is not allowed
bool x1 = a == b; // Two arrays: diagnosed.
^

"Test_name.c", line 11: error: comparison between two arrays is not allowed
bool x2 = a != b;
^

"Test_name.c", line 12: error: comparison between two arrays is not allowed
bool x3 = a < b;
^

"Test_name.c", line 13: error: comparison between two arrays is not allowed
bool x4 = a >= b;
^

4 errors detected in the compilation of "Test_name.c".
17 changes: 17 additions & 0 deletions tests/tests/changes/.GH370_a.rto/default.1.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
fe_only -DTEST_NUMBER=1 --c++20 Test_name.c
"Test_name.c", line 12: warning: comparison between two arrays is deprecated
bool x1 = a == b; // Two arrays: diagnosed.
^

"Test_name.c", line 13: warning: comparison between two arrays is deprecated
bool x2 = a != b;
^

"Test_name.c", line 14: warning: comparison between two arrays is deprecated
bool x3 = a < b;
^

"Test_name.c", line 15: warning: comparison between two arrays is deprecated
bool x4 = a >= b;
^

17 changes: 17 additions & 0 deletions tests/tests/changes/.GH370_a.rto/default.2.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
fe_only -DTEST_NUMBER=2 --c++26 --gnu_version 140000 Test_name.c
"Test_name.c", line 12: warning: comparison between two arrays is deprecated
bool x1 = a == b; // Two arrays: diagnosed.
^

"Test_name.c", line 13: warning: comparison between two arrays is deprecated
bool x2 = a != b;
^

"Test_name.c", line 14: warning: comparison between two arrays is deprecated
bool x3 = a < b;
^

"Test_name.c", line 15: warning: comparison between two arrays is deprecated
bool x4 = a >= b;
^

17 changes: 17 additions & 0 deletions tests/tests/changes/.GH370_a.rto/default.3.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
fe_only -DTEST_NUMBER=3 --c++26 --clang_version 190000 Test_name.c
"Test_name.c", line 12: warning: comparison between two arrays is deprecated
bool x1 = a == b; // Two arrays: diagnosed.
^

"Test_name.c", line 13: warning: comparison between two arrays is deprecated
bool x2 = a != b;
^

"Test_name.c", line 14: warning: comparison between two arrays is deprecated
bool x3 = a < b;
^

"Test_name.c", line 15: warning: comparison between two arrays is deprecated
bool x4 = a >= b;
^

1 change: 1 addition & 0 deletions tests/tests/changes/.GH370_a.rto/default.4.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fe_only -DTEST_NUMBER=4 --c++17 Test_name.c
16 changes: 16 additions & 0 deletions tests/tests/changes/GH370.sft.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//type:fn
//options:--c++26:--c++26 --gnu_version 150000:--c++26 --clang_version 200000
//remark:[GH #370] C++26: comparison between two arrays is not allowed
//
// P2865 makes a comparison between two arrays ill-formed in C++26.

int a[2], b[2];
int *p = b;

bool x1 = a == b; // Two arrays: diagnosed.
bool x2 = a != b;
bool x3 = a < b;
bool x4 = a >= b;

bool y1 = a == p; // Array and pointer: not diagnosed.
bool y2 = p < a;
18 changes: 18 additions & 0 deletions tests/tests/changes/GH370_a.sft.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//type:fp
//options:--c++20:--c++26 --gnu_version 140000:--c++26 --clang_version 190000:--c++17
//remark:[GH #370] Comparison between two arrays is deprecated in C++20
//
// A comparison between two arrays is deprecated in C++20 and C++23. When
// emulating GCC before 15 or Clang before 20, it is also only deprecated in
// C++26. Before C++20 it is not diagnosed.

int a[2], b[2];
int *p = b;

bool x1 = a == b; // Two arrays: diagnosed.
bool x2 = a != b;
bool x3 = a < b;
bool x4 = a >= b;

bool y1 = a == p; // Array and pointer: not diagnosed.
bool y2 = p < a;
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,26 @@ fe_only -DTEST_NUMBER=8 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
void trex(volatile short left_arm, volatile struct amber right_arm);
^

"SemaCXX/deprecated.cpp", line 256: warning: comparison between two arrays is deprecated
bool b1 = arr1 == arr2;
^

"SemaCXX/deprecated.cpp", line 258: warning: comparison between two arrays is deprecated
bool b2 = arr1 < arr2;
^

"SemaCXX/deprecated.cpp", line 261: warning: comparison between two arrays is deprecated
bool b3 = arr1 == arr3;
^

"SemaCXX/deprecated.cpp", line 262: warning: comparison between two arrays is deprecated
bool b4 = arr1 < arr3;
^

"SemaCXX/deprecated.cpp", line 268: warning: comparison between two arrays is deprecated
bool b6 = arr1 == f();
^

"SemaCXX/deprecated.cpp", line 280: warning: parameter "x" was set but never used
[[deprecated]] void f2([[deprecated]] int x) {
^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,26 @@ fe_only -DTEST_NUMBER=9 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
void trex(volatile short left_arm, volatile struct amber right_arm);
^

"SemaCXX/deprecated.cpp", line 256: warning: comparison between two arrays is deprecated
bool b1 = arr1 == arr2;
^

"SemaCXX/deprecated.cpp", line 258: warning: comparison between two arrays is deprecated
bool b2 = arr1 < arr2;
^

"SemaCXX/deprecated.cpp", line 261: warning: comparison between two arrays is deprecated
bool b3 = arr1 == arr3;
^

"SemaCXX/deprecated.cpp", line 262: warning: comparison between two arrays is deprecated
bool b4 = arr1 < arr3;
^

"SemaCXX/deprecated.cpp", line 268: warning: comparison between two arrays is deprecated
bool b6 = arr1 == f();
^

"SemaCXX/deprecated.cpp", line 280: warning: parameter "x" was set but never used
[[deprecated]] void f2([[deprecated]] int x) {
^
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_version 999999 --c++20 Test_name.c
"Test_name.c", line 21: warning: comparison between two arrays is deprecated
bool h() { return a == b; } // expected-warning {{array comparison always evaluates to false}} expected-warning {{deprecated}}
^

"Test_name.c", line 24: warning: comparison between two arrays is deprecated
return a == c; // expected-warning {{array comparison always evaluates to false}} expected-warning {{deprecated}}
^

"Test_name.c", line 30: warning: comparison between two arrays is deprecated
bool k = NA::x == NB::x; // expected-warning {{self-comparison always evaluates to true}} expected-warning {{deprecated}}
^

"Test_name.c", line 53: warning: statement is unreachable
return static_field == static_field; // expected-warning {{self-comparison always evaluates to true}}
^
Expand Down Expand Up @@ -39,6 +51,10 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
return s1.array == s1.array; // expected-warning {{self-comparison always evaluates to true}} expected-warning {{deprecated}}
^

"Test_name.c", line 87: warning: comparison between two arrays is deprecated
return s1.array == s1.array; // expected-warning {{self-comparison always evaluates to true}} expected-warning {{deprecated}}
^

"Test_name.c", line 88: warning: statement is unreachable
return t.s.static_field == S::static_field; // expected-warning {{self-comparison always evaluates to true}}
^
Expand Down Expand Up @@ -103,6 +119,10 @@ fe_only -DTEST_NUMBER=1 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
return s2.array == s1.array; // FIXME: This always evaluates to false. expected-warning {{deprecated}}
^

"Test_name.c", line 108: warning: comparison between two arrays is deprecated
return s2.array == s1.array; // FIXME: This always evaluates to false. expected-warning {{deprecated}}
^

"Test_name.c", line 109: warning: statement is unreachable
return s2.array[0] == s1.array[0];
^
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,16 @@
fe_only -DTEST_NUMBER=2 --clang -tused -e 200 --no_wrap_diagnostics --clang_version 999999 --c++20 Test_name.c
"Test_name.c", line 21: warning: comparison between two arrays is deprecated
bool h() { return a == b; } // expected-warning {{array comparison always evaluates to false}} expected-warning {{deprecated}}
^

"Test_name.c", line 24: warning: comparison between two arrays is deprecated
return a == c; // expected-warning {{array comparison always evaluates to false}} expected-warning {{deprecated}}
^

"Test_name.c", line 30: warning: comparison between two arrays is deprecated
bool k = NA::x == NB::x; // expected-warning {{self-comparison always evaluates to true}} expected-warning {{deprecated}}
^

"Test_name.c", line 53: warning: statement is unreachable
return static_field == static_field; // expected-warning {{self-comparison always evaluates to true}}
^
Expand Down Expand Up @@ -39,6 +51,10 @@ fe_only -DTEST_NUMBER=2 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
return s1.array == s1.array; // expected-warning {{self-comparison always evaluates to true}} expected-warning {{deprecated}}
^

"Test_name.c", line 87: warning: comparison between two arrays is deprecated
return s1.array == s1.array; // expected-warning {{self-comparison always evaluates to true}} expected-warning {{deprecated}}
^

"Test_name.c", line 88: warning: statement is unreachable
return t.s.static_field == S::static_field; // expected-warning {{self-comparison always evaluates to true}}
^
Expand Down Expand Up @@ -103,6 +119,10 @@ fe_only -DTEST_NUMBER=2 --clang -tused -e 200 --no_wrap_diagnostics --clang_vers
return s2.array == s1.array; // FIXME: This always evaluates to false. expected-warning {{deprecated}}
^

"Test_name.c", line 108: warning: comparison between two arrays is deprecated
return s2.array == s1.array; // FIXME: This always evaluates to false. expected-warning {{deprecated}}
^

"Test_name.c", line 109: warning: statement is unreachable
return s2.array[0] == s1.array[0];
^
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
fe_only -DTEST_NUMBER=2 --clang -tused -e 200 --no_wrap_diagnostics --clang_version 999999 --c++20 Test_name.c
"Test_name.c", line 14: warning: comparison between two arrays is deprecated
if (obj1.str != obj2.str) // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}}
^

"Test_name.c", line 16: warning: comparison between two arrays is deprecated
if (obj1.id != obj2.id) // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}}
^

"Test_name.c", line 23: warning: comparison between two arrays is deprecated
if (array1 == array2) { } // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}}
^

Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
fe_only -DTEST_NUMBER=3 --clang -tused -e 200 --no_wrap_diagnostics --clang_version 999999 --c++20 Test_name.c
"Test_name.c", line 14: warning: comparison between two arrays is deprecated
if (obj1.str != obj2.str) // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}}
^

"Test_name.c", line 16: warning: comparison between two arrays is deprecated
if (obj1.id != obj2.id) // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}}
^

"Test_name.c", line 23: warning: comparison between two arrays is deprecated
if (array1 == array2) { } // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}}
^

Loading
Loading