From 76077868e268da8caec5f66d6cc62a03716e9e93 Mon Sep 17 00:00:00 2001
From: Eric Fiselier <eric@efcs.ca>
Date: Thu, 9 Mar 2017 05:01:31 +0000
Subject: [PATCH] [coroutines] Fix assertion in DependentCoawaitExpr when the
 argument is non-dependent.

Summary:
A `co_await arg` expression has a dependent type whenever the promise type is still dependent, even if the argument to co_await is not. This is because we cannot attempt the `await_transform(<arg>)` until after we know the promise type.

This patch fixes an assertion in the constructor of `DependentCoawaitExpr` that asserted that `arg` must also be dependent.

Reviewers: rsmith, GorNishanov, aaron.ballman

Reviewed By: GorNishanov

Subscribers: mehdi_amini, cfe-commits

Differential Revision: https://reviews.llvm.org/D30772

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@297358 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/AST/ExprCXX.h | 4 +++-
 test/SemaCXX/coroutines.cpp | 6 ++++++
 2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h
index cc7c5c90d4a..30d1d0b7563 100644
--- a/include/clang/AST/ExprCXX.h
+++ b/include/clang/AST/ExprCXX.h
@@ -4236,7 +4236,9 @@ public:
              /*InstantiationDependent*/ true,
              Op->containsUnexpandedParameterPack()),
         KeywordLoc(KeywordLoc) {
-    assert(Op->isTypeDependent() && Ty->isDependentType() &&
+    // NOTE: A co_await expression is dependent on the coroutines promise
+    // type and may be dependent even when the `Op` expression is not.
+    assert(Ty->isDependentType() &&
            "wrong constructor for non-dependent co_await/co_yield expression");
     SubExprs[0] = Op;
     SubExprs[1] = OpCoawait;
diff --git a/test/SemaCXX/coroutines.cpp b/test/SemaCXX/coroutines.cpp
index 9ff42a46d77..22fdcde1c21 100644
--- a/test/SemaCXX/coroutines.cpp
+++ b/test/SemaCXX/coroutines.cpp
@@ -151,6 +151,12 @@ void coreturn(int n) {
   co_return 42;
 }
 
+template <class T>
+void co_await_non_dependent_arg(T) {
+  co_await a;
+}
+template void co_await_non_dependent_arg(int);
+
 void mixed_yield() {
   co_yield 0; // expected-note {{use of 'co_yield'}}
   return; // expected-error {{not allowed in coroutine}}
-- 
GitLab