Skip to content

[C++20] Fix a crash with spaceship and vector types #139767

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 2 commits into from
May 14, 2025
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
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ C++23 Feature Support

C++20 Feature Support
^^^^^^^^^^^^^^^^^^^^^
- Fixed a crash with a defaulted spaceship (``<=>``) operator when the class
contains a member declaration of vector type. Vector types cannot yet be
compared directly, so this causes the operator to be deleted. (#GH137452)

C++17 Feature Support
^^^^^^^^^^^^^^^^^^^^^
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -10176,6 +10176,9 @@ def note_defaulted_comparison_no_viable_function_synthesized : Note<
def note_defaulted_comparison_not_rewritten_callee : Note<
"defaulted %0 is implicitly deleted because this non-rewritten comparison "
"function would be the best match for the comparison">;
def note_defaulted_comparison_vector_types : Note<
"defaulted %0 is implicitly deleted because defaulted comparison of vector "
"types is not supported">;
def note_defaulted_comparison_not_rewritten_conversion : Note<
"defaulted %0 is implicitly deleted because a builtin comparison function "
"using this conversion would be the best match for the comparison">;
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8651,6 +8651,18 @@ class DefaultedComparisonAnalyzer
assert(Best->BuiltinParamTypes[2].isNull() &&
"invalid builtin comparison");

// FIXME: If the type we deduced is a vector type, we mark the
// comparison as deleted because we don't yet support this.
if (isa<VectorType>(T)) {
if (Diagnose == ExplainDeleted) {
S.Diag(FD->getLocation(),
diag::note_defaulted_comparison_vector_types)
<< FD;
S.Diag(Subobj.Decl->getLocation(), diag::note_declared_at);
}
return Result::deleted();
Copy link
Collaborator

Choose a reason for hiding this comment

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

The other versions of 'deleted' all seem to diagnose first, is there a reason to not do so here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oh, I missed the "explain deleted" code paths entirely. I'll address that.

}

if (NeedsDeducing) {
std::optional<ComparisonCategoryType> Cat =
getComparisonCategoryForBuiltinCmp(T);
Expand Down
9 changes: 9 additions & 0 deletions clang/test/SemaCXX/cxx2a-three-way-comparison.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,12 @@ namespace PR44325 {
// implicit rewrite rules, not for explicit use by programs.
bool c = cmp_cat() < 0; // expected-warning {{zero as null pointer constant}}
}

namespace GH137452 {
struct comparable_t {
__attribute__((vector_size(32))) double numbers; // expected-note {{declared here}}
auto operator<=>(const comparable_t& rhs) const = default; // expected-warning {{explicitly defaulted three-way comparison operator is implicitly deleted}} \
expected-note {{replace 'default' with 'delete'}} \
expected-note {{defaulted 'operator<=>' is implicitly deleted because defaulted comparison of vector types is not supported}}
};
} // namespace GH137452