Author: Aaron Ballman Date: 2021-10-14T14:47:29-04:00 New Revision: b9941de0bfac4bad93e11dff26396e34a53e3891
URL: https://github.com/llvm/llvm-project/commit/b9941de0bfac4bad93e11dff26396e34a53e3891 DIFF: https://github.com/llvm/llvm-project/commit/b9941de0bfac4bad93e11dff26396e34a53e3891.diff LOG: Fix a rejects-valid with consteval on overloaded operators It seems that Clang 11 regressed functionality that was working in Clang 10 regarding calling a few overloaded operators in an immediate context. Specifically, we were not checking for immediate invocations of array subscripting and the arrow operators, but we properly handle the other overloaded operators. This fixes the two problematic operators and adds some test coverage to show they're equivalent to calling the operator directly. This addresses PR50779. Added: Modified: clang/lib/Sema/SemaOverload.cpp clang/test/SemaCXX/cxx2a-consteval.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 044e3c4b254ad..d93fd9df0093e 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -14161,7 +14161,8 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, Method->getType()->castAs<FunctionProtoType>())) return ExprError(); - return MaybeBindToTemporary(TheCall); + return CheckForImmediateInvocation(MaybeBindToTemporary(TheCall), + FnDecl); } else { // We matched a built-in operator. Convert the arguments, then // break out so that we will build the appropriate built-in @@ -14916,7 +14917,7 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, Method->getType()->castAs<FunctionProtoType>())) return ExprError(); - return MaybeBindToTemporary(TheCall); + return CheckForImmediateInvocation(MaybeBindToTemporary(TheCall), Method); } /// BuildLiteralOperatorCall - Build a UserDefinedLiteral by creating a call to diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp index 04c8898aa5bad..c1e713a5b6b79 100644 --- a/clang/test/SemaCXX/cxx2a-consteval.cpp +++ b/clang/test/SemaCXX/cxx2a-consteval.cpp @@ -612,3 +612,34 @@ using T = decltype(g(f())); static_assert(is_same<long, T>::value); } // namespace unevaluated + +namespace PR50779 { +struct derp { + int b = 0; +}; + +constexpr derp d; + +struct test { + consteval int operator[](int i) const { return {}; } + consteval const derp * operator->() const { return &d; } + consteval int f() const { return 12; } // expected-note 2{{declared here}} +}; + +constexpr test a; + +// We previously rejected both of these overloaded operators as taking the +// address of a consteval function outside of an immediate context, but we +// accepted direct calls to the overloaded operator. Now we show that we accept +// both forms. +constexpr int s = a.operator[](1); +constexpr int t = a[1]; +constexpr int u = a.operator->()->b; +constexpr int v = a->b; +// FIXME: I believe this case should work, but we currently reject. +constexpr int w = (a.*&test::f)(); // expected-error {{cannot take address of consteval function 'f' outside of an immediate invocation}} +constexpr int x = a.f(); + +// Show that we reject when not in an immediate context. +int w2 = (a.*&test::f)(); // expected-error {{cannot take address of consteval function 'f' outside of an immediate invocation}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits