mizvekov updated this revision to Diff 326514. mizvekov added a comment. Updated comment and moved tests to correct places.
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D95409/new/ https://reviews.llvm.org/D95409 Files: clang/lib/Sema/SemaDeclCXX.cpp clang/test/CXX/class/class.compare/class.compare.default/p2.cpp clang/test/CXX/class/class.compare/class.eq/p2.cpp clang/test/CXX/class/class.compare/class.spaceship/p2.cpp Index: clang/test/CXX/class/class.compare/class.spaceship/p2.cpp =================================================================== --- clang/test/CXX/class/class.compare/class.spaceship/p2.cpp +++ clang/test/CXX/class/class.compare/class.spaceship/p2.cpp @@ -155,3 +155,20 @@ friend CmpCat auto operator<=>(const D&, const D&) = default; }; } + +namespace PR48856 { + struct A { + auto operator<=>(const A &) const = default; // expected-warning {{implicitly deleted}} + void (*x)(); // expected-note {{because there is no viable comparison function for member 'x'}} + }; + + struct B { + auto operator<=>(const B &) const = default; // expected-warning {{implicitly deleted}} + void (B::*x)(); // expected-note {{because there is no viable comparison function for member 'x'}} + }; + + struct C { + auto operator<=>(const C &) const = default; // expected-warning {{implicitly deleted}} + int C::*x; // expected-note {{because there is no viable comparison function for member 'x'}} + }; +} Index: clang/test/CXX/class/class.compare/class.eq/p2.cpp =================================================================== --- clang/test/CXX/class/class.compare/class.eq/p2.cpp +++ clang/test/CXX/class/class.compare/class.eq/p2.cpp @@ -15,6 +15,25 @@ struct F { void operator==(F) const; }; struct G { bool operator==(G) const = delete; }; // expected-note {{deleted here}} +struct H1 { + bool operator==(const H1 &) const = default; + bool operator<(const H1 &) const = default; // expected-warning {{implicitly deleted}} + // expected-note@-1 {{because there is no viable comparison function}} + void (*x)(); +}; +struct H2 { + bool operator==(const H2 &) const = default; + bool operator<(const H2 &) const = default; // expected-warning {{implicitly deleted}} + // expected-note@-1 {{because there is no viable comparison function}} + void (H2::*x)(); +}; +struct H3 { + bool operator==(const H3 &) const = default; + bool operator<(const H3 &) const = default; // expected-warning {{implicitly deleted}} + // expected-note@-1 {{because there is no viable comparison function}} + int H3::*x; +}; + template<typename T> struct X { X(); bool operator==(const X&) const = default; // #x expected-note 4{{deleted here}} Index: clang/test/CXX/class/class.compare/class.compare.default/p2.cpp =================================================================== --- clang/test/CXX/class/class.compare/class.compare.default/p2.cpp +++ clang/test/CXX/class/class.compare/class.compare.default/p2.cpp @@ -39,6 +39,14 @@ void(a >= a); } +struct A3 { + int &x; // expected-note {{because class 'A3' has a reference member}} + + bool operator==(const A3 &) const = default; // expected-warning {{implicitly deleted}} + bool operator<(const A3 &) const = default; // expected-warning {{implicitly deleted}} + // expected-note@-1 {{because there is no viable comparison function}} +}; + struct B1 { struct { int x; Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -7685,10 +7685,14 @@ if (Args[0]->getType()->isOverloadableType()) S.LookupOverloadedBinOp(CandidateSet, OO, Fns, Args); - else { + else if (OO == OO_EqualEqual || + !Args[0]->getType()->isFunctionPointerType()) { // FIXME: We determine whether this is a valid expression by checking to // see if there's a viable builtin operator candidate for it. That isn't // really what the rules ask us to do, but should give the right results. + // + // Note that the builtin operator for relational comparisons on function + // pointers is the only known case which cannot be used. S.AddBuiltinOperatorCandidates(OO, FD->getLocation(), Args, CandidateSet); }
Index: clang/test/CXX/class/class.compare/class.spaceship/p2.cpp =================================================================== --- clang/test/CXX/class/class.compare/class.spaceship/p2.cpp +++ clang/test/CXX/class/class.compare/class.spaceship/p2.cpp @@ -155,3 +155,20 @@ friend CmpCat auto operator<=>(const D&, const D&) = default; }; } + +namespace PR48856 { + struct A { + auto operator<=>(const A &) const = default; // expected-warning {{implicitly deleted}} + void (*x)(); // expected-note {{because there is no viable comparison function for member 'x'}} + }; + + struct B { + auto operator<=>(const B &) const = default; // expected-warning {{implicitly deleted}} + void (B::*x)(); // expected-note {{because there is no viable comparison function for member 'x'}} + }; + + struct C { + auto operator<=>(const C &) const = default; // expected-warning {{implicitly deleted}} + int C::*x; // expected-note {{because there is no viable comparison function for member 'x'}} + }; +} Index: clang/test/CXX/class/class.compare/class.eq/p2.cpp =================================================================== --- clang/test/CXX/class/class.compare/class.eq/p2.cpp +++ clang/test/CXX/class/class.compare/class.eq/p2.cpp @@ -15,6 +15,25 @@ struct F { void operator==(F) const; }; struct G { bool operator==(G) const = delete; }; // expected-note {{deleted here}} +struct H1 { + bool operator==(const H1 &) const = default; + bool operator<(const H1 &) const = default; // expected-warning {{implicitly deleted}} + // expected-note@-1 {{because there is no viable comparison function}} + void (*x)(); +}; +struct H2 { + bool operator==(const H2 &) const = default; + bool operator<(const H2 &) const = default; // expected-warning {{implicitly deleted}} + // expected-note@-1 {{because there is no viable comparison function}} + void (H2::*x)(); +}; +struct H3 { + bool operator==(const H3 &) const = default; + bool operator<(const H3 &) const = default; // expected-warning {{implicitly deleted}} + // expected-note@-1 {{because there is no viable comparison function}} + int H3::*x; +}; + template<typename T> struct X { X(); bool operator==(const X&) const = default; // #x expected-note 4{{deleted here}} Index: clang/test/CXX/class/class.compare/class.compare.default/p2.cpp =================================================================== --- clang/test/CXX/class/class.compare/class.compare.default/p2.cpp +++ clang/test/CXX/class/class.compare/class.compare.default/p2.cpp @@ -39,6 +39,14 @@ void(a >= a); } +struct A3 { + int &x; // expected-note {{because class 'A3' has a reference member}} + + bool operator==(const A3 &) const = default; // expected-warning {{implicitly deleted}} + bool operator<(const A3 &) const = default; // expected-warning {{implicitly deleted}} + // expected-note@-1 {{because there is no viable comparison function}} +}; + struct B1 { struct { int x; Index: clang/lib/Sema/SemaDeclCXX.cpp =================================================================== --- clang/lib/Sema/SemaDeclCXX.cpp +++ clang/lib/Sema/SemaDeclCXX.cpp @@ -7685,10 +7685,14 @@ if (Args[0]->getType()->isOverloadableType()) S.LookupOverloadedBinOp(CandidateSet, OO, Fns, Args); - else { + else if (OO == OO_EqualEqual || + !Args[0]->getType()->isFunctionPointerType()) { // FIXME: We determine whether this is a valid expression by checking to // see if there's a viable builtin operator candidate for it. That isn't // really what the rules ask us to do, but should give the right results. + // + // Note that the builtin operator for relational comparisons on function + // pointers is the only known case which cannot be used. S.AddBuiltinOperatorCandidates(OO, FD->getLocation(), Args, CandidateSet); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits