diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -9122,6 +9122,10 @@ "%select{|member|base class}0 %1 declared here">; def note_defaulted_comparison_cannot_deduce_callee : Note< "selected 'operator<=>' for %select{|member|base class}0 %1 declared here">; +def err_defaulted_comparison_cannot_deduce_unsupported_builtin_type : Error< + "return type of defaulted 'operator<=>' cannot be deduced because " + "three-way comparison for %select{|member|base class}0 %1 " + "would compare as builtin type %2 which is not currently supported by clang">; def err_incorrect_defaulted_comparison_constexpr : Error< "defaulted definition of %select{%sub{select_defaulted_comparison_kind}1|" "three-way comparison operator}0 " diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -7868,7 +7868,15 @@ "invalid builtin comparison"); Optional Cat = getComparisonCategoryForBuiltinCmp(T); - assert(Cat && "no category for builtin comparison?"); + if (!Cat) { + if (Diagnose == NoDiagnostics) + S.Diag( + FD->getLocation(), + diag:: + err_defaulted_comparison_cannot_deduce_unsupported_builtin_type) + << Subobj.Kind << Subobj.Decl << T; + return Result::deleted(); + } R.Category = *Cat; } } diff --git a/clang/test/CXX/class/class.compare/class.spaceship/p2.cpp b/clang/test/CXX/class/class.compare/class.spaceship/p2.cpp --- a/clang/test/CXX/class/class.compare/class.spaceship/p2.cpp +++ b/clang/test/CXX/class/class.compare/class.spaceship/p2.cpp @@ -191,4 +191,14 @@ a2 f; }; std::partial_ordering cmp_b2 = b2() <=> b2(); + + struct a3 { + using fp = void (*)(); + operator fp() const; + }; + struct b3 { + auto operator<=>(b3 const &) const = default; // expected-error {{cannot be deduced because three-way comparison for member 'f' would compare as builtin type 'void (*)()' which is not currently supported}} + // expected-warning@-1 {{implicitly deleted}} + a3 f; + }; }