r333379 - [coroutines] Pass implicit object parameter to promise ctor (fix BUG37604)
Gor Nishanov via cfe-commits
cfe-commits at lists.llvm.org
Mon May 28 11:08:47 PDT 2018
Author: gornishanov
Date: Mon May 28 11:08:47 2018
New Revision: 333379
URL: http://llvm.org/viewvc/llvm-project?rev=333379&view=rev
Log:
[coroutines] Pass implicit object parameter to promise ctor (fix BUG37604)
Summary:
Complete the implementation of p0914r1.
Implicit object parameter should be passed to a promise constructor.
Fixes: https://bugs.llvm.org/show_bug.cgi?id=37604
Reviewers: modocache, rsmith, lewissbaker
Reviewed By: modocache
Subscribers: cfe-commits, EricWF
Differential Revision: https://reviews.llvm.org/D47454
Modified:
cfe/trunk/lib/Sema/SemaCoroutine.cpp
cfe/trunk/test/CodeGenCoroutines/coro-params.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=333379&r1=333378&r2=333379&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Mon May 28 11:08:47 2018
@@ -510,6 +510,20 @@ VarDecl *Sema::buildCoroutinePromise(Sou
// Build a list of arguments, based on the coroutine functions arguments,
// that will be passed to the promise type's constructor.
llvm::SmallVector<Expr *, 4> CtorArgExprs;
+
+ // Add implicit object parameter.
+ if (auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
+ if (MD->isInstance() && !isLambdaCallOperator(MD)) {
+ ExprResult ThisExpr = ActOnCXXThis(Loc);
+ if (ThisExpr.isInvalid())
+ return nullptr;
+ ThisExpr = CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.get());
+ if (ThisExpr.isInvalid())
+ return nullptr;
+ CtorArgExprs.push_back(ThisExpr.get());
+ }
+ }
+
auto &Moves = ScopeInfo->CoroutineParameterMoves;
for (auto *PD : FD->parameters()) {
if (PD->getType()->isDependentType())
Modified: cfe/trunk/test/CodeGenCoroutines/coro-params.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCoroutines/coro-params.cpp?rev=333379&r1=333378&r2=333379&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCoroutines/coro-params.cpp (original)
+++ cfe/trunk/test/CodeGenCoroutines/coro-params.cpp Mon May 28 11:08:47 2018
@@ -156,3 +156,28 @@ void coroutine_matching_promise_construc
// CHECK: invoke void @_ZNSt12experimental16coroutine_traitsIJv28promise_matching_constructorifdEE12promise_typeC1ES1_ifd(%"struct.std::experimental::coroutine_traits<void, promise_matching_constructor, int, float, double>::promise_type"* %__promise, i32 %[[INT]], float %[[FLOAT]], double %[[DOUBLE]])
co_return;
}
+
+struct some_class;
+
+struct method {};
+
+template <typename... Args> struct std::experimental::coroutine_traits<method, Args...> {
+ struct promise_type {
+ promise_type(some_class&, float);
+ method get_return_object();
+ suspend_always initial_suspend();
+ suspend_always final_suspend();
+ void return_void();
+ void unhandled_exception();
+ };
+};
+
+struct some_class {
+ method good_coroutine_calls_custom_constructor(float);
+};
+
+// CHECK-LABEL: define void @_ZN10some_class39good_coroutine_calls_custom_constructorEf(%struct.some_class*
+method some_class::good_coroutine_calls_custom_constructor(float) {
+ // CHECK: invoke void @_ZNSt12experimental16coroutine_traitsIJ6methodR10some_classfEE12promise_typeC1ES3_f(%"struct.std::experimental::coroutine_traits<method, some_class &, float>::promise_type"* %__promise, %struct.some_class* dereferenceable(1) %{{.+}}, float
+ co_return;
+}
Modified: cfe/trunk/test/SemaCXX/coroutines.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/coroutines.cpp?rev=333379&r1=333378&r2=333379&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/coroutines.cpp (original)
+++ cfe/trunk/test/SemaCXX/coroutines.cpp Mon May 28 11:08:47 2018
@@ -831,7 +831,7 @@ struct std::experimental::coroutine_trai
};
};
-extern "C" int f(mismatch_gro_type_tag1) {
+extern "C" int f(mismatch_gro_type_tag1) {
// expected-error at -1 {{cannot initialize return object of type 'int' with an rvalue of type 'void'}}
co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
}
@@ -848,7 +848,7 @@ struct std::experimental::coroutine_trai
};
};
-extern "C" int f(mismatch_gro_type_tag2) {
+extern "C" int f(mismatch_gro_type_tag2) {
// expected-error at -1 {{cannot initialize return object of type 'int' with an lvalue of type 'void *'}}
co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
}
@@ -866,7 +866,7 @@ struct std::experimental::coroutine_trai
};
};
-extern "C" int f(mismatch_gro_type_tag3) {
+extern "C" int f(mismatch_gro_type_tag3) {
// expected-error at -1 {{cannot initialize return object of type 'int' with an rvalue of type 'void'}}
co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
}
@@ -885,7 +885,7 @@ struct std::experimental::coroutine_trai
};
};
-extern "C" int f(mismatch_gro_type_tag4) {
+extern "C" int f(mismatch_gro_type_tag4) {
// expected-error at -1 {{cannot initialize return object of type 'int' with an rvalue of type 'char *'}}
co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
}
@@ -1246,7 +1246,10 @@ good_coroutine_calls_default_constructor
co_return;
}
+struct some_class;
+
struct good_promise_custom_constructor {
+ good_promise_custom_constructor(some_class&, float, int);
good_promise_custom_constructor(double, float, int);
good_promise_custom_constructor() = delete;
coro<good_promise_custom_constructor> get_return_object();
@@ -1261,9 +1264,20 @@ good_coroutine_calls_custom_constructor(
co_return;
}
+struct some_class {
+ coro<good_promise_custom_constructor>
+ good_coroutine_calls_custom_constructor(float, int) {
+ co_return;
+ }
+ coro<good_promise_custom_constructor>
+ static good_coroutine_calls_custom_constructor(double, float, int) {
+ co_return;
+ }
+};
+
struct bad_promise_no_matching_constructor {
bad_promise_no_matching_constructor(int, int, int);
- // expected-note at +1 {{'bad_promise_no_matching_constructor' has been explicitly marked deleted here}}
+ // expected-note at +1 2 {{'bad_promise_no_matching_constructor' has been explicitly marked deleted here}}
bad_promise_no_matching_constructor() = delete;
coro<bad_promise_no_matching_constructor> get_return_object();
suspend_always initial_suspend();
@@ -1278,6 +1292,14 @@ bad_coroutine_calls_with_no_matching_con
co_return;
}
+struct some_class2 {
+coro<bad_promise_no_matching_constructor>
+bad_coroutine_calls_with_no_matching_constructor(int, int, int) {
+ // expected-error at -1 {{call to deleted constructor}}
+ co_return;
+}
+};
+
} // namespace CoroHandleMemberFunctionTest
class awaitable_no_unused_warn {
More information about the cfe-commits
mailing list