[PATCH] D68845: Don't emit unwanted constructor calls in co_return statements
Aaron Puchert via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu Oct 10 17:59:02 PDT 2019
aaronpuchert updated this revision to Diff 224513.
aaronpuchert added a comment.
Also remove FIXME comment.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D68845/new/
https://reviews.llvm.org/D68845
Files:
clang/lib/Sema/SemaCoroutine.cpp
clang/test/SemaCXX/coroutine-rvo.cpp
Index: clang/test/SemaCXX/coroutine-rvo.cpp
===================================================================
--- clang/test/SemaCXX/coroutine-rvo.cpp
+++ clang/test/SemaCXX/coroutine-rvo.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -stdlib=libc++ -std=c++1z -fcoroutines-ts -fsyntax-only
+// RUN: %clang_cc1 -verify -std=c++17 -fcoroutines-ts -fsyntax-only %s
namespace std::experimental {
template <class Promise = void> struct coroutine_handle {
@@ -38,11 +38,17 @@
void await_resume() noexcept;
};
+struct Default {};
+
struct MoveOnly {
- MoveOnly() {};
+ MoveOnly() = default;
MoveOnly(const MoveOnly&) = delete;
- MoveOnly(MoveOnly&&) noexcept {};
- ~MoveOnly() {};
+ MoveOnly(MoveOnly&&) = default;
+};
+
+struct NoCopyNoMove {
+ NoCopyNoMove() = default;
+ NoCopyNoMove(const NoCopyNoMove&) = delete;
};
template <typename T>
@@ -52,18 +58,31 @@
auto final_suspend() { return suspend_never{}; }
auto get_return_object() { return task{}; }
static void unhandled_exception() {}
- void return_value(T&& value) {}
+ void return_value(T&& value) {} // expected-note 2{{passing argument}}
};
};
-task<MoveOnly> f() {
- MoveOnly value;
+task<NoCopyNoMove> local2val() {
+ NoCopyNoMove value;
co_return value;
}
-int main() {
- f();
- return 0;
+task<MoveOnly> param2val(MoveOnly value) {
+ co_return value;
}
-// expected-no-diagnostics
+task<Default> lvalue2val(Default& value) {
+ co_return value; // expected-error{{rvalue reference to type 'Default' cannot bind to lvalue of type 'Default'}}
+}
+
+task<NoCopyNoMove> rvalue2val(NoCopyNoMove&& value) {
+ co_return value;
+}
+
+task<NoCopyNoMove&> lvalue2ref(NoCopyNoMove& value) {
+ co_return value;
+}
+
+task<Default&> rvalue2ref(Default&& value) {
+ co_return value; // expected-error{{non-const lvalue reference to type 'Default' cannot bind to a temporary of type 'Default'}}
+}
Index: clang/lib/Sema/SemaCoroutine.cpp
===================================================================
--- clang/lib/Sema/SemaCoroutine.cpp
+++ clang/lib/Sema/SemaCoroutine.cpp
@@ -866,20 +866,13 @@
// Move the return value if we can
if (E) {
- auto NRVOCandidate = this->getCopyElisionCandidate(E->getType(), E, CES_AsIfByStdMove);
- if (NRVOCandidate) {
- InitializedEntity Entity =
- InitializedEntity::InitializeResult(Loc, E->getType(), NRVOCandidate);
- ExprResult MoveResult = this->PerformMoveOrCopyInitialization(
- Entity, NRVOCandidate, E->getType(), E);
- if (MoveResult.get())
- E = MoveResult.get();
- }
+ VarDecl *NRVOCandidate =
+ getCopyElisionCandidate(E->getType(), E, CES_Default);
+ if (NRVOCandidate && !NRVOCandidate->getType()->isLValueReferenceType())
+ E = ImplicitCastExpr::Create(Context, E->getType(), CK_NoOp, E, {},
+ VK_XValue);
}
- // FIXME: If the operand is a reference to a variable that's about to go out
- // of scope, we should treat the operand as an xvalue for this overload
- // resolution.
VarDecl *Promise = FSI->CoroutinePromise;
ExprResult PC;
if (E && (isa<InitListExpr>(E) || !E->getType()->isVoidType())) {
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D68845.224513.patch
Type: text/x-patch
Size: 3226 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20191011/eb4c1dd9/attachment.bin>
More information about the cfe-commits
mailing list