r300511 - Revert r300504 - [coroutines] Fix rebuilding of implicit and dependent coroutine statements.
Eric Fiselier via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 17 15:40:44 PDT 2017
Author: ericwf
Date: Mon Apr 17 17:40:44 2017
New Revision: 300511
URL: http://llvm.org/viewvc/llvm-project?rev=300511&view=rev
Log:
Revert r300504 - [coroutines] Fix rebuilding of implicit and dependent coroutine statements.
I have no idea what's happening here. The tests that fail on all of the bots
pass on my machine. Further investigation needed.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaCoroutine.cpp
cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
cfe/trunk/test/SemaCXX/coroutines.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=300511&r1=300510&r2=300511&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Apr 17 17:40:44 2017
@@ -8854,11 +8854,6 @@ def err_coroutine_invalid_func_context :
def err_implied_coroutine_type_not_found : Error<
"%0 type was not found; include <experimental/coroutine> before defining "
"a coroutine">;
-def err_implicit_coroutine_std_nothrow_type_not_found : Error<
- "std::nothrow was not found; include <new> before defining a coroutine which "
- "uses get_return_object_on_allocation_failure()">;
-def err_malformed_std_nothrow : Error<
- "std::nothrow must be a valid variable declaration">;
def err_malformed_std_coroutine_handle : Error<
"std::experimental::coroutine_handle must be a class template">;
def err_coroutine_handle_missing_member : Error<
@@ -8878,7 +8873,7 @@ def err_coroutine_promise_return_ill_for
"%0 declares both 'return_value' and 'return_void'">;
def note_coroutine_promise_implicit_await_transform_required_here : Note<
"call to 'await_transform' implicitly required by 'co_await' here">;
-def note_coroutine_promise_suspend_implicitly_required : Note<
+def note_coroutine_promise_call_implicitly_required : Note<
"call to '%select{initial_suspend|final_suspend}0' implicitly "
"required by the %select{initial suspend point|final suspend point}0">;
def err_coroutine_promise_unhandled_exception_required : Error<
@@ -8888,11 +8883,6 @@ def warn_coroutine_promise_unhandled_exc
InGroup<Coroutine>;
def err_coroutine_promise_get_return_object_on_allocation_failure : Error<
"%0: 'get_return_object_on_allocation_failure()' must be a static member function">;
-def err_coroutine_promise_new_requires_nothrow : Error<
- "%0 is required to have a non-throwing noexcept specification when the promise "
- "type declares 'get_return_object_on_allocation_failure()'">;
-def note_coroutine_promise_call_implicitly_required : Note<
- "call to %0 implicitly required by coroutine function here">;
}
let CategoryName = "Documentation Issue" in {
Modified: cfe/trunk/lib/Sema/SemaCoroutine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCoroutine.cpp?rev=300511&r1=300510&r2=300511&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Mon Apr 17 17:40:44 2017
@@ -454,7 +454,7 @@ static bool actOnCoroutineBodyStart(Sema
/*IsImplicit*/ true);
Suspend = S.ActOnFinishFullExpr(Suspend.get());
if (Suspend.isInvalid()) {
- S.Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
+ S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
<< ((Name == "initial_suspend") ? 0 : 1);
S.Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
return StmtError();
@@ -660,39 +660,6 @@ StmtResult Sema::BuildCoreturnStmt(Sourc
return Res;
}
-/// Look up the std::nothrow object.
-static Expr *buildStdNoThrowDeclRef(Sema &S, SourceLocation Loc) {
- NamespaceDecl *Std = S.getStdNamespace();
- assert(Std && "Should already be diagnosed");
-
- LookupResult Result(S, &S.PP.getIdentifierTable().get("nothrow"), Loc,
- Sema::LookupOrdinaryName);
- if (!S.LookupQualifiedName(Result, Std)) {
- // FIXME: <experimental/coroutine> should have been included already.
- // If we require it to include <new> then this diagnostic is no longer
- // needed.
- S.Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
- return nullptr;
- }
-
- // FIXME: Mark the variable as ODR used. This currently does not work
- // likely due to the scope at in which this function is called.
- auto *VD = Result.getAsSingle<VarDecl>();
- if (!VD) {
- Result.suppressDiagnostics();
- // We found something weird. Complain about the first thing we found.
- NamedDecl *Found = *Result.begin();
- S.Diag(Found->getLocation(), diag::err_malformed_std_nothrow);
- return nullptr;
- }
-
- ExprResult DR = S.BuildDeclRefExpr(VD, VD->getType(), VK_LValue, Loc);
- if (DR.isInvalid())
- return nullptr;
-
- return DR.get();
-}
-
// Find an appropriate delete for the promise.
static FunctionDecl *findDeleteForPromise(Sema &S, SourceLocation Loc,
QualType PromiseType) {
@@ -880,51 +847,23 @@ bool CoroutineStmtBuilder::makeNewAndDel
if (S.RequireCompleteType(Loc, PromiseType, diag::err_incomplete_type))
return false;
- const bool RequiresNoThrowAlloc = ReturnStmtOnAllocFailure != nullptr;
-
+ // FIXME: Add nothrow_t placement arg for global alloc
+ // if ReturnStmtOnAllocFailure != nullptr.
// FIXME: Add support for stateful allocators.
FunctionDecl *OperatorNew = nullptr;
FunctionDecl *OperatorDelete = nullptr;
FunctionDecl *UnusedResult = nullptr;
bool PassAlignment = false;
- MultiExprArg PlacementArgs = None;
S.FindAllocationFunctions(Loc, SourceRange(),
/*UseGlobal*/ false, PromiseType,
- /*isArray*/ false, PassAlignment, PlacementArgs,
- OperatorNew, UnusedResult);
+ /*isArray*/ false, PassAlignment,
+ /*PlacementArgs*/ None, OperatorNew, UnusedResult);
- bool IsGlobalOverload =
- OperatorNew && !isa<CXXRecordDecl>(OperatorNew->getDeclContext());
- // If we didn't find a class-local new declaration and non-throwing new
- // was is required then we need to lookup the non-throwing global operator
- // instead.
- if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
- auto *StdNoThrow = buildStdNoThrowDeclRef(S, Loc);
- if (!StdNoThrow)
- return false;
- PlacementArgs = MultiExprArg(StdNoThrow);
- OperatorNew = nullptr;
- S.FindAllocationFunctions(Loc, SourceRange(),
- /*UseGlobal*/ true, PromiseType,
- /*isArray*/ false, PassAlignment, PlacementArgs,
- OperatorNew, UnusedResult);
- }
-
- if (OperatorNew && RequiresNoThrowAlloc) {
- const auto *FT = OperatorNew->getType()->getAs<FunctionProtoType>();
- if (!FT->isNothrow(S.Context, /*ResultIfDependent*/ false)) {
- S.Diag(OperatorNew->getLocation(),
- diag::err_coroutine_promise_new_requires_nothrow)
- << OperatorNew;
- S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
- << OperatorNew;
- return false;
- }
- }
+ OperatorDelete = findDeleteForPromise(S, Loc, PromiseType);
- if ((OperatorDelete = findDeleteForPromise(S, Loc, PromiseType)) == nullptr)
+ if (!OperatorDelete || !OperatorNew)
return false;
Expr *FramePtr =
@@ -940,13 +879,8 @@ bool CoroutineStmtBuilder::makeNewAndDel
if (NewRef.isInvalid())
return false;
- SmallVector<Expr *, 2> NewArgs{FrameSize};
- for (auto Arg : PlacementArgs)
- NewArgs.push_back(Arg);
-
ExprResult NewExpr =
- S.ActOnCallExpr(S.getCurScope(), NewRef.get(), Loc, NewArgs, Loc);
- NewExpr = S.ActOnFinishFullExpr(NewExpr.get());
+ S.ActOnCallExpr(S.getCurScope(), NewRef.get(), Loc, FrameSize, Loc);
if (NewExpr.isInvalid())
return false;
@@ -972,7 +906,6 @@ bool CoroutineStmtBuilder::makeNewAndDel
ExprResult DeleteExpr =
S.ActOnCallExpr(S.getCurScope(), DeleteRef.get(), Loc, DeleteArgs, Loc);
- DeleteExpr = S.ActOnFinishFullExpr(DeleteExpr.get());
if (DeleteExpr.isInvalid())
return false;
Modified: cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp?rev=300511&r1=300510&r2=300511&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp (original)
+++ cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp Mon Apr 17 17:40:44 2017
@@ -19,19 +19,8 @@ struct coroutine_handle<void> {
coroutine_handle(coroutine_handle<PromiseType>) {}
};
-} // end namespace experimental
-
-struct nothrow_t {};
-constexpr nothrow_t nothrow = {};
-
-} // end namespace std
-
-// Required when get_return_object_on_allocation_failure() is defined by
-// the promise.
-using SizeT = decltype(sizeof(int));
-void* operator new(SizeT __sz, const std::nothrow_t&) noexcept;
-void operator delete(void* __p, const std::nothrow_t&) noexcept;
-
+}
+}
struct suspend_always {
bool await_ready() { return false; }
@@ -156,7 +145,7 @@ struct std::experimental::coroutine_trai
extern "C" int f4(promise_on_alloc_failure_tag) {
// CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16
// CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
- // CHECK: %[[MEM:.+]] = call i8* @_ZnwmRKSt9nothrow_t(i64 %[[SIZE]], %"struct.std::nothrow_t"* dereferenceable(1) @_ZStL7nothrow)
+ // CHECK: %[[MEM:.+]] = call i8* @_Znwm(i64 %[[SIZE]])
// CHECK: %[[OK:.+]] = icmp ne i8* %[[MEM]], null
// CHECK: br i1 %[[OK]], label %[[OKBB:.+]], label %[[ERRBB:.+]]
Modified: cfe/trunk/test/SemaCXX/coroutines.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/coroutines.cpp?rev=300511&r1=300510&r2=300511&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/coroutines.cpp (original)
+++ cfe/trunk/test/SemaCXX/coroutines.cpp Mon Apr 17 17:40:44 2017
@@ -654,18 +654,6 @@ float badly_specialized_coro_handle() {
co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
}
-namespace std {
- struct nothrow_t {};
- constexpr nothrow_t nothrow = {};
-}
-
-using SizeT = decltype(sizeof(int));
-
-void* operator new(SizeT __sz, const std::nothrow_t&) noexcept;
-void operator delete(void* __p, const std::nothrow_t&) noexcept;
-
-
-
struct promise_on_alloc_failure_tag {};
template<>
@@ -706,43 +694,3 @@ coro<T> dependent_private_alloc_failure_
}
template coro<bad_promise_11> dependent_private_alloc_failure_handler(bad_promise_11);
// expected-note at -1 {{requested here}}
-
-struct bad_promise_12 {
- coro<bad_promise_12> get_return_object();
- suspend_always initial_suspend();
- suspend_always final_suspend();
- void unhandled_exception();
- void return_void();
- static coro<bad_promise_12> get_return_object_on_allocation_failure();
-
- static void* operator new(SizeT);
- // expected-error at -1 2 {{'operator new' is required to have a non-throwing noexcept specification when the promise type declares 'get_return_object_on_allocation_failure()'}}
-};
-coro<bad_promise_12> throwing_in_class_new() { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
- co_return;
-}
-
-template <class T>
-coro<T> dependent_throwing_in_class_new(T) { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
- co_return;
-}
-template coro<bad_promise_12> dependent_throwing_in_class_new(bad_promise_12); // expected-note {{requested here}}
-
-
-struct good_promise_13 {
- coro<good_promise_13> get_return_object();
- suspend_always initial_suspend();
- suspend_always final_suspend();
- void unhandled_exception();
- void return_void();
- static coro<good_promise_13> get_return_object_on_allocation_failure();
-};
-coro<good_promise_13> uses_nothrow_new() {
- co_return;
-}
-
-template <class T>
-coro<T> dependent_uses_nothrow_new(T) {
- co_return;
-}
-template coro<good_promise_13> dependent_uses_nothrow_new(good_promise_13);
More information about the cfe-commits
mailing list