Skip to content

diagnose comparisons between two arrays (P2865), fix for [GH #370] - #387

Open
mohitmishra786 wants to merge 5 commits into
edgcpp:mainfrom
mohitmishra786:gh-370-array-comparisons
Open

mohitmishra786 wants to merge 5 commits into
edgcpp:mainfrom
mohitmishra786:gh-370-array-comparisons

Conversation

@mohitmishra786

@mohitmishra786 mohitmishra786 commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #370.

A comparison between two arrays with ==, !=, <, <=, > or >= was accepted silently in every mode. It is deprecated in C++20 and not allowed in C++26 (P2865).

process_eq_operator and process_rel_operator now call check_for_array_comparison before the array-to-pointer conversion (the same place <=> already rejects two arrays). If both operands have array type:

  • C++26: error, "comparison between two arrays is not allowed".
  • C++20 and C++23: warning, "comparison between two arrays is deprecated".
  • When emulating GCC before 15 or Clang before 20, C++26 only gets the warning. GCC 14 warns and GCC 15 errors with -std=c++26 (checked with the gcc:14 and gcc:15 images); Clang implemented P2865 in Clang 20.

A comparison between an array and a pointer is not affected.

Summary by CodeRabbit

Bug Fixes

  • Equality and relational comparisons between two arrays are now diagnosed. They produce deprecation warnings in C++20 and C++23; before C++20, they produce a remark, or a warning in Clang 20+ compatibility mode.
  • In C++26, these comparisons produce errors with newer GCC and Clang compatibility settings; otherwise, they produce deprecation warnings.
  • Comparisons involving class operands converted to arrays are diagnosed as well.
  • Comparisons between an array and a pointer remain allowed.

@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 0f1c04f7-ddd5-4078-aef5-db8f45493a3f
Commits

Reviewing files that changed from the base of the PR and between ee685d1 and 8cf11d6.

Files ignored due to path filters: 1
  • tests/expectations/edg_x86_64/imported.log is excluded by !**/*.log
Files selected for processing: 40
  • src/error_msg.txt
  • src/expr.c
  • src/pending_changes/gh-370-array-comparisons.txt
  • tests/tests/changes/.GH370.rto/default.1.1.txt
  • tests/tests/changes/.GH370.rto/default.2.1.txt
  • tests/tests/changes/.GH370.rto/default.3.1.txt
  • tests/tests/changes/.GH370_a.rto/default.1.1.txt
  • tests/tests/changes/.GH370_a.rto/default.2.1.txt
  • tests/tests/changes/.GH370_a.rto/default.3.1.txt
  • tests/tests/changes/.GH370_a.rto/default.4.1.txt
  • tests/tests/changes/.GH370_a.rto/default.5.1.txt
  • tests/tests/changes/.GH370_a.rto/default.6.1.txt
  • tests/tests/changes/.GH370_a.rto/default.7.1.txt
  • tests/tests/changes/GH370.sft.cpp
  • tests/tests/changes/GH370_a.sft.cpp
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/default.1.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/default.10.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/default.11.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/default.2.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/default.3.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/default.4.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/default.5.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/default.6.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/default.7.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/default.8.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/default.9.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/edg_x86_64_cp.1.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/edg_x86_64_cp.11.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/edg_x86_64_cp.2.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/edg_x86_64_cp.3.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.deprecated.rto/edg_x86_64_cp.5.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.self-comparison.rto/default.1.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.self-comparison.rto/default.2.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.warn-array-comparion.rto/default.1.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.warn-array-comparion.rto/default.2.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.warn-array-comparion.rto/default.3.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.warn-array-comparion.rto/default.4.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.warn-self-comparisons.rto/default.1.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.warn-self-comparisons.rto/default.2.1.txt
  • tests/tests/imported/clang/cpp/SemaCXX/.warn-self-comparisons.rto/default.3.1.txt
Files skipped from review as they are similar to previous changes: 2

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Walkthrough

The compiler now diagnoses built-in equality and relational comparisons between two arrays. The diagnostic depends on the C++ standard and, in C++26 mode, the emulated compiler version. Tests also cover array-to-pointer comparisons.

Changes: Array comparison diagnostics

Layer / File(s) Summary
Diagnostic check and operator integration
src/error_msg.txt, src/expr.c
The built-in comparison paths check operands before transformations. They report remarks, warnings, or errors according to the C++ standard and emulated compiler versions.
Standard and compiler-version coverage
tests/tests/changes/GH370*.sft.cpp, tests/tests/changes/.GH370*.rto/*, src/pending_changes/gh-370-array-comparisons.txt
Tests cover array-to-array and array-to-pointer comparisons across language modes and compiler-version configurations. The pending-change note describes the diagnostics.
Imported Clang diagnostic expectations
tests/tests/imported/clang/cpp/SemaCXX/*
Expected outputs now include array-comparison remarks, warnings, and errors for the covered cases.

Priority: Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant BuiltinComparisonPath
  participant ArrayComparisonCheck
  participant CompilerDiagnostics
  BuiltinComparisonPath->>ArrayComparisonCheck: Check original operands
  ArrayComparisonCheck->>CompilerDiagnostics: Report remark, warning, or error
Loading

Suggested labels: bug

Suggested reviewers: darkarc

Merge Risk: Minimal · up to 8cf11

The change adds standard-aware array-comparison diagnostics. No actionable merge-blocking risk remains in the supplied evidence.

Architecture risk: Low · up to 0d4ea

The change affects 2 systems.

Changed systems: tests, src

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — tests (service) was modified; 18 changed files map to changed impact.
  • observed — src (service) was modified; 3 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in src/error_msg.txt: Added diagnostic entries for deprecated and disallowed comparisons between two arrays.
  • observed — Modified behavior in src/expr.c: Added check_for_array_comparison, which checks for two array-typed operands in C++20 mode and diagnoses the comparison. In C++26 mode, it emits an error except on GCC 15+ and Clang 20+, where it emits a deprecation warning.
  • observed — Modified behavior in src/expr.c: The built-in relational-operator path now checks the original operands for an array comparison before operand transformations.
  • observed — Modified behavior in src/expr.c: The built-in equality-operator path now checks the original operands for an array comparison before operand transformations.
Pre-merge checks: Passed 5
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies the main change: diagnosing comparisons between two arrays under P2865. It also references the related issue.
Linked Issues check Passed Issue #370 requires P2865R6 handling of array comparisons: deprecate them in C++20 and disallow them in C++26. The change adds check_for_array_comparison calls in both non-operator-function comparis…
Out of Scope Changes check Passed The changes in src/expr.c, src/error_msg.txt, and the pending-change note gh-370-array-comparisons.txt implement the array-comparison diagnostics for #370. The test changes cover the same diagno…
Docstring Coverage Passed No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Full details: Linked Issues check

Explanation

Issue #370 requires P2865R6 handling of array comparisons: deprecate them in C++20 and disallow them in C++26. The change adds check_for_array_comparison calls in both non-operator-function comparison paths, before operand transformations, so the array check runs before array-to-pointer conversion. The check covers ==, !=, &lt;, &lt;=, &gt; and &gt;=. The summary reports a deprecation warning in C++20 and C++23, and an error in C++26 when the emulated GCC is version 15 or later or the emulated Clang is version 20 or later. Otherwise C++26 gives the deprecation warning. The new and updated tests (GH370.sft.cpp, GH370_a.sft.cpp, .GH370.rto and .GH370_a.rto expectations) cover the language modes, emulated compiler versions, class operands converted to arrays, and the qualification-conversion case. Array-to-pointer comparisons stay allowed. The requirement is implemented and tested. The summary wording for the C++26 error condition uses 'and' between the GCC and Clang checks. The PR description and the test expectations (GCC 150000 and Clang 200000 error; Clang 190000 warns) indicate 'or'. This wording difference does not change the result.

Full details: Out of Scope Changes check

Explanation

The changes in src/expr.c, src/error_msg.txt, and the pending-change note gh-370-array-comparisons.txt implement the array-comparison diagnostics for #370. The test changes cover the same diagnostics in the changes/ and imported Clang SemaCXX expectations. The imported Clang expectation updates record the new diagnostics for existing array comparisons, so they follow from the feature and are not unrelated edits. The pre-C++20 remark and the Clang 20+ warning under emulation belong to the same array-comparison diagnostic family. The current PR description does not mention the pre-C++20 remark, but the reviewer agreed to it and it does not affect unrelated behavior. No unrelated change appears in the reviewable summary. The ignored file tests/expectations/edg_x86_64/imported.log matches the !**/*.log exclusion rule and was not inspected. Its exclusion does not establish an out-of-scope change.

Full details: Docstring Coverage

Explanation

No eligible functions found in the changed files. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 0 functions across 2 files. (38 skipped: 37 unsupported, 1 too large.)

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Warning

Some tools did not complete. Review the errors below.

LanguageTool
src/error_msg.txt

LanguageTool checks are incomplete because the per-file request limit of 5 was reached. Remaining text was skipped; findings from completed checks are retained.

Comment @coderabbitai help to get the list of available commands.

@edgcpp-bot

Copy link
Copy Markdown
Collaborator

AcknowlEDG review results updated for d5a1e7d07c57:

@codecov

codecov Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.81818% with 4 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/expr.c 81.81% 0 Missing and 4 partials ⚠️

📢 Thoughts on this report? Let us know!

@edgcpp-bot

Copy link
Copy Markdown
Collaborator

AcknowlEDG review results updated for 0d4eabd027be:

CI success.

@nv-cmeerw nv-cmeerw left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also handle user-defined conversion functions, e.g.

struct C
{
  using arr_t = int[2];
  operator arr_t &() const;
};

void g(int (&arr)[2], C c)
{
  arr == arr;
  c == c;
}

@mohitmishra786
mohitmishra786 force-pushed the gh-370-array-comparisons branch from 0d4eabd to ee685d1 Compare October 28, 2026 16:25
@mohitmishra786
mohitmishra786 requested a review from a team October 28, 2026 16:25
@mohitmishra786

Copy link
Copy Markdown
Contributor Author

@nv-cmeerw fixed in ee685d1 (rebased onto main): class operands converted to arrays by a conversion function (c == c, c < c, c == arr) are now diagnosed too, matching GCC 15 and Clang 20, and changes/GH370 covers them. Could you please take another look?

@edgcpp-bot

Copy link
Copy Markdown
Collaborator

AcknowlEDG review results updated for ee685d105146:

@edgcpp-bot

Copy link
Copy Markdown
Collaborator

AcknowlEDG review results updated for ee685d105146:

CI success.

@daveedvdv-nvidia

Copy link
Copy Markdown
Contributor

@nv-cmeerw @mohitmishra786

Clang diagnosed this with a warning even before C++20 deprecated it. E.g.: https://godbolt.org/z/KvThjdvqv

Should we perhaps do something similar with this change?

@daveedvdv-nvidia daveedvdv-nvidia left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.
I have a question in the conversation about possibly extending the diagnosis to pre-C++20 modes.

@mohitmishra786

Copy link
Copy Markdown
Contributor Author

@daveedvdv-nvidia @nv-cmeerw Thanks, good point. I checked this on Godbolt (x86-64), with no extra warning options:

  • Clang 9 to 19, -std=c++17: no array-comparison warning. The warning in the link is -Wtautological-compare ("array comparison always evaluates to false"), which only fires when the result is known, e.g. for two distinct global arrays. Comparing two array references gives nothing.
  • Clang 20 and later warn on every array comparison in C++03 to C++17 by default (-Warray-compare: "comparison between two arrays compare their addresses and will be deprecated in c++20").
  • GCC 12 and later warn before C++20 only with -Wall (-Warray-compare). GCC 11 and earlier do not warn at all.

So my suggestion: before C++20, issue a remark, the way a comma operator in a subscript is handled before C++20, and a warning when emulating Clang 20 or later. It would get its own message, e.g. "comparison between two arrays compares their addresses", since it is not deprecated yet in those modes. C++20 and later stay as in this PR.

Does that sound OK, or would you prefer a warning in all modes before C++20?

@daveedvdv-nvidia

Copy link
Copy Markdown
Contributor

Yes, the remark idea sounds exactly right — thanks!

@nv-cmeerw

Copy link
Copy Markdown
Contributor

There still appears to be an issue with cv-qualifications:

struct C { using A = int[2]; operator A &() const; };

const int a[2] = {};
int b[2] = {};

bool f(C c) { return c == a; }  // not diagnosed yet
bool g(C c) { return b == a; }  // diagnosed

@mohitmishra786

mohitmishra786 commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor Author

@nv-cmeerw @daveedvdv-nvidia updated in 197630c:

  • c == a with a const array is now diagnosed. The check looks through the implicit qualification conversion added by overload resolution, but not through a cast in the source, so (const int *)b == a is still not diagnosed, matching GCC and Clang.
  • Before C++20 there is now a remark ("comparison between two arrays compares their addresses"), and a warning when emulating Clang 20 or later.

changes/GH370 and GH370_a cover both. Could you please take another look?

@edgcpp-bot

Copy link
Copy Markdown
Collaborator

AcknowlEDG review results updated for 8cf11d690be4:

@edgcpp-bot

Copy link
Copy Markdown
Collaborator

AcknowlEDG review results updated for 8cf11d690be4:

CI failure.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[GNATS 27773] C++26: Remove Deprecated Array Comparisons from C++26 (P2865R6)

4 participants