From 5a5f5350e1cbe14eaf852d9003523c7fdb1132af Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Mon, 29 Jun 2020 19:02:47 -0700 Subject: [PATCH] [c++20] Fix handling of operator rewrites naming consteval operator<=>. --- clang/lib/Sema/SemaOverload.cpp | 6 +++++- clang/test/SemaCXX/cxx2a-consteval.cpp | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 038b814..d68be85 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -13506,6 +13506,10 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, if (R.isInvalid()) return ExprError(); + R = CheckForImmediateInvocation(R, FnDecl); + if (R.isInvalid()) + return ExprError(); + // For a rewritten candidate, we've already reversed the arguments // if needed. Perform the rest of the rewrite now. if ((Best->RewriteKind & CRK_DifferentOperator) || @@ -13541,7 +13545,7 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc, if (Best->RewriteKind != CRK_None) R = new (Context) CXXRewrittenBinaryOperator(R.get(), IsReversed); - return CheckForImmediateInvocation(R, FnDecl); + return R; } else { // We matched a built-in operator. Convert the arguments, then // break out so that we will build the appropriate built-in diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index 0a6d137..3231107 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -476,6 +476,25 @@ namespace override { } } +namespace operator_rewrite { + struct A { + friend consteval int operator<=>(const A&, const A&) { return 0; } + }; + const bool k = A() < A(); + static_assert(!k); + + A a; + bool k2 = A() < a; // OK, does not access 'a'. + + struct B { + friend consteval int operator<=>(const B &l, const B &r) { return r.n - l.n; } // expected-note {{read of }} + int n; + }; + static_assert(B() >= B()); + B b; // expected-note {{here}} + bool k3 = B() < b; // expected-error-re {{call to consteval function '{{.*}}::operator<=>' is not a constant expression}} expected-note {{in call}} +} + struct A { int(*ptr)(); consteval A(int(*p)() = nullptr) : ptr(p) {} -- 2.7.4