<div dir="ltr">LGTM</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Sep 28, 2016 at 10:09 PM, Eric Fiselier <span dir="ltr"><<a href="mailto:eric@efcs.ca" target="_blank">eric@efcs.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">EricWF created this revision.<br>
EricWF added reviewers: rsmith, GorNishanov.<br>
EricWF added a subscriber: cfe-commits.<br>
Herald added a subscriber: mehdi_amini.<br>
<br>
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()`.<br>
<br>
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.<br>
<br>
<a href="https://reviews.llvm.org/D25060" rel="noreferrer" target="_blank">https://reviews.llvm.org/<wbr>D25060</a><br>
<br>
Files:<br>
lib/Sema/SemaCoroutine.cpp<br>
test/SemaCXX/coroutines.cpp<br>
<br>
Index: test/SemaCXX/coroutines.cpp<br>
==============================<wbr>==============================<wbr>=======<br>
--- test/SemaCXX/coroutines.cpp<br>
+++ test/SemaCXX/coroutines.cpp<br>
@@ -1,5 +1,22 @@<br>
// RUN: %clang_cc1 -std=c++14 -fcoroutines -verify %s<br>
<br>
+void no_coroutine_traits_bad_arg_<wbr>await() {<br>
+ co_await a; // expected-error {{include <coroutine>}}<br>
+ // expected-error@-1 {{use of undeclared identifier 'a'}}<br>
+}<br>
+<br>
+void no_coroutine_traits_bad_arg_<wbr>yield() {<br>
+ co_yield a; // expected-error {{include <coroutine>}}<br>
+ // expected-error@-1 {{use of undeclared identifier 'a'}}<br>
+}<br>
+<br>
+<br>
+void no_coroutine_traits_bad_arg_<wbr>return() {<br>
+ co_return a; // expected-error {{include <coroutine>}}<br>
+ // expected-error@-1 {{use of undeclared identifier 'a'}}<br>
+}<br>
+<br>
+<br>
struct awaitable {<br>
bool await_ready();<br>
void await_suspend(); // FIXME: coroutine_handle<br>
Index: lib/Sema/SemaCoroutine.cpp<br>
==============================<wbr>==============================<wbr>=======<br>
--- lib/Sema/SemaCoroutine.cpp<br>
+++ lib/Sema/SemaCoroutine.cpp<br>
@@ -213,6 +213,11 @@<br>
}<br>
<br>
ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) {<br>
+ auto *Coroutine = checkCoroutineContext(*this, Loc, "co_await");<br>
+ if (!Coroutine) {<br>
+ CorrectDelayedTyposInExpr(E);<br>
+ return ExprError();<br>
+ }<br>
if (E->getType()-><wbr>isPlaceholderType()) {<br>
ExprResult R = CheckPlaceholderExpr(E);<br>
if (R.isInvalid()) return ExprError();<br>
@@ -222,6 +227,7 @@<br>
ExprResult Awaitable = buildOperatorCoawaitCall(*<wbr>this, S, Loc, E);<br>
if (Awaitable.isInvalid())<br>
return ExprError();<br>
+<br>
return BuildCoawaitExpr(Loc, Awaitable.get());<br>
}<br>
ExprResult Sema::BuildCoawaitExpr(<wbr>SourceLocation Loc, Expr *E) {<br>
@@ -275,8 +281,10 @@<br>
<br>
ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) {<br>
auto *Coroutine = checkCoroutineContext(*this, Loc, "co_yield");<br>
- if (!Coroutine)<br>
+ if (!Coroutine) {<br>
+ CorrectDelayedTyposInExpr(E);<br>
return ExprError();<br>
+ }<br>
<br>
// Build yield_value call.<br>
ExprResult Awaitable =<br>
@@ -325,6 +333,11 @@<br>
}<br>
<br>
StmtResult Sema::ActOnCoreturnStmt(<wbr>SourceLocation Loc, Expr *E) {<br>
+ auto *Coroutine = checkCoroutineContext(*this, Loc, "co_return");<br>
+ if (!Coroutine) {<br>
+ CorrectDelayedTyposInExpr(E);<br>
+ return StmtError();<br>
+ }<br>
return BuildCoreturnStmt(Loc, E);<br>
}<br>
StmtResult Sema::BuildCoreturnStmt(<wbr>SourceLocation Loc, Expr *E) {<br>
<br>
<br>
</blockquote></div><br></div>