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) ||
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
}
}
+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) {}