EricWF created this revision. EricWF added reviewers: rsmith, GorNishanov. EricWF added a subscriber: cfe-commits. Herald added a subscriber: mehdi_amini.
If there is an error finding the `coroutine_traits` template when building a coroutine AST nodes we throw away the remainder of the assignment expression. If the expression has uncorrected typo's this will trigger an assertion in `~Sema()`. This patch attempts to preemptively correct those typo's when we encounter an error building the coroutine nodes, at least for the case where the `coroutine_traits` template is invalid. https://reviews.llvm.org/D25060 Files: lib/Sema/SemaCoroutine.cpp test/SemaCXX/coroutines.cpp Index: test/SemaCXX/coroutines.cpp =================================================================== --- test/SemaCXX/coroutines.cpp +++ test/SemaCXX/coroutines.cpp @@ -1,5 +1,22 @@ // RUN: %clang_cc1 -std=c++14 -fcoroutines -verify %s +void no_coroutine_traits_bad_arg_await() { + co_await a; // expected-error {{include <coroutine>}} + // expected-error@-1 {{use of undeclared identifier 'a'}} +} + +void no_coroutine_traits_bad_arg_yield() { + co_yield a; // expected-error {{include <coroutine>}} + // expected-error@-1 {{use of undeclared identifier 'a'}} +} + + +void no_coroutine_traits_bad_arg_return() { + co_return a; // expected-error {{include <coroutine>}} + // expected-error@-1 {{use of undeclared identifier 'a'}} +} + + struct awaitable { bool await_ready(); void await_suspend(); // FIXME: coroutine_handle Index: lib/Sema/SemaCoroutine.cpp =================================================================== --- lib/Sema/SemaCoroutine.cpp +++ lib/Sema/SemaCoroutine.cpp @@ -213,6 +213,11 @@ } ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) { + auto *Coroutine = checkCoroutineContext(*this, Loc, "co_await"); + if (!Coroutine) { + CorrectDelayedTyposInExpr(E); + return ExprError(); + } if (E->getType()->isPlaceholderType()) { ExprResult R = CheckPlaceholderExpr(E); if (R.isInvalid()) return ExprError(); @@ -222,6 +227,7 @@ ExprResult Awaitable = buildOperatorCoawaitCall(*this, S, Loc, E); if (Awaitable.isInvalid()) return ExprError(); + return BuildCoawaitExpr(Loc, Awaitable.get()); } ExprResult Sema::BuildCoawaitExpr(SourceLocation Loc, Expr *E) { @@ -275,8 +281,10 @@ ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) { auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield"); - if (!Coroutine) + if (!Coroutine) { + CorrectDelayedTyposInExpr(E); return ExprError(); + } // Build yield_value call. ExprResult Awaitable = @@ -325,6 +333,11 @@ } StmtResult Sema::ActOnCoreturnStmt(SourceLocation Loc, Expr *E) { + auto *Coroutine = checkCoroutineContext(*this, Loc, "co_return"); + if (!Coroutine) { + CorrectDelayedTyposInExpr(E); + return StmtError(); + } return BuildCoreturnStmt(Loc, E); } StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E) {
Index: test/SemaCXX/coroutines.cpp =================================================================== --- test/SemaCXX/coroutines.cpp +++ test/SemaCXX/coroutines.cpp @@ -1,5 +1,22 @@ // RUN: %clang_cc1 -std=c++14 -fcoroutines -verify %s +void no_coroutine_traits_bad_arg_await() { + co_await a; // expected-error {{include <coroutine>}} + // expected-error@-1 {{use of undeclared identifier 'a'}} +} + +void no_coroutine_traits_bad_arg_yield() { + co_yield a; // expected-error {{include <coroutine>}} + // expected-error@-1 {{use of undeclared identifier 'a'}} +} + + +void no_coroutine_traits_bad_arg_return() { + co_return a; // expected-error {{include <coroutine>}} + // expected-error@-1 {{use of undeclared identifier 'a'}} +} + + struct awaitable { bool await_ready(); void await_suspend(); // FIXME: coroutine_handle Index: lib/Sema/SemaCoroutine.cpp =================================================================== --- lib/Sema/SemaCoroutine.cpp +++ lib/Sema/SemaCoroutine.cpp @@ -213,6 +213,11 @@ } ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) { + auto *Coroutine = checkCoroutineContext(*this, Loc, "co_await"); + if (!Coroutine) { + CorrectDelayedTyposInExpr(E); + return ExprError(); + } if (E->getType()->isPlaceholderType()) { ExprResult R = CheckPlaceholderExpr(E); if (R.isInvalid()) return ExprError(); @@ -222,6 +227,7 @@ ExprResult Awaitable = buildOperatorCoawaitCall(*this, S, Loc, E); if (Awaitable.isInvalid()) return ExprError(); + return BuildCoawaitExpr(Loc, Awaitable.get()); } ExprResult Sema::BuildCoawaitExpr(SourceLocation Loc, Expr *E) { @@ -275,8 +281,10 @@ ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) { auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield"); - if (!Coroutine) + if (!Coroutine) { + CorrectDelayedTyposInExpr(E); return ExprError(); + } // Build yield_value call. ExprResult Awaitable = @@ -325,6 +333,11 @@ } StmtResult Sema::ActOnCoreturnStmt(SourceLocation Loc, Expr *E) { + auto *Coroutine = checkCoroutineContext(*this, Loc, "co_return"); + if (!Coroutine) { + CorrectDelayedTyposInExpr(E); + return StmtError(); + } return BuildCoreturnStmt(Loc, E); } StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E) {
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits