From d2e30d34b943470025ebcf0fe18f8925c2aac012 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Tue, 27 Mar 2018 03:15:46 +0000 Subject: [PATCH] [coroutines] Fix invalid source range in co_await call expressions. Summary: Currently an invalid source range is generated for the member call expressions of `co_await`. The end location of the call expression is the `co_await` token loc, while the start is the location of the operand. This causes crashes when the source range is used to produce diagnostics. This patch fixes the issues by using the expression location instead of the token location when building the member calls. Reviewers: GorNishanov, rsmith, vsk, aaron.ballman Reviewed By: vsk Subscribers: cfe-commits, modocache Differential Revision: https://reviews.llvm.org/D44915 llvm-svn: 328606 --- clang/lib/Sema/SemaCoroutine.cpp | 7 ++++- .../SemaCXX/coroutine-source-location-crash.cpp | 33 ++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 clang/test/SemaCXX/coroutine-source-location-crash.cpp diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp index e4cb4cf..95758ba 100644 --- a/clang/lib/Sema/SemaCoroutine.cpp +++ b/clang/lib/Sema/SemaCoroutine.cpp @@ -708,9 +708,14 @@ ExprResult Sema::BuildResolvedCoawaitExpr(SourceLocation Loc, Expr *E, if (E->getValueKind() == VK_RValue) E = CreateMaterializeTemporaryExpr(E->getType(), E, true); + // The location of the `co_await` token cannot be used when constructing + // the member call expressions since it's before the location of `Expr`, which + // is used as the start of the member call expression. + SourceLocation CallLoc = E->getExprLoc(); + // Build the await_ready, await_suspend, await_resume calls. ReadySuspendResumeResult RSS = - buildCoawaitCalls(*this, Coroutine->CoroutinePromise, Loc, E); + buildCoawaitCalls(*this, Coroutine->CoroutinePromise, CallLoc, E); if (RSS.IsInvalid) return ExprError(); diff --git a/clang/test/SemaCXX/coroutine-source-location-crash.cpp b/clang/test/SemaCXX/coroutine-source-location-crash.cpp new file mode 100644 index 0000000..04fb1d4 --- /dev/null +++ b/clang/test/SemaCXX/coroutine-source-location-crash.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts \ +// RUN: -fsyntax-only -ast-dump | FileCheck %s +#include "Inputs/std-coroutine.h" + +using namespace std::experimental; + +struct A { + bool await_ready(); + void await_resume(); + template + void await_suspend(F); +}; + +struct coro_t { + struct promise_type { + coro_t get_return_object(); + suspend_never initial_suspend(); + suspend_never final_suspend(); + void return_void(); + static void unhandled_exception(); + }; +}; + +// {{0x[0-9a-fA-F]+}} +// CHECK-LABEL: FunctionDecl {{.*}} f 'coro_t (int)' +coro_t f(int n) { + A a{}; + // CHECK: CoawaitExpr {{0x[0-9a-fA-F]+}} + // CHECK-NEXT: DeclRefExpr {{0x[0-9a-fA-F]+}} + // CHECK-NEXT: CXXMemberCallExpr {{0x[0-9a-fA-F]+}} + // CHECK-NEXT: MemberExpr {{0x[0-9a-fA-F]+}} + co_await a; +} -- 2.7.4