aaron.ballman updated this revision to Diff 379795. aaron.ballman added a comment.
Updated the patch to add new test cases. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D111817/new/ https://reviews.llvm.org/D111817 Files: clang/lib/Sema/SemaOverload.cpp clang/test/SemaCXX/cxx2a-consteval.cpp Index: clang/test/SemaCXX/cxx2a-consteval.cpp =================================================================== --- clang/test/SemaCXX/cxx2a-consteval.cpp +++ clang/test/SemaCXX/cxx2a-consteval.cpp @@ -612,3 +612,34 @@ 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}} +} Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -14161,7 +14161,8 @@ 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 @@ Method->getType()->castAs<FunctionProtoType>())) return ExprError(); - return MaybeBindToTemporary(TheCall); + return CheckForImmediateInvocation(MaybeBindToTemporary(TheCall), Method); } /// BuildLiteralOperatorCall - Build a UserDefinedLiteral by creating a call to
Index: clang/test/SemaCXX/cxx2a-consteval.cpp =================================================================== --- clang/test/SemaCXX/cxx2a-consteval.cpp +++ clang/test/SemaCXX/cxx2a-consteval.cpp @@ -612,3 +612,34 @@ 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}} +} Index: clang/lib/Sema/SemaOverload.cpp =================================================================== --- clang/lib/Sema/SemaOverload.cpp +++ clang/lib/Sema/SemaOverload.cpp @@ -14161,7 +14161,8 @@ 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 @@ Method->getType()->castAs<FunctionProtoType>())) return ExprError(); - return MaybeBindToTemporary(TheCall); + return CheckForImmediateInvocation(MaybeBindToTemporary(TheCall), Method); } /// BuildLiteralOperatorCall - Build a UserDefinedLiteral by creating a call to
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits