Author: rsmith Date: Sun Nov 22 01:33:28 2015 New Revision: 253817 URL: http://llvm.org/viewvc/llvm-project?rev=253817&view=rev Log: [coroutines] Check for overload sets in co_yield / co_return operands being resolved by a call to yield_value / return_value before rejecting them.
Modified: cfe/trunk/lib/Sema/SemaCoroutine.cpp cfe/trunk/test/SemaCXX/coroutines.cpp Modified: cfe/trunk/lib/Sema/SemaCoroutine.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCoroutine.cpp?rev=253817&r1=253816&r2=253817&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original) +++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Sun Nov 22 01:33:28 2015 @@ -52,6 +52,8 @@ static QualType lookupPromiseType(Sema & Args.addArgument(TemplateArgumentLoc( TemplateArgument(FnType->getReturnType()), S.Context.getTrivialTypeSourceInfo(FnType->getReturnType(), Loc))); + // FIXME: If the function is a non-static member function, add the type + // of the implicit object parameter before the formal parameters. for (QualType T : FnType->getParamTypes()) Args.addArgument(TemplateArgumentLoc( TemplateArgument(T), S.Context.getTrivialTypeSourceInfo(T, Loc))); @@ -270,12 +272,6 @@ static ExprResult buildPromiseCall(Sema } ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) { - if (E->getType()->isPlaceholderType()) { - ExprResult R = CheckPlaceholderExpr(E); - if (R.isInvalid()) return ExprError(); - E = R.get(); - } - auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield"); if (!Coroutine) return ExprError(); @@ -330,16 +326,17 @@ StmtResult Sema::ActOnCoreturnStmt(Sourc return BuildCoreturnStmt(Loc, E); } StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E) { - if (E && E->getType()->isPlaceholderType()) { + auto *Coroutine = checkCoroutineContext(*this, Loc, "co_return"); + if (!Coroutine) + return StmtError(); + + if (E && E->getType()->isPlaceholderType() && + !E->getType()->isSpecificPlaceholderType(BuiltinType::Overload)) { ExprResult R = CheckPlaceholderExpr(E); if (R.isInvalid()) return StmtError(); E = R.get(); } - auto *Coroutine = checkCoroutineContext(*this, Loc, "co_return"); - if (!Coroutine) - return StmtError(); - // FIXME: If the operand is a reference to a variable that's about to go out // ot scope, we should treat the operand as an xvalue for this overload // resolution. Modified: cfe/trunk/test/SemaCXX/coroutines.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/coroutines.cpp?rev=253817&r1=253816&r2=253817&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/coroutines.cpp (original) +++ cfe/trunk/test/SemaCXX/coroutines.cpp Sun Nov 22 01:33:28 2015 @@ -49,11 +49,11 @@ struct yielded_thing { const char *p; sh struct not_awaitable {}; struct promise { - awaitable yield_value(int); // expected-note {{candidate}} - awaitable yield_value(yielded_thing); // expected-note {{candidate}} - not_awaitable yield_value(void()); // expected-note {{candidate}} + awaitable yield_value(int); // expected-note 2{{candidate}} + awaitable yield_value(yielded_thing); // expected-note 2{{candidate}} + not_awaitable yield_value(void()); // expected-note 2{{candidate}} void return_void(); - void return_value(int); // expected-note {{here}} + void return_value(int); // expected-note 2{{here}} }; void yield() { @@ -159,17 +159,37 @@ namespace dependent_operator_co_await_lo template void await_template_2(outer); } +struct yield_fn_tag {}; +template<> struct std::coroutine_traits<void, yield_fn_tag> { + struct promise_type { + // FIXME: add an await_transform overload for functions + awaitable yield_value(int()); + void return_value(int()); + }; +}; + namespace placeholder { - awaitable f(), f(int); // expected-note 2{{possible target}} - int g(), g(int); // expected-note 4{{possible target}} + awaitable f(), f(int); // expected-note 4{{possible target}} + int g(), g(int); // expected-note 2{{candidate}} void x() { co_await f; // expected-error {{reference to overloaded function}} } void y() { - co_yield g; // expected-error {{reference to overloaded function}} + co_yield g; // expected-error {{no matching member function for call to 'yield_value'}} } void z() { co_await a; - co_return g; // expected-error {{reference to overloaded function}} + co_return g; // expected-error {{address of overloaded function 'g' does not match required type 'int'}} + } + + void x(yield_fn_tag) { + co_await f; // expected-error {{reference to overloaded function}} + } + void y(yield_fn_tag) { + co_yield g; + } + void z(yield_fn_tag) { + co_await a; + co_return g; } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits