From d4507266c8c8f1bd99f7d3fcb86989cda2e16066 Mon Sep 17 00:00:00 2001 From: Gor Nishanov Date: Tue, 27 Mar 2018 20:38:19 +0000 Subject: [PATCH] [coroutines] Do not attempt to typo-correct when coroutine is looking for required members When SemaCoroutine looks for await_resume, it means it. No need for helpful: "Did you mean await_ready?" messages. Fixes PR33477 and a couple of FIXMEs in test/SemaCXX/coroutines.cpp llvm-svn: 328663 --- clang/lib/Sema/SemaCoroutine.cpp | 9 +++++++++ clang/test/SemaCXX/coroutines.cpp | 25 +++++++++++++++++++++---- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index 95758ba..139a210 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -362,6 +362,15 @@ static ExprResult buildMemberCall(Sema &S, Expr *Base, SourceLocation Loc, if (Result.isInvalid()) return ExprError(); + // We meant exactly what we asked for. No need for typo correction. + if (auto *TE = dyn_cast(Result.get())) { + S.clearDelayedTypo(TE); + S.Diag(Loc, diag::err_no_member) + << NameInfo.getName() << Base->getType()->getAsCXXRecordDecl() + << Base->getSourceRange(); + return ExprError(); + } + return S.ActOnCallExpr(nullptr, Result.get(), Loc, Args, Loc, nullptr); } diff --git a/clang/test/SemaCXX/coroutines.cpp b/clang/test/SemaCXX/coroutines.cpp index c09ca57..ed8fd90 100644 --- a/clang/test/SemaCXX/coroutines.cpp +++ b/clang/test/SemaCXX/coroutines.cpp @@ -510,8 +510,7 @@ coro missing_get_return_object() { // expected-error {{no member struct bad_promise_2 { coro get_return_object(); - // FIXME: We shouldn't offer a typo-correction here! - suspend_always final_suspend(); // expected-note {{here}} + suspend_always final_suspend(); void unhandled_exception(); void return_void(); }; @@ -522,8 +521,7 @@ coro missing_initial_suspend() { // expected-error {{no member na struct bad_promise_3 { coro get_return_object(); - // FIXME: We shouldn't offer a typo-correction here! - suspend_always initial_suspend(); // expected-note {{here}} + suspend_always initial_suspend(); void unhandled_exception(); void return_void(); }; @@ -1378,3 +1376,22 @@ test_unused_warning() { co_await awaitable_unused_warn(); // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} co_yield 42; // expected-warning {{ignoring return value of function declared with 'nodiscard' attribute}} } + +struct missing_await_ready { + void await_suspend(std::experimental::coroutine_handle<>); + void await_resume(); +}; +struct missing_await_suspend { + bool await_ready(); + void await_resume(); +}; +struct missing_await_resume { + bool await_ready(); + void await_suspend(std::experimental::coroutine_handle<>); +}; + +void test_missing_awaitable_members() { + co_await missing_await_ready{}; // expected-error {{no member named 'await_ready' in 'missing_await_ready'}} + co_await missing_await_suspend{}; // expected-error {{no member named 'await_suspend' in 'missing_await_suspend'}} + co_await missing_await_resume{}; // expected-error {{no member named 'await_resume' in 'missing_await_resume'}} +} -- 2.7.4