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@-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@-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); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits