1 //===-- SemaCoroutine.cpp - Semantic Analysis for Coroutines --------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements semantic analysis for C++ Coroutines.
11 // This file contains references to sections of the Coroutines TS, which
12 // can be found at http://wg21.link/coroutines.
14 //===----------------------------------------------------------------------===//
16 #include "CoroutineStmtBuilder.h"
17 #include "clang/AST/ASTLambda.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/ExprCXX.h"
20 #include "clang/AST/StmtCXX.h"
21 #include "clang/Basic/Builtins.h"
22 #include "clang/Lex/Preprocessor.h"
23 #include "clang/Sema/Initialization.h"
24 #include "clang/Sema/Overload.h"
25 #include "clang/Sema/ScopeInfo.h"
26 #include "clang/Sema/SemaInternal.h"
27 #include "llvm/ADT/SmallSet.h"
29 using namespace clang
;
32 static LookupResult
lookupMember(Sema
&S
, const char *Name
, CXXRecordDecl
*RD
,
33 SourceLocation Loc
, bool &Res
) {
34 DeclarationName DN
= S
.PP
.getIdentifierInfo(Name
);
35 LookupResult
LR(S
, DN
, Loc
, Sema::LookupMemberName
);
36 // Suppress diagnostics when a private member is selected. The same warnings
37 // will be produced again when building the call.
38 LR
.suppressDiagnostics();
39 Res
= S
.LookupQualifiedName(LR
, RD
);
43 static bool lookupMember(Sema
&S
, const char *Name
, CXXRecordDecl
*RD
,
46 lookupMember(S
, Name
, RD
, Loc
, Res
);
50 /// Look up the std::coroutine_traits<...>::promise_type for the given
52 static QualType
lookupPromiseType(Sema
&S
, const FunctionDecl
*FD
,
53 SourceLocation KwLoc
) {
54 const FunctionProtoType
*FnType
= FD
->getType()->castAs
<FunctionProtoType
>();
55 const SourceLocation FuncLoc
= FD
->getLocation();
57 ClassTemplateDecl
*CoroTraits
=
58 S
.lookupCoroutineTraits(KwLoc
, FuncLoc
);
62 // Form template argument list for coroutine_traits<R, P1, P2, ...> according
63 // to [dcl.fct.def.coroutine]3
64 TemplateArgumentListInfo
Args(KwLoc
, KwLoc
);
65 auto AddArg
= [&](QualType T
) {
66 Args
.addArgument(TemplateArgumentLoc(
67 TemplateArgument(T
), S
.Context
.getTrivialTypeSourceInfo(T
, KwLoc
)));
69 AddArg(FnType
->getReturnType());
70 // If the function is a non-static member function, add the type
71 // of the implicit object parameter before the formal parameters.
72 if (auto *MD
= dyn_cast
<CXXMethodDecl
>(FD
)) {
73 if (MD
->isImplicitObjectMemberFunction()) {
74 // [over.match.funcs]4
75 // For non-static member functions, the type of the implicit object
77 // -- "lvalue reference to cv X" for functions declared without a
78 // ref-qualifier or with the & ref-qualifier
79 // -- "rvalue reference to cv X" for functions declared with the &&
81 QualType T
= MD
->getFunctionObjectParameterType();
82 T
= FnType
->getRefQualifier() == RQ_RValue
83 ? S
.Context
.getRValueReferenceType(T
)
84 : S
.Context
.getLValueReferenceType(T
, /*SpelledAsLValue*/ true);
88 for (QualType T
: FnType
->getParamTypes())
91 // Build the template-id.
93 S
.CheckTemplateIdType(TemplateName(CoroTraits
), KwLoc
, Args
);
94 if (CoroTrait
.isNull())
96 if (S
.RequireCompleteType(KwLoc
, CoroTrait
,
97 diag::err_coroutine_type_missing_specialization
))
100 auto *RD
= CoroTrait
->getAsCXXRecordDecl();
101 assert(RD
&& "specialization of class template is not a class?");
103 // Look up the ::promise_type member.
104 LookupResult
R(S
, &S
.PP
.getIdentifierTable().get("promise_type"), KwLoc
,
105 Sema::LookupOrdinaryName
);
106 S
.LookupQualifiedName(R
, RD
);
107 auto *Promise
= R
.getAsSingle
<TypeDecl
>();
110 diag::err_implied_std_coroutine_traits_promise_type_not_found
)
114 // The promise type is required to be a class type.
115 QualType PromiseType
= S
.Context
.getTypeDeclType(Promise
);
117 auto buildElaboratedType
= [&]() {
118 auto *NNS
= NestedNameSpecifier::Create(S
.Context
, nullptr, S
.getStdNamespace());
119 NNS
= NestedNameSpecifier::Create(S
.Context
, NNS
, false,
120 CoroTrait
.getTypePtr());
121 return S
.Context
.getElaboratedType(ElaboratedTypeKeyword::None
, NNS
,
125 if (!PromiseType
->getAsCXXRecordDecl()) {
127 diag::err_implied_std_coroutine_traits_promise_type_not_class
)
128 << buildElaboratedType();
131 if (S
.RequireCompleteType(FuncLoc
, buildElaboratedType(),
132 diag::err_coroutine_promise_type_incomplete
))
138 /// Look up the std::coroutine_handle<PromiseType>.
139 static QualType
lookupCoroutineHandleType(Sema
&S
, QualType PromiseType
,
140 SourceLocation Loc
) {
141 if (PromiseType
.isNull())
144 NamespaceDecl
*CoroNamespace
= S
.getStdNamespace();
145 assert(CoroNamespace
&& "Should already be diagnosed");
147 LookupResult
Result(S
, &S
.PP
.getIdentifierTable().get("coroutine_handle"),
148 Loc
, Sema::LookupOrdinaryName
);
149 if (!S
.LookupQualifiedName(Result
, CoroNamespace
)) {
150 S
.Diag(Loc
, diag::err_implied_coroutine_type_not_found
)
151 << "std::coroutine_handle";
155 ClassTemplateDecl
*CoroHandle
= Result
.getAsSingle
<ClassTemplateDecl
>();
157 Result
.suppressDiagnostics();
158 // We found something weird. Complain about the first thing we found.
159 NamedDecl
*Found
= *Result
.begin();
160 S
.Diag(Found
->getLocation(), diag::err_malformed_std_coroutine_handle
);
164 // Form template argument list for coroutine_handle<Promise>.
165 TemplateArgumentListInfo
Args(Loc
, Loc
);
166 Args
.addArgument(TemplateArgumentLoc(
167 TemplateArgument(PromiseType
),
168 S
.Context
.getTrivialTypeSourceInfo(PromiseType
, Loc
)));
170 // Build the template-id.
171 QualType CoroHandleType
=
172 S
.CheckTemplateIdType(TemplateName(CoroHandle
), Loc
, Args
);
173 if (CoroHandleType
.isNull())
175 if (S
.RequireCompleteType(Loc
, CoroHandleType
,
176 diag::err_coroutine_type_missing_specialization
))
179 return CoroHandleType
;
182 static bool isValidCoroutineContext(Sema
&S
, SourceLocation Loc
,
184 // [expr.await]p2 dictates that 'co_await' and 'co_yield' must be used within
186 // FIXME: This also covers [expr.await]p2: "An await-expression shall not
187 // appear in a default argument." But the diagnostic QoI here could be
188 // improved to inform the user that default arguments specifically are not
190 auto *FD
= dyn_cast
<FunctionDecl
>(S
.CurContext
);
192 S
.Diag(Loc
, isa
<ObjCMethodDecl
>(S
.CurContext
)
193 ? diag::err_coroutine_objc_method
194 : diag::err_coroutine_outside_function
) << Keyword
;
198 // An enumeration for mapping the diagnostic type to the correct diagnostic
200 enum InvalidFuncDiag
{
209 bool Diagnosed
= false;
210 auto DiagInvalid
= [&](InvalidFuncDiag ID
) {
211 S
.Diag(Loc
, diag::err_coroutine_invalid_func_context
) << ID
<< Keyword
;
216 // Diagnose when a constructor, destructor
217 // or the function 'main' are declared as a coroutine.
218 auto *MD
= dyn_cast
<CXXMethodDecl
>(FD
);
219 // [class.ctor]p11: "A constructor shall not be a coroutine."
220 if (MD
&& isa
<CXXConstructorDecl
>(MD
))
221 return DiagInvalid(DiagCtor
);
222 // [class.dtor]p17: "A destructor shall not be a coroutine."
223 else if (MD
&& isa
<CXXDestructorDecl
>(MD
))
224 return DiagInvalid(DiagDtor
);
225 // [basic.start.main]p3: "The function main shall not be a coroutine."
226 else if (FD
->isMain())
227 return DiagInvalid(DiagMain
);
229 // Emit a diagnostics for each of the following conditions which is not met.
230 // [expr.const]p2: "An expression e is a core constant expression unless the
231 // evaluation of e [...] would evaluate one of the following expressions:
232 // [...] an await-expression [...] a yield-expression."
233 if (FD
->isConstexpr())
234 DiagInvalid(FD
->isConsteval() ? DiagConsteval
: DiagConstexpr
);
235 // [dcl.spec.auto]p15: "A function declared with a return type that uses a
236 // placeholder type shall not be a coroutine."
237 if (FD
->getReturnType()->isUndeducedType())
238 DiagInvalid(DiagAutoRet
);
239 // [dcl.fct.def.coroutine]p1
240 // The parameter-declaration-clause of the coroutine shall not terminate with
241 // an ellipsis that is not part of a parameter-declaration.
242 if (FD
->isVariadic())
243 DiagInvalid(DiagVarargs
);
248 /// Build a call to 'operator co_await' if there is a suitable operator for
249 /// the given expression.
250 ExprResult
Sema::BuildOperatorCoawaitCall(SourceLocation Loc
, Expr
*E
,
251 UnresolvedLookupExpr
*Lookup
) {
252 UnresolvedSet
<16> Functions
;
253 Functions
.append(Lookup
->decls_begin(), Lookup
->decls_end());
254 return CreateOverloadedUnaryOp(Loc
, UO_Coawait
, Functions
, E
);
257 static ExprResult
buildOperatorCoawaitCall(Sema
&SemaRef
, Scope
*S
,
258 SourceLocation Loc
, Expr
*E
) {
259 ExprResult R
= SemaRef
.BuildOperatorCoawaitLookupExpr(S
, Loc
);
262 return SemaRef
.BuildOperatorCoawaitCall(Loc
, E
,
263 cast
<UnresolvedLookupExpr
>(R
.get()));
266 static ExprResult
buildCoroutineHandle(Sema
&S
, QualType PromiseType
,
267 SourceLocation Loc
) {
268 QualType CoroHandleType
= lookupCoroutineHandleType(S
, PromiseType
, Loc
);
269 if (CoroHandleType
.isNull())
272 DeclContext
*LookupCtx
= S
.computeDeclContext(CoroHandleType
);
273 LookupResult
Found(S
, &S
.PP
.getIdentifierTable().get("from_address"), Loc
,
274 Sema::LookupOrdinaryName
);
275 if (!S
.LookupQualifiedName(Found
, LookupCtx
)) {
276 S
.Diag(Loc
, diag::err_coroutine_handle_missing_member
)
282 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_frame
, {});
285 ExprResult FromAddr
=
286 S
.BuildDeclarationNameExpr(SS
, Found
, /*NeedsADL=*/false);
287 if (FromAddr
.isInvalid())
290 return S
.BuildCallExpr(nullptr, FromAddr
.get(), Loc
, FramePtr
, Loc
);
293 struct ReadySuspendResumeResult
{
294 enum AwaitCallType
{ ACT_Ready
, ACT_Suspend
, ACT_Resume
};
296 OpaqueValueExpr
*OpaqueValue
;
300 static ExprResult
buildMemberCall(Sema
&S
, Expr
*Base
, SourceLocation Loc
,
301 StringRef Name
, MultiExprArg Args
) {
302 DeclarationNameInfo
NameInfo(&S
.PP
.getIdentifierTable().get(Name
), Loc
);
304 // FIXME: Fix BuildMemberReferenceExpr to take a const CXXScopeSpec&.
306 ExprResult Result
= S
.BuildMemberReferenceExpr(
307 Base
, Base
->getType(), Loc
, /*IsPtr=*/false, SS
,
308 SourceLocation(), nullptr, NameInfo
, /*TemplateArgs=*/nullptr,
310 if (Result
.isInvalid())
313 // We meant exactly what we asked for. No need for typo correction.
314 if (auto *TE
= dyn_cast
<TypoExpr
>(Result
.get())) {
315 S
.clearDelayedTypo(TE
);
316 S
.Diag(Loc
, diag::err_no_member
)
317 << NameInfo
.getName() << Base
->getType()->getAsCXXRecordDecl()
318 << Base
->getSourceRange();
322 auto EndLoc
= Args
.empty() ? Loc
: Args
.back()->getEndLoc();
323 return S
.BuildCallExpr(nullptr, Result
.get(), Loc
, Args
, EndLoc
, nullptr);
326 // See if return type is coroutine-handle and if so, invoke builtin coro-resume
327 // on its address. This is to enable the support for coroutine-handle
328 // returning await_suspend that results in a guaranteed tail call to the target
330 static Expr
*maybeTailCall(Sema
&S
, QualType RetType
, Expr
*E
,
331 SourceLocation Loc
) {
332 if (RetType
->isReferenceType())
334 Type
const *T
= RetType
.getTypePtr();
335 if (!T
->isClassType() && !T
->isStructureType())
338 // FIXME: Add convertability check to coroutine_handle<>. Possibly via
339 // EvaluateBinaryTypeTrait(BTT_IsConvertible, ...) which is at the moment
340 // a private function in SemaExprCXX.cpp
342 ExprResult AddressExpr
= buildMemberCall(S
, E
, Loc
, "address", std::nullopt
);
343 if (AddressExpr
.isInvalid())
346 Expr
*JustAddress
= AddressExpr
.get();
348 // FIXME: Without optimizations, the temporary result from `await_suspend()`
349 // may be put on the coroutine frame since the coroutine frame constructor
350 // will think the temporary variable will escape from the
351 // `coroutine_handle<>::address()` call. This is problematic since the
352 // coroutine should be considered to be suspended after it enters
353 // `await_suspend` so it shouldn't access/update the coroutine frame after
356 // See https://github.com/llvm/llvm-project/issues/65054 for the report.
358 // The long term solution may wrap the whole logic about `await-suspend`
359 // into a standalone function. This is similar to the proposed solution
360 // in tryMarkAwaitSuspendNoInline. See the comments there for details.
362 // The short term solution here is to mark `coroutine_handle<>::address()`
363 // function as always-inline so that the coroutine frame constructor won't
364 // think the temporary result is escaped incorrectly.
365 if (auto *FD
= cast
<CallExpr
>(JustAddress
)->getDirectCallee())
366 if (!FD
->hasAttr
<AlwaysInlineAttr
>() && !FD
->hasAttr
<NoInlineAttr
>())
367 FD
->addAttr(AlwaysInlineAttr::CreateImplicit(S
.getASTContext(),
370 // Check that the type of AddressExpr is void*
371 if (!JustAddress
->getType().getTypePtr()->isVoidPointerType())
372 S
.Diag(cast
<CallExpr
>(JustAddress
)->getCalleeDecl()->getLocation(),
373 diag::warn_coroutine_handle_address_invalid_return_type
)
374 << JustAddress
->getType();
376 // Clean up temporary objects so that they don't live across suspension points
377 // unnecessarily. We choose to clean up before the call to
378 // __builtin_coro_resume so that the cleanup code are not inserted in-between
379 // the resume call and return instruction, which would interfere with the
380 // musttail call contract.
381 JustAddress
= S
.MaybeCreateExprWithCleanups(JustAddress
);
382 return S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_resume
,
386 /// The await_suspend call performed by co_await is essentially asynchronous
387 /// to the execution of the coroutine. Inlining it normally into an unsplit
388 /// coroutine can cause miscompilation because the coroutine CFG misrepresents
389 /// the true control flow of the program: things that happen in the
390 /// await_suspend are not guaranteed to happen prior to the resumption of the
391 /// coroutine, and things that happen after the resumption of the coroutine
392 /// (including its exit and the potential deallocation of the coroutine frame)
393 /// are not guaranteed to happen only after the end of await_suspend.
395 /// See https://github.com/llvm/llvm-project/issues/56301 and
396 /// https://reviews.llvm.org/D157070 for the example and the full discussion.
398 /// The short-term solution to this problem is to mark the call as uninlinable.
399 /// But we don't want to do this if the call is known to be trivial, which is
402 /// The long-term solution may introduce patterns like:
404 /// call @llvm.coro.await_suspend(ptr %awaiter, ptr %handle,
405 /// ptr @awaitSuspendFn)
407 /// Then it is much easier to perform the safety analysis in the middle end.
408 /// If it is safe to inline the call to awaitSuspend, we can replace it in the
409 /// CoroEarly pass. Otherwise we could replace it in the CoroSplit pass.
410 static void tryMarkAwaitSuspendNoInline(Sema
&S
, OpaqueValueExpr
*Awaiter
,
411 CallExpr
*AwaitSuspend
) {
412 // The method here to extract the awaiter decl is not precise.
413 // This is intentional. Since it is hard to perform the analysis in the
414 // frontend due to the complexity of C++'s type systems.
415 // And we prefer to perform such analysis in the middle end since it is
416 // easier to implement and more powerful.
417 CXXRecordDecl
*AwaiterDecl
=
418 Awaiter
->getType().getNonReferenceType()->getAsCXXRecordDecl();
420 if (AwaiterDecl
&& AwaiterDecl
->field_empty())
423 FunctionDecl
*FD
= AwaitSuspend
->getDirectCallee();
427 // If the `await_suspend()` function is marked as `always_inline` explicitly,
428 // we should give the user the right to control the codegen.
429 if (FD
->hasAttr
<NoInlineAttr
>() || FD
->hasAttr
<AlwaysInlineAttr
>())
432 // This is problematic if the user calls the await_suspend standalone. But on
433 // the on hand, it is not incorrect semantically since inlining is not part
434 // of the standard. On the other hand, it is relatively rare to call
435 // the await_suspend function standalone.
437 // And given we've already had the long-term plan, the current workaround
438 // looks relatively tolerant.
440 NoInlineAttr::CreateImplicit(S
.getASTContext(), FD
->getLocation()));
443 /// Build calls to await_ready, await_suspend, and await_resume for a co_await
445 /// The generated AST tries to clean up temporary objects as early as
446 /// possible so that they don't live across suspension points if possible.
447 /// Having temporary objects living across suspension points unnecessarily can
448 /// lead to large frame size, and also lead to memory corruptions if the
449 /// coroutine frame is destroyed after coming back from suspension. This is done
450 /// by wrapping both the await_ready call and the await_suspend call with
451 /// ExprWithCleanups. In the end of this function, we also need to explicitly
452 /// set cleanup state so that the CoawaitExpr is also wrapped with an
453 /// ExprWithCleanups to clean up the awaiter associated with the co_await
455 static ReadySuspendResumeResult
buildCoawaitCalls(Sema
&S
, VarDecl
*CoroPromise
,
456 SourceLocation Loc
, Expr
*E
) {
457 OpaqueValueExpr
*Operand
= new (S
.Context
)
458 OpaqueValueExpr(Loc
, E
->getType(), VK_LValue
, E
->getObjectKind(), E
);
460 // Assume valid until we see otherwise.
461 // Further operations are responsible for setting IsInalid to true.
462 ReadySuspendResumeResult Calls
= {{}, Operand
, /*IsInvalid=*/false};
464 using ACT
= ReadySuspendResumeResult::AwaitCallType
;
466 auto BuildSubExpr
= [&](ACT CallType
, StringRef Func
,
467 MultiExprArg Arg
) -> Expr
* {
468 ExprResult Result
= buildMemberCall(S
, Operand
, Loc
, Func
, Arg
);
469 if (Result
.isInvalid()) {
470 Calls
.IsInvalid
= true;
473 Calls
.Results
[CallType
] = Result
.get();
477 CallExpr
*AwaitReady
= cast_or_null
<CallExpr
>(
478 BuildSubExpr(ACT::ACT_Ready
, "await_ready", std::nullopt
));
481 if (!AwaitReady
->getType()->isDependentType()) {
482 // [expr.await]p3 [...]
483 // — await-ready is the expression e.await_ready(), contextually converted
485 ExprResult Conv
= S
.PerformContextuallyConvertToBool(AwaitReady
);
486 if (Conv
.isInvalid()) {
487 S
.Diag(AwaitReady
->getDirectCallee()->getBeginLoc(),
488 diag::note_await_ready_no_bool_conversion
);
489 S
.Diag(Loc
, diag::note_coroutine_promise_call_implicitly_required
)
490 << AwaitReady
->getDirectCallee() << E
->getSourceRange();
491 Calls
.IsInvalid
= true;
493 Calls
.Results
[ACT::ACT_Ready
] = S
.MaybeCreateExprWithCleanups(Conv
.get());
496 ExprResult CoroHandleRes
=
497 buildCoroutineHandle(S
, CoroPromise
->getType(), Loc
);
498 if (CoroHandleRes
.isInvalid()) {
499 Calls
.IsInvalid
= true;
502 Expr
*CoroHandle
= CoroHandleRes
.get();
503 CallExpr
*AwaitSuspend
= cast_or_null
<CallExpr
>(
504 BuildSubExpr(ACT::ACT_Suspend
, "await_suspend", CoroHandle
));
507 if (!AwaitSuspend
->getType()->isDependentType()) {
508 // [expr.await]p3 [...]
509 // - await-suspend is the expression e.await_suspend(h), which shall be
510 // a prvalue of type void, bool, or std::coroutine_handle<Z> for some
512 QualType RetType
= AwaitSuspend
->getCallReturnType(S
.Context
);
514 // We need to mark await_suspend as noinline temporarily. See the comment
515 // of tryMarkAwaitSuspendNoInline for details.
516 tryMarkAwaitSuspendNoInline(S
, Operand
, AwaitSuspend
);
518 // Support for coroutine_handle returning await_suspend.
519 if (Expr
*TailCallSuspend
=
520 maybeTailCall(S
, RetType
, AwaitSuspend
, Loc
))
521 // Note that we don't wrap the expression with ExprWithCleanups here
522 // because that might interfere with tailcall contract (e.g. inserting
523 // clean up instructions in-between tailcall and return). Instead
524 // ExprWithCleanups is wrapped within maybeTailCall() prior to the resume
526 Calls
.Results
[ACT::ACT_Suspend
] = TailCallSuspend
;
528 // non-class prvalues always have cv-unqualified types
529 if (RetType
->isReferenceType() ||
530 (!RetType
->isBooleanType() && !RetType
->isVoidType())) {
531 S
.Diag(AwaitSuspend
->getCalleeDecl()->getLocation(),
532 diag::err_await_suspend_invalid_return_type
)
534 S
.Diag(Loc
, diag::note_coroutine_promise_call_implicitly_required
)
535 << AwaitSuspend
->getDirectCallee();
536 Calls
.IsInvalid
= true;
538 Calls
.Results
[ACT::ACT_Suspend
] =
539 S
.MaybeCreateExprWithCleanups(AwaitSuspend
);
543 BuildSubExpr(ACT::ACT_Resume
, "await_resume", std::nullopt
);
545 // Make sure the awaiter object gets a chance to be cleaned up.
546 S
.Cleanup
.setExprNeedsCleanups(true);
551 static ExprResult
buildPromiseCall(Sema
&S
, VarDecl
*Promise
,
552 SourceLocation Loc
, StringRef Name
,
555 // Form a reference to the promise.
556 ExprResult PromiseRef
= S
.BuildDeclRefExpr(
557 Promise
, Promise
->getType().getNonReferenceType(), VK_LValue
, Loc
);
558 if (PromiseRef
.isInvalid())
561 return buildMemberCall(S
, PromiseRef
.get(), Loc
, Name
, Args
);
564 VarDecl
*Sema::buildCoroutinePromise(SourceLocation Loc
) {
565 assert(isa
<FunctionDecl
>(CurContext
) && "not in a function scope");
566 auto *FD
= cast
<FunctionDecl
>(CurContext
);
567 bool IsThisDependentType
= [&] {
568 if (const auto *MD
= dyn_cast_if_present
<CXXMethodDecl
>(FD
))
569 return MD
->isImplicitObjectMemberFunction() &&
570 MD
->getThisType()->isDependentType();
574 QualType T
= FD
->getType()->isDependentType() || IsThisDependentType
575 ? Context
.DependentTy
576 : lookupPromiseType(*this, FD
, Loc
);
580 auto *VD
= VarDecl::Create(Context
, FD
, FD
->getLocation(), FD
->getLocation(),
581 &PP
.getIdentifierTable().get("__promise"), T
,
582 Context
.getTrivialTypeSourceInfo(T
, Loc
), SC_None
);
584 CheckVariableDeclarationType(VD
);
585 if (VD
->isInvalidDecl())
588 auto *ScopeInfo
= getCurFunction();
590 // Build a list of arguments, based on the coroutine function's arguments,
591 // that if present will be passed to the promise type's constructor.
592 llvm::SmallVector
<Expr
*, 4> CtorArgExprs
;
594 // Add implicit object parameter.
595 if (auto *MD
= dyn_cast
<CXXMethodDecl
>(FD
)) {
596 if (MD
->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD
)) {
597 ExprResult ThisExpr
= ActOnCXXThis(Loc
);
598 if (ThisExpr
.isInvalid())
600 ThisExpr
= CreateBuiltinUnaryOp(Loc
, UO_Deref
, ThisExpr
.get());
601 if (ThisExpr
.isInvalid())
603 CtorArgExprs
.push_back(ThisExpr
.get());
607 // Add the coroutine function's parameters.
608 auto &Moves
= ScopeInfo
->CoroutineParameterMoves
;
609 for (auto *PD
: FD
->parameters()) {
610 if (PD
->getType()->isDependentType())
613 auto RefExpr
= ExprEmpty();
614 auto Move
= Moves
.find(PD
);
615 assert(Move
!= Moves
.end() &&
616 "Coroutine function parameter not inserted into move map");
617 // If a reference to the function parameter exists in the coroutine
618 // frame, use that reference.
620 cast
<VarDecl
>(cast
<DeclStmt
>(Move
->second
)->getSingleDecl());
622 BuildDeclRefExpr(MoveDecl
, MoveDecl
->getType().getNonReferenceType(),
623 ExprValueKind::VK_LValue
, FD
->getLocation());
624 if (RefExpr
.isInvalid())
626 CtorArgExprs
.push_back(RefExpr
.get());
629 // If we have a non-zero number of constructor arguments, try to use them.
630 // Otherwise, fall back to the promise type's default constructor.
631 if (!CtorArgExprs
.empty()) {
632 // Create an initialization sequence for the promise type using the
633 // constructor arguments, wrapped in a parenthesized list expression.
634 Expr
*PLE
= ParenListExpr::Create(Context
, FD
->getLocation(),
635 CtorArgExprs
, FD
->getLocation());
636 InitializedEntity Entity
= InitializedEntity::InitializeVariable(VD
);
637 InitializationKind Kind
= InitializationKind::CreateForInit(
638 VD
->getLocation(), /*DirectInit=*/true, PLE
);
639 InitializationSequence
InitSeq(*this, Entity
, Kind
, CtorArgExprs
,
640 /*TopLevelOfInitList=*/false,
641 /*TreatUnavailableAsInvalid=*/false);
643 // [dcl.fct.def.coroutine]5.7
644 // promise-constructor-arguments is determined as follows: overload
645 // resolution is performed on a promise constructor call created by
646 // assembling an argument list q_1 ... q_n . If a viable constructor is
647 // found ([over.match.viable]), then promise-constructor-arguments is ( q_1
648 // , ..., q_n ), otherwise promise-constructor-arguments is empty.
650 ExprResult Result
= InitSeq
.Perform(*this, Entity
, Kind
, CtorArgExprs
);
651 if (Result
.isInvalid()) {
652 VD
->setInvalidDecl();
653 } else if (Result
.get()) {
654 VD
->setInit(MaybeCreateExprWithCleanups(Result
.get()));
655 VD
->setInitStyle(VarDecl::CallInit
);
656 CheckCompleteVariableDeclaration(VD
);
659 ActOnUninitializedDecl(VD
);
661 ActOnUninitializedDecl(VD
);
667 /// Check that this is a context in which a coroutine suspension can appear.
668 static FunctionScopeInfo
*checkCoroutineContext(Sema
&S
, SourceLocation Loc
,
670 bool IsImplicit
= false) {
671 if (!isValidCoroutineContext(S
, Loc
, Keyword
))
674 assert(isa
<FunctionDecl
>(S
.CurContext
) && "not in a function scope");
676 auto *ScopeInfo
= S
.getCurFunction();
677 assert(ScopeInfo
&& "missing function scope for function");
679 if (ScopeInfo
->FirstCoroutineStmtLoc
.isInvalid() && !IsImplicit
)
680 ScopeInfo
->setFirstCoroutineStmt(Loc
, Keyword
);
682 if (ScopeInfo
->CoroutinePromise
)
685 if (!S
.buildCoroutineParameterMoves(Loc
))
688 ScopeInfo
->CoroutinePromise
= S
.buildCoroutinePromise(Loc
);
689 if (!ScopeInfo
->CoroutinePromise
)
695 /// Recursively check \p E and all its children to see if any call target
696 /// (including constructor call) is declared noexcept. Also any value returned
697 /// from the call has a noexcept destructor.
698 static void checkNoThrow(Sema
&S
, const Stmt
*E
,
699 llvm::SmallPtrSetImpl
<const Decl
*> &ThrowingDecls
) {
700 auto checkDeclNoexcept
= [&](const Decl
*D
, bool IsDtor
= false) {
701 // In the case of dtor, the call to dtor is implicit and hence we should
702 // pass nullptr to canCalleeThrow.
703 if (Sema::canCalleeThrow(S
, IsDtor
? nullptr : cast
<Expr
>(E
), D
)) {
704 if (const auto *FD
= dyn_cast
<FunctionDecl
>(D
)) {
705 // co_await promise.final_suspend() could end up calling
706 // __builtin_coro_resume for symmetric transfer if await_suspend()
707 // returns a handle. In that case, even __builtin_coro_resume is not
708 // declared as noexcept and may throw, it does not throw _into_ the
709 // coroutine that just suspended, but rather throws back out from
710 // whoever called coroutine_handle::resume(), hence we claim that
711 // logically it does not throw.
712 if (FD
->getBuiltinID() == Builtin::BI__builtin_coro_resume
)
715 if (ThrowingDecls
.empty()) {
716 // [dcl.fct.def.coroutine]p15
717 // The expression co_await promise.final_suspend() shall not be
718 // potentially-throwing ([except.spec]).
720 // First time seeing an error, emit the error message.
721 S
.Diag(cast
<FunctionDecl
>(S
.CurContext
)->getLocation(),
722 diag::err_coroutine_promise_final_suspend_requires_nothrow
);
724 ThrowingDecls
.insert(D
);
728 if (auto *CE
= dyn_cast
<CXXConstructExpr
>(E
)) {
729 CXXConstructorDecl
*Ctor
= CE
->getConstructor();
730 checkDeclNoexcept(Ctor
);
731 // Check the corresponding destructor of the constructor.
732 checkDeclNoexcept(Ctor
->getParent()->getDestructor(), /*IsDtor=*/true);
733 } else if (auto *CE
= dyn_cast
<CallExpr
>(E
)) {
734 if (CE
->isTypeDependent())
737 checkDeclNoexcept(CE
->getCalleeDecl());
738 QualType ReturnType
= CE
->getCallReturnType(S
.getASTContext());
739 // Check the destructor of the call return type, if any.
740 if (ReturnType
.isDestructedType() ==
741 QualType::DestructionKind::DK_cxx_destructor
) {
743 cast
<RecordType
>(ReturnType
.getCanonicalType().getTypePtr());
744 checkDeclNoexcept(cast
<CXXRecordDecl
>(T
->getDecl())->getDestructor(),
748 for (const auto *Child
: E
->children()) {
751 checkNoThrow(S
, Child
, ThrowingDecls
);
755 bool Sema::checkFinalSuspendNoThrow(const Stmt
*FinalSuspend
) {
756 llvm::SmallPtrSet
<const Decl
*, 4> ThrowingDecls
;
757 // We first collect all declarations that should not throw but not declared
758 // with noexcept. We then sort them based on the location before printing.
759 // This is to avoid emitting the same note multiple times on the same
760 // declaration, and also provide a deterministic order for the messages.
761 checkNoThrow(*this, FinalSuspend
, ThrowingDecls
);
762 auto SortedDecls
= llvm::SmallVector
<const Decl
*, 4>{ThrowingDecls
.begin(),
763 ThrowingDecls
.end()};
764 sort(SortedDecls
, [](const Decl
*A
, const Decl
*B
) {
765 return A
->getEndLoc() < B
->getEndLoc();
767 for (const auto *D
: SortedDecls
) {
768 Diag(D
->getEndLoc(), diag::note_coroutine_function_declare_noexcept
);
770 return ThrowingDecls
.empty();
773 bool Sema::ActOnCoroutineBodyStart(Scope
*SC
, SourceLocation KWLoc
,
775 if (!checkCoroutineContext(*this, KWLoc
, Keyword
))
777 auto *ScopeInfo
= getCurFunction();
778 assert(ScopeInfo
->CoroutinePromise
);
780 // If we have existing coroutine statements then we have already built
781 // the initial and final suspend points.
782 if (!ScopeInfo
->NeedsCoroutineSuspends
)
785 ScopeInfo
->setNeedsCoroutineSuspends(false);
787 auto *Fn
= cast
<FunctionDecl
>(CurContext
);
788 SourceLocation Loc
= Fn
->getLocation();
789 // Build the initial suspend point
790 auto buildSuspends
= [&](StringRef Name
) mutable -> StmtResult
{
791 ExprResult Operand
= buildPromiseCall(*this, ScopeInfo
->CoroutinePromise
,
792 Loc
, Name
, std::nullopt
);
793 if (Operand
.isInvalid())
796 buildOperatorCoawaitCall(*this, SC
, Loc
, Operand
.get());
797 if (Suspend
.isInvalid())
799 Suspend
= BuildResolvedCoawaitExpr(Loc
, Operand
.get(), Suspend
.get(),
800 /*IsImplicit*/ true);
801 Suspend
= ActOnFinishFullExpr(Suspend
.get(), /*DiscardedValue*/ false);
802 if (Suspend
.isInvalid()) {
803 Diag(Loc
, diag::note_coroutine_promise_suspend_implicitly_required
)
804 << ((Name
== "initial_suspend") ? 0 : 1);
805 Diag(KWLoc
, diag::note_declared_coroutine_here
) << Keyword
;
808 return cast
<Stmt
>(Suspend
.get());
811 StmtResult InitSuspend
= buildSuspends("initial_suspend");
812 if (InitSuspend
.isInvalid())
815 StmtResult FinalSuspend
= buildSuspends("final_suspend");
816 if (FinalSuspend
.isInvalid() || !checkFinalSuspendNoThrow(FinalSuspend
.get()))
819 ScopeInfo
->setCoroutineSuspends(InitSuspend
.get(), FinalSuspend
.get());
824 // Recursively walks up the scope hierarchy until either a 'catch' or a function
825 // scope is found, whichever comes first.
826 static bool isWithinCatchScope(Scope
*S
) {
827 // 'co_await' and 'co_yield' keywords are disallowed within catch blocks, but
828 // lambdas that use 'co_await' are allowed. The loop below ends when a
829 // function scope is found in order to ensure the following behavior:
831 // void foo() { // <- function scope
833 // co_await x; // <- 'co_await' is OK within a function scope
834 // } catch { // <- catch scope
835 // co_await x; // <- 'co_await' is not OK within a catch scope
836 // []() { // <- function scope
837 // co_await x; // <- 'co_await' is OK within a function scope
841 while (S
&& !S
->isFunctionScope()) {
842 if (S
->isCatchScope())
849 // [expr.await]p2, emphasis added: "An await-expression shall appear only in
850 // a *potentially evaluated* expression within the compound-statement of a
851 // function-body *outside of a handler* [...] A context within a function
852 // where an await-expression can appear is called a suspension context of the
854 static bool checkSuspensionContext(Sema
&S
, SourceLocation Loc
,
856 // First emphasis of [expr.await]p2: must be a potentially evaluated context.
857 // That is, 'co_await' and 'co_yield' cannot appear in subexpressions of
859 if (S
.isUnevaluatedContext()) {
860 S
.Diag(Loc
, diag::err_coroutine_unevaluated_context
) << Keyword
;
864 // Second emphasis of [expr.await]p2: must be outside of an exception handler.
865 if (isWithinCatchScope(S
.getCurScope())) {
866 S
.Diag(Loc
, diag::err_coroutine_within_handler
) << Keyword
;
873 ExprResult
Sema::ActOnCoawaitExpr(Scope
*S
, SourceLocation Loc
, Expr
*E
) {
874 if (!checkSuspensionContext(*this, Loc
, "co_await"))
877 if (!ActOnCoroutineBodyStart(S
, Loc
, "co_await")) {
878 CorrectDelayedTyposInExpr(E
);
882 if (E
->hasPlaceholderType()) {
883 ExprResult R
= CheckPlaceholderExpr(E
);
884 if (R
.isInvalid()) return ExprError();
887 ExprResult Lookup
= BuildOperatorCoawaitLookupExpr(S
, Loc
);
888 if (Lookup
.isInvalid())
890 return BuildUnresolvedCoawaitExpr(Loc
, E
,
891 cast
<UnresolvedLookupExpr
>(Lookup
.get()));
894 ExprResult
Sema::BuildOperatorCoawaitLookupExpr(Scope
*S
, SourceLocation Loc
) {
895 DeclarationName OpName
=
896 Context
.DeclarationNames
.getCXXOperatorName(OO_Coawait
);
897 LookupResult
Operators(*this, OpName
, SourceLocation(),
898 Sema::LookupOperatorName
);
899 LookupName(Operators
, S
);
901 assert(!Operators
.isAmbiguous() && "Operator lookup cannot be ambiguous");
902 const auto &Functions
= Operators
.asUnresolvedSet();
904 Functions
.size() > 1 ||
905 (Functions
.size() == 1 && isa
<FunctionTemplateDecl
>(*Functions
.begin()));
906 Expr
*CoawaitOp
= UnresolvedLookupExpr::Create(
907 Context
, /*NamingClass*/ nullptr, NestedNameSpecifierLoc(),
908 DeclarationNameInfo(OpName
, Loc
), /*RequiresADL*/ true, IsOverloaded
,
909 Functions
.begin(), Functions
.end());
914 // Attempts to resolve and build a CoawaitExpr from "raw" inputs, bailing out to
915 // DependentCoawaitExpr if needed.
916 ExprResult
Sema::BuildUnresolvedCoawaitExpr(SourceLocation Loc
, Expr
*Operand
,
917 UnresolvedLookupExpr
*Lookup
) {
918 auto *FSI
= checkCoroutineContext(*this, Loc
, "co_await");
922 if (Operand
->hasPlaceholderType()) {
923 ExprResult R
= CheckPlaceholderExpr(Operand
);
929 auto *Promise
= FSI
->CoroutinePromise
;
930 if (Promise
->getType()->isDependentType()) {
931 Expr
*Res
= new (Context
)
932 DependentCoawaitExpr(Loc
, Context
.DependentTy
, Operand
, Lookup
);
936 auto *RD
= Promise
->getType()->getAsCXXRecordDecl();
937 auto *Transformed
= Operand
;
938 if (lookupMember(*this, "await_transform", RD
, Loc
)) {
940 buildPromiseCall(*this, Promise
, Loc
, "await_transform", Operand
);
943 diag::note_coroutine_promise_implicit_await_transform_required_here
)
944 << Operand
->getSourceRange();
947 Transformed
= R
.get();
949 ExprResult Awaiter
= BuildOperatorCoawaitCall(Loc
, Transformed
, Lookup
);
950 if (Awaiter
.isInvalid())
953 return BuildResolvedCoawaitExpr(Loc
, Operand
, Awaiter
.get());
956 ExprResult
Sema::BuildResolvedCoawaitExpr(SourceLocation Loc
, Expr
*Operand
,
957 Expr
*Awaiter
, bool IsImplicit
) {
958 auto *Coroutine
= checkCoroutineContext(*this, Loc
, "co_await", IsImplicit
);
962 if (Awaiter
->hasPlaceholderType()) {
963 ExprResult R
= CheckPlaceholderExpr(Awaiter
);
964 if (R
.isInvalid()) return ExprError();
968 if (Awaiter
->getType()->isDependentType()) {
969 Expr
*Res
= new (Context
)
970 CoawaitExpr(Loc
, Context
.DependentTy
, Operand
, Awaiter
, IsImplicit
);
974 // If the expression is a temporary, materialize it as an lvalue so that we
975 // can use it multiple times.
976 if (Awaiter
->isPRValue())
977 Awaiter
= CreateMaterializeTemporaryExpr(Awaiter
->getType(), Awaiter
, true);
979 // The location of the `co_await` token cannot be used when constructing
980 // the member call expressions since it's before the location of `Expr`, which
981 // is used as the start of the member call expression.
982 SourceLocation CallLoc
= Awaiter
->getExprLoc();
984 // Build the await_ready, await_suspend, await_resume calls.
985 ReadySuspendResumeResult RSS
=
986 buildCoawaitCalls(*this, Coroutine
->CoroutinePromise
, CallLoc
, Awaiter
);
990 Expr
*Res
= new (Context
)
991 CoawaitExpr(Loc
, Operand
, Awaiter
, RSS
.Results
[0], RSS
.Results
[1],
992 RSS
.Results
[2], RSS
.OpaqueValue
, IsImplicit
);
997 ExprResult
Sema::ActOnCoyieldExpr(Scope
*S
, SourceLocation Loc
, Expr
*E
) {
998 if (!checkSuspensionContext(*this, Loc
, "co_yield"))
1001 if (!ActOnCoroutineBodyStart(S
, Loc
, "co_yield")) {
1002 CorrectDelayedTyposInExpr(E
);
1006 // Build yield_value call.
1007 ExprResult Awaitable
= buildPromiseCall(
1008 *this, getCurFunction()->CoroutinePromise
, Loc
, "yield_value", E
);
1009 if (Awaitable
.isInvalid())
1012 // Build 'operator co_await' call.
1013 Awaitable
= buildOperatorCoawaitCall(*this, S
, Loc
, Awaitable
.get());
1014 if (Awaitable
.isInvalid())
1017 return BuildCoyieldExpr(Loc
, Awaitable
.get());
1019 ExprResult
Sema::BuildCoyieldExpr(SourceLocation Loc
, Expr
*E
) {
1020 auto *Coroutine
= checkCoroutineContext(*this, Loc
, "co_yield");
1024 if (E
->hasPlaceholderType()) {
1025 ExprResult R
= CheckPlaceholderExpr(E
);
1026 if (R
.isInvalid()) return ExprError();
1032 if (E
->getType()->isDependentType()) {
1033 Expr
*Res
= new (Context
) CoyieldExpr(Loc
, Context
.DependentTy
, Operand
, E
);
1037 // If the expression is a temporary, materialize it as an lvalue so that we
1038 // can use it multiple times.
1040 E
= CreateMaterializeTemporaryExpr(E
->getType(), E
, true);
1042 // Build the await_ready, await_suspend, await_resume calls.
1043 ReadySuspendResumeResult RSS
= buildCoawaitCalls(
1044 *this, Coroutine
->CoroutinePromise
, Loc
, E
);
1049 new (Context
) CoyieldExpr(Loc
, Operand
, E
, RSS
.Results
[0], RSS
.Results
[1],
1050 RSS
.Results
[2], RSS
.OpaqueValue
);
1055 StmtResult
Sema::ActOnCoreturnStmt(Scope
*S
, SourceLocation Loc
, Expr
*E
) {
1056 if (!ActOnCoroutineBodyStart(S
, Loc
, "co_return")) {
1057 CorrectDelayedTyposInExpr(E
);
1060 return BuildCoreturnStmt(Loc
, E
);
1063 StmtResult
Sema::BuildCoreturnStmt(SourceLocation Loc
, Expr
*E
,
1065 auto *FSI
= checkCoroutineContext(*this, Loc
, "co_return", IsImplicit
);
1069 if (E
&& E
->hasPlaceholderType() &&
1070 !E
->hasPlaceholderType(BuiltinType::Overload
)) {
1071 ExprResult R
= CheckPlaceholderExpr(E
);
1072 if (R
.isInvalid()) return StmtError();
1076 VarDecl
*Promise
= FSI
->CoroutinePromise
;
1078 if (E
&& (isa
<InitListExpr
>(E
) || !E
->getType()->isVoidType())) {
1079 getNamedReturnInfo(E
, SimplerImplicitMoveMode::ForceOn
);
1080 PC
= buildPromiseCall(*this, Promise
, Loc
, "return_value", E
);
1082 E
= MakeFullDiscardedValueExpr(E
).get();
1083 PC
= buildPromiseCall(*this, Promise
, Loc
, "return_void", std::nullopt
);
1088 Expr
*PCE
= ActOnFinishFullExpr(PC
.get(), /*DiscardedValue*/ false).get();
1090 Stmt
*Res
= new (Context
) CoreturnStmt(Loc
, E
, PCE
, IsImplicit
);
1094 /// Look up the std::nothrow object.
1095 static Expr
*buildStdNoThrowDeclRef(Sema
&S
, SourceLocation Loc
) {
1096 NamespaceDecl
*Std
= S
.getStdNamespace();
1097 assert(Std
&& "Should already be diagnosed");
1099 LookupResult
Result(S
, &S
.PP
.getIdentifierTable().get("nothrow"), Loc
,
1100 Sema::LookupOrdinaryName
);
1101 if (!S
.LookupQualifiedName(Result
, Std
)) {
1102 // <coroutine> is not requred to include <new>, so we couldn't omit
1104 S
.Diag(Loc
, diag::err_implicit_coroutine_std_nothrow_type_not_found
);
1108 auto *VD
= Result
.getAsSingle
<VarDecl
>();
1110 Result
.suppressDiagnostics();
1111 // We found something weird. Complain about the first thing we found.
1112 NamedDecl
*Found
= *Result
.begin();
1113 S
.Diag(Found
->getLocation(), diag::err_malformed_std_nothrow
);
1117 ExprResult DR
= S
.BuildDeclRefExpr(VD
, VD
->getType(), VK_LValue
, Loc
);
1124 static TypeSourceInfo
*getTypeSourceInfoForStdAlignValT(Sema
&S
,
1125 SourceLocation Loc
) {
1126 EnumDecl
*StdAlignValT
= S
.getStdAlignValT();
1127 QualType StdAlignValDecl
= S
.Context
.getTypeDeclType(StdAlignValT
);
1128 return S
.Context
.getTrivialTypeSourceInfo(StdAlignValDecl
);
1131 // Find an appropriate delete for the promise.
1132 static bool findDeleteForPromise(Sema
&S
, SourceLocation Loc
, QualType PromiseType
,
1133 FunctionDecl
*&OperatorDelete
) {
1134 DeclarationName DeleteName
=
1135 S
.Context
.DeclarationNames
.getCXXOperatorName(OO_Delete
);
1137 auto *PointeeRD
= PromiseType
->getAsCXXRecordDecl();
1138 assert(PointeeRD
&& "PromiseType must be a CxxRecordDecl type");
1140 const bool Overaligned
= S
.getLangOpts().CoroAlignedAllocation
;
1142 // [dcl.fct.def.coroutine]p12
1143 // The deallocation function's name is looked up by searching for it in the
1144 // scope of the promise type. If nothing is found, a search is performed in
1145 // the global scope.
1146 if (S
.FindDeallocationFunction(Loc
, PointeeRD
, DeleteName
, OperatorDelete
,
1147 /*Diagnose*/ true, /*WantSize*/ true,
1148 /*WantAligned*/ Overaligned
))
1151 // [dcl.fct.def.coroutine]p12
1152 // If both a usual deallocation function with only a pointer parameter and a
1153 // usual deallocation function with both a pointer parameter and a size
1154 // parameter are found, then the selected deallocation function shall be the
1155 // one with two parameters. Otherwise, the selected deallocation function
1156 // shall be the function with one parameter.
1157 if (!OperatorDelete
) {
1158 // Look for a global declaration.
1159 // Coroutines can always provide their required size.
1160 const bool CanProvideSize
= true;
1161 // Sema::FindUsualDeallocationFunction will try to find the one with two
1162 // parameters first. It will return the deallocation function with one
1163 // parameter if failed.
1164 OperatorDelete
= S
.FindUsualDeallocationFunction(Loc
, CanProvideSize
,
1165 Overaligned
, DeleteName
);
1167 if (!OperatorDelete
)
1171 S
.MarkFunctionReferenced(Loc
, OperatorDelete
);
1176 void Sema::CheckCompletedCoroutineBody(FunctionDecl
*FD
, Stmt
*&Body
) {
1177 FunctionScopeInfo
*Fn
= getCurFunction();
1178 assert(Fn
&& Fn
->isCoroutine() && "not a coroutine");
1180 assert(FD
->isInvalidDecl() &&
1181 "a null body is only allowed for invalid declarations");
1184 // We have a function that uses coroutine keywords, but we failed to build
1185 // the promise type.
1186 if (!Fn
->CoroutinePromise
)
1187 return FD
->setInvalidDecl();
1189 if (isa
<CoroutineBodyStmt
>(Body
)) {
1190 // Nothing todo. the body is already a transformed coroutine body statement.
1194 // The always_inline attribute doesn't reliably apply to a coroutine,
1195 // because the coroutine will be split into pieces and some pieces
1196 // might be called indirectly, as in a virtual call. Even the ramp
1197 // function cannot be inlined at -O0, due to pipeline ordering
1198 // problems (see https://llvm.org/PR53413). Tell the user about it.
1199 if (FD
->hasAttr
<AlwaysInlineAttr
>())
1200 Diag(FD
->getLocation(), diag::warn_always_inline_coroutine
);
1202 // The design of coroutines means we cannot allow use of VLAs within one, so
1203 // diagnose if we've seen a VLA in the body of this function.
1204 if (Fn
->FirstVLALoc
.isValid())
1205 Diag(Fn
->FirstVLALoc
, diag::err_vla_in_coroutine_unsupported
);
1207 // [stmt.return.coroutine]p1:
1208 // A coroutine shall not enclose a return statement ([stmt.return]).
1209 if (Fn
->FirstReturnLoc
.isValid()) {
1210 assert(Fn
->FirstCoroutineStmtLoc
.isValid() &&
1211 "first coroutine location not set");
1212 Diag(Fn
->FirstReturnLoc
, diag::err_return_in_coroutine
);
1213 Diag(Fn
->FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
1214 << Fn
->getFirstCoroutineStmtKeyword();
1217 // Coroutines will get splitted into pieces. The GNU address of label
1218 // extension wouldn't be meaningful in coroutines.
1219 for (AddrLabelExpr
*ALE
: Fn
->AddrLabels
)
1220 Diag(ALE
->getBeginLoc(), diag::err_coro_invalid_addr_of_label
);
1222 CoroutineStmtBuilder
Builder(*this, *FD
, *Fn
, Body
);
1223 if (Builder
.isInvalid() || !Builder
.buildStatements())
1224 return FD
->setInvalidDecl();
1226 // Build body for the coroutine wrapper statement.
1227 Body
= CoroutineBodyStmt::Create(Context
, Builder
);
1230 static CompoundStmt
*buildCoroutineBody(Stmt
*Body
, ASTContext
&Context
) {
1231 if (auto *CS
= dyn_cast
<CompoundStmt
>(Body
))
1234 // The body of the coroutine may be a try statement if it is in
1235 // 'function-try-block' syntax. Here we wrap it into a compound
1236 // statement for consistency.
1237 assert(isa
<CXXTryStmt
>(Body
) && "Unimaged coroutine body type");
1238 return CompoundStmt::Create(Context
, {Body
}, FPOptionsOverride(),
1239 SourceLocation(), SourceLocation());
1242 CoroutineStmtBuilder::CoroutineStmtBuilder(Sema
&S
, FunctionDecl
&FD
,
1243 sema::FunctionScopeInfo
&Fn
,
1245 : S(S
), FD(FD
), Fn(Fn
), Loc(FD
.getLocation()),
1246 IsPromiseDependentType(
1247 !Fn
.CoroutinePromise
||
1248 Fn
.CoroutinePromise
->getType()->isDependentType()) {
1249 this->Body
= buildCoroutineBody(Body
, S
.getASTContext());
1251 for (auto KV
: Fn
.CoroutineParameterMoves
)
1252 this->ParamMovesVector
.push_back(KV
.second
);
1253 this->ParamMoves
= this->ParamMovesVector
;
1255 if (!IsPromiseDependentType
) {
1256 PromiseRecordDecl
= Fn
.CoroutinePromise
->getType()->getAsCXXRecordDecl();
1257 assert(PromiseRecordDecl
&& "Type should have already been checked");
1259 this->IsValid
= makePromiseStmt() && makeInitialAndFinalSuspend();
1262 bool CoroutineStmtBuilder::buildStatements() {
1263 assert(this->IsValid
&& "coroutine already invalid");
1264 this->IsValid
= makeReturnObject();
1265 if (this->IsValid
&& !IsPromiseDependentType
)
1266 buildDependentStatements();
1267 return this->IsValid
;
1270 bool CoroutineStmtBuilder::buildDependentStatements() {
1271 assert(this->IsValid
&& "coroutine already invalid");
1272 assert(!this->IsPromiseDependentType
&&
1273 "coroutine cannot have a dependent promise type");
1274 this->IsValid
= makeOnException() && makeOnFallthrough() &&
1275 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
1276 makeNewAndDeleteExpr();
1277 return this->IsValid
;
1280 bool CoroutineStmtBuilder::makePromiseStmt() {
1281 // Form a declaration statement for the promise declaration, so that AST
1282 // visitors can more easily find it.
1283 StmtResult PromiseStmt
=
1284 S
.ActOnDeclStmt(S
.ConvertDeclToDeclGroup(Fn
.CoroutinePromise
), Loc
, Loc
);
1285 if (PromiseStmt
.isInvalid())
1288 this->Promise
= PromiseStmt
.get();
1292 bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1293 if (Fn
.hasInvalidCoroutineSuspends())
1295 this->InitialSuspend
= cast
<Expr
>(Fn
.CoroutineSuspends
.first
);
1296 this->FinalSuspend
= cast
<Expr
>(Fn
.CoroutineSuspends
.second
);
1300 static bool diagReturnOnAllocFailure(Sema
&S
, Expr
*E
,
1301 CXXRecordDecl
*PromiseRecordDecl
,
1302 FunctionScopeInfo
&Fn
) {
1303 auto Loc
= E
->getExprLoc();
1304 if (auto *DeclRef
= dyn_cast_or_null
<DeclRefExpr
>(E
)) {
1305 auto *Decl
= DeclRef
->getDecl();
1306 if (CXXMethodDecl
*Method
= dyn_cast_or_null
<CXXMethodDecl
>(Decl
)) {
1307 if (Method
->isStatic())
1310 Loc
= Decl
->getLocation();
1316 diag::err_coroutine_promise_get_return_object_on_allocation_failure
)
1317 << PromiseRecordDecl
;
1318 S
.Diag(Fn
.FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
1319 << Fn
.getFirstCoroutineStmtKeyword();
1323 bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1324 assert(!IsPromiseDependentType
&&
1325 "cannot make statement while the promise type is dependent");
1327 // [dcl.fct.def.coroutine]p10
1328 // If a search for the name get_return_object_on_allocation_failure in
1329 // the scope of the promise type ([class.member.lookup]) finds any
1330 // declarations, then the result of a call to an allocation function used to
1331 // obtain storage for the coroutine state is assumed to return nullptr if it
1332 // fails to obtain storage, ... If the allocation function returns nullptr,
1333 // ... and the return value is obtained by a call to
1334 // T::get_return_object_on_allocation_failure(), where T is the
1336 DeclarationName DN
=
1337 S
.PP
.getIdentifierInfo("get_return_object_on_allocation_failure");
1338 LookupResult
Found(S
, DN
, Loc
, Sema::LookupMemberName
);
1339 if (!S
.LookupQualifiedName(Found
, PromiseRecordDecl
))
1343 ExprResult DeclNameExpr
=
1344 S
.BuildDeclarationNameExpr(SS
, Found
, /*NeedsADL=*/false);
1345 if (DeclNameExpr
.isInvalid())
1348 if (!diagReturnOnAllocFailure(S
, DeclNameExpr
.get(), PromiseRecordDecl
, Fn
))
1351 ExprResult ReturnObjectOnAllocationFailure
=
1352 S
.BuildCallExpr(nullptr, DeclNameExpr
.get(), Loc
, {}, Loc
);
1353 if (ReturnObjectOnAllocationFailure
.isInvalid())
1356 StmtResult ReturnStmt
=
1357 S
.BuildReturnStmt(Loc
, ReturnObjectOnAllocationFailure
.get());
1358 if (ReturnStmt
.isInvalid()) {
1359 S
.Diag(Found
.getFoundDecl()->getLocation(), diag::note_member_declared_here
)
1361 S
.Diag(Fn
.FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
1362 << Fn
.getFirstCoroutineStmtKeyword();
1366 this->ReturnStmtOnAllocFailure
= ReturnStmt
.get();
1370 // Collect placement arguments for allocation function of coroutine FD.
1371 // Return true if we collect placement arguments succesfully. Return false,
1373 static bool collectPlacementArgs(Sema
&S
, FunctionDecl
&FD
, SourceLocation Loc
,
1374 SmallVectorImpl
<Expr
*> &PlacementArgs
) {
1375 if (auto *MD
= dyn_cast
<CXXMethodDecl
>(&FD
)) {
1376 if (MD
->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD
)) {
1377 ExprResult ThisExpr
= S
.ActOnCXXThis(Loc
);
1378 if (ThisExpr
.isInvalid())
1380 ThisExpr
= S
.CreateBuiltinUnaryOp(Loc
, UO_Deref
, ThisExpr
.get());
1381 if (ThisExpr
.isInvalid())
1383 PlacementArgs
.push_back(ThisExpr
.get());
1387 for (auto *PD
: FD
.parameters()) {
1388 if (PD
->getType()->isDependentType())
1391 // Build a reference to the parameter.
1392 auto PDLoc
= PD
->getLocation();
1393 ExprResult PDRefExpr
=
1394 S
.BuildDeclRefExpr(PD
, PD
->getOriginalType().getNonReferenceType(),
1395 ExprValueKind::VK_LValue
, PDLoc
);
1396 if (PDRefExpr
.isInvalid())
1399 PlacementArgs
.push_back(PDRefExpr
.get());
1405 bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1406 // Form and check allocation and deallocation calls.
1407 assert(!IsPromiseDependentType
&&
1408 "cannot make statement while the promise type is dependent");
1409 QualType PromiseType
= Fn
.CoroutinePromise
->getType();
1411 if (S
.RequireCompleteType(Loc
, PromiseType
, diag::err_incomplete_type
))
1414 const bool RequiresNoThrowAlloc
= ReturnStmtOnAllocFailure
!= nullptr;
1416 // According to [dcl.fct.def.coroutine]p9, Lookup allocation functions using a
1417 // parameter list composed of the requested size of the coroutine state being
1418 // allocated, followed by the coroutine function's arguments. If a matching
1419 // allocation function exists, use it. Otherwise, use an allocation function
1420 // that just takes the requested size.
1422 // [dcl.fct.def.coroutine]p9
1423 // An implementation may need to allocate additional storage for a
1425 // This storage is known as the coroutine state and is obtained by calling a
1426 // non-array allocation function ([basic.stc.dynamic.allocation]). The
1427 // allocation function's name is looked up by searching for it in the scope of
1428 // the promise type.
1429 // - If any declarations are found, overload resolution is performed on a
1430 // function call created by assembling an argument list. The first argument is
1431 // the amount of space requested, and has type std::size_t. The
1432 // lvalues p1 ... pn are the succeeding arguments.
1434 // ...where "p1 ... pn" are defined earlier as:
1436 // [dcl.fct.def.coroutine]p3
1437 // The promise type of a coroutine is `std::coroutine_traits<R, P1, ...,
1439 // , where R is the return type of the function, and `P1, ..., Pn` are the
1440 // sequence of types of the non-object function parameters, preceded by the
1441 // type of the object parameter ([dcl.fct]) if the coroutine is a non-static
1442 // member function. [dcl.fct.def.coroutine]p4 In the following, p_i is an
1443 // lvalue of type P_i, where p1 denotes the object parameter and p_i+1 denotes
1444 // the i-th non-object function parameter for a non-static member function,
1445 // and p_i denotes the i-th function parameter otherwise. For a non-static
1446 // member function, q_1 is an lvalue that denotes *this; any other q_i is an
1447 // lvalue that denotes the parameter copy corresponding to p_i.
1449 FunctionDecl
*OperatorNew
= nullptr;
1450 SmallVector
<Expr
*, 1> PlacementArgs
;
1452 const bool PromiseContainsNew
= [this, &PromiseType
]() -> bool {
1453 DeclarationName NewName
=
1454 S
.getASTContext().DeclarationNames
.getCXXOperatorName(OO_New
);
1455 LookupResult
R(S
, NewName
, Loc
, Sema::LookupOrdinaryName
);
1457 if (PromiseType
->isRecordType())
1458 S
.LookupQualifiedName(R
, PromiseType
->getAsCXXRecordDecl());
1460 return !R
.empty() && !R
.isAmbiguous();
1463 // Helper function to indicate whether the last lookup found the aligned
1464 // allocation function.
1465 bool PassAlignment
= S
.getLangOpts().CoroAlignedAllocation
;
1466 auto LookupAllocationFunction
= [&](Sema::AllocationFunctionScope NewScope
=
1468 bool WithoutPlacementArgs
= false,
1469 bool ForceNonAligned
= false) {
1470 // [dcl.fct.def.coroutine]p9
1471 // The allocation function's name is looked up by searching for it in the
1472 // scope of the promise type.
1473 // - If any declarations are found, ...
1474 // - If no declarations are found in the scope of the promise type, a search
1475 // is performed in the global scope.
1476 if (NewScope
== Sema::AFS_Both
)
1477 NewScope
= PromiseContainsNew
? Sema::AFS_Class
: Sema::AFS_Global
;
1479 PassAlignment
= !ForceNonAligned
&& S
.getLangOpts().CoroAlignedAllocation
;
1480 FunctionDecl
*UnusedResult
= nullptr;
1481 S
.FindAllocationFunctions(Loc
, SourceRange(), NewScope
,
1482 /*DeleteScope*/ Sema::AFS_Both
, PromiseType
,
1483 /*isArray*/ false, PassAlignment
,
1484 WithoutPlacementArgs
? MultiExprArg
{}
1486 OperatorNew
, UnusedResult
, /*Diagnose*/ false);
1489 // We don't expect to call to global operator new with (size, p0, …, pn).
1490 // So if we choose to lookup the allocation function in global scope, we
1491 // shouldn't lookup placement arguments.
1492 if (PromiseContainsNew
&& !collectPlacementArgs(S
, FD
, Loc
, PlacementArgs
))
1495 LookupAllocationFunction();
1497 if (PromiseContainsNew
&& !PlacementArgs
.empty()) {
1498 // [dcl.fct.def.coroutine]p9
1499 // If no viable function is found ([over.match.viable]), overload
1501 // is performed again on a function call created by passing just the amount
1502 // of space required as an argument of type std::size_t.
1504 // Proposed Change of [dcl.fct.def.coroutine]p9 in P2014R0:
1505 // Otherwise, overload resolution is performed again on a function call
1507 // by passing the amount of space requested as an argument of type
1508 // std::size_t as the first argument, and the requested alignment as
1509 // an argument of type std:align_val_t as the second argument.
1511 (S
.getLangOpts().CoroAlignedAllocation
&& !PassAlignment
))
1512 LookupAllocationFunction(/*NewScope*/ Sema::AFS_Class
,
1513 /*WithoutPlacementArgs*/ true);
1516 // Proposed Change of [dcl.fct.def.coroutine]p12 in P2014R0:
1517 // Otherwise, overload resolution is performed again on a function call
1519 // by passing the amount of space requested as an argument of type
1520 // std::size_t as the first argument, and the lvalues p1 ... pn as the
1521 // succeeding arguments. Otherwise, overload resolution is performed again
1522 // on a function call created by passing just the amount of space required as
1523 // an argument of type std::size_t.
1525 // So within the proposed change in P2014RO, the priority order of aligned
1526 // allocation functions wiht promise_type is:
1528 // void* operator new( std::size_t, std::align_val_t, placement_args... );
1529 // void* operator new( std::size_t, std::align_val_t);
1530 // void* operator new( std::size_t, placement_args... );
1531 // void* operator new( std::size_t);
1533 // Helper variable to emit warnings.
1534 bool FoundNonAlignedInPromise
= false;
1535 if (PromiseContainsNew
&& S
.getLangOpts().CoroAlignedAllocation
)
1536 if (!OperatorNew
|| !PassAlignment
) {
1537 FoundNonAlignedInPromise
= OperatorNew
;
1539 LookupAllocationFunction(/*NewScope*/ Sema::AFS_Class
,
1540 /*WithoutPlacementArgs*/ false,
1541 /*ForceNonAligned*/ true);
1543 if (!OperatorNew
&& !PlacementArgs
.empty())
1544 LookupAllocationFunction(/*NewScope*/ Sema::AFS_Class
,
1545 /*WithoutPlacementArgs*/ true,
1546 /*ForceNonAligned*/ true);
1549 bool IsGlobalOverload
=
1550 OperatorNew
&& !isa
<CXXRecordDecl
>(OperatorNew
->getDeclContext());
1551 // If we didn't find a class-local new declaration and non-throwing new
1552 // was is required then we need to lookup the non-throwing global operator
1554 if (RequiresNoThrowAlloc
&& (!OperatorNew
|| IsGlobalOverload
)) {
1555 auto *StdNoThrow
= buildStdNoThrowDeclRef(S
, Loc
);
1558 PlacementArgs
= {StdNoThrow
};
1559 OperatorNew
= nullptr;
1560 LookupAllocationFunction(Sema::AFS_Global
);
1563 // If we found a non-aligned allocation function in the promise_type,
1564 // it indicates the user forgot to update the allocation function. Let's emit
1566 if (FoundNonAlignedInPromise
) {
1567 S
.Diag(OperatorNew
->getLocation(),
1568 diag::warn_non_aligned_allocation_function
)
1573 if (PromiseContainsNew
)
1574 S
.Diag(Loc
, diag::err_coroutine_unusable_new
) << PromiseType
<< &FD
;
1575 else if (RequiresNoThrowAlloc
)
1576 S
.Diag(Loc
, diag::err_coroutine_unfound_nothrow_new
)
1577 << &FD
<< S
.getLangOpts().CoroAlignedAllocation
;
1582 if (RequiresNoThrowAlloc
) {
1583 const auto *FT
= OperatorNew
->getType()->castAs
<FunctionProtoType
>();
1584 if (!FT
->isNothrow(/*ResultIfDependent*/ false)) {
1585 S
.Diag(OperatorNew
->getLocation(),
1586 diag::err_coroutine_promise_new_requires_nothrow
)
1588 S
.Diag(Loc
, diag::note_coroutine_promise_call_implicitly_required
)
1594 FunctionDecl
*OperatorDelete
= nullptr;
1595 if (!findDeleteForPromise(S
, Loc
, PromiseType
, OperatorDelete
)) {
1596 // FIXME: We should add an error here. According to:
1597 // [dcl.fct.def.coroutine]p12
1598 // If no usual deallocation function is found, the program is ill-formed.
1603 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_frame
, {});
1606 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_size
, {});
1608 Expr
*FrameAlignment
= nullptr;
1610 if (S
.getLangOpts().CoroAlignedAllocation
) {
1612 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_align
, {});
1614 TypeSourceInfo
*AlignValTy
= getTypeSourceInfoForStdAlignValT(S
, Loc
);
1618 FrameAlignment
= S
.BuildCXXNamedCast(Loc
, tok::kw_static_cast
, AlignValTy
,
1619 FrameAlignment
, SourceRange(Loc
, Loc
),
1620 SourceRange(Loc
, Loc
))
1626 S
.BuildDeclRefExpr(OperatorNew
, OperatorNew
->getType(), VK_LValue
, Loc
);
1627 if (NewRef
.isInvalid())
1630 SmallVector
<Expr
*, 2> NewArgs(1, FrameSize
);
1631 if (S
.getLangOpts().CoroAlignedAllocation
&& PassAlignment
)
1632 NewArgs
.push_back(FrameAlignment
);
1634 if (OperatorNew
->getNumParams() > NewArgs
.size())
1635 llvm::append_range(NewArgs
, PlacementArgs
);
1637 ExprResult NewExpr
=
1638 S
.BuildCallExpr(S
.getCurScope(), NewRef
.get(), Loc
, NewArgs
, Loc
);
1639 NewExpr
= S
.ActOnFinishFullExpr(NewExpr
.get(), /*DiscardedValue*/ false);
1640 if (NewExpr
.isInvalid())
1643 // Make delete call.
1645 QualType OpDeleteQualType
= OperatorDelete
->getType();
1647 ExprResult DeleteRef
=
1648 S
.BuildDeclRefExpr(OperatorDelete
, OpDeleteQualType
, VK_LValue
, Loc
);
1649 if (DeleteRef
.isInvalid())
1653 S
.BuildBuiltinCallExpr(Loc
, Builtin::BI__builtin_coro_free
, {FramePtr
});
1655 SmallVector
<Expr
*, 2> DeleteArgs
{CoroFree
};
1657 // [dcl.fct.def.coroutine]p12
1658 // The selected deallocation function shall be called with the address of
1659 // the block of storage to be reclaimed as its first argument. If a
1660 // deallocation function with a parameter of type std::size_t is
1661 // used, the size of the block is passed as the corresponding argument.
1662 const auto *OpDeleteType
=
1663 OpDeleteQualType
.getTypePtr()->castAs
<FunctionProtoType
>();
1664 if (OpDeleteType
->getNumParams() > DeleteArgs
.size() &&
1665 S
.getASTContext().hasSameUnqualifiedType(
1666 OpDeleteType
->getParamType(DeleteArgs
.size()), FrameSize
->getType()))
1667 DeleteArgs
.push_back(FrameSize
);
1669 // Proposed Change of [dcl.fct.def.coroutine]p12 in P2014R0:
1670 // If deallocation function lookup finds a usual deallocation function with
1671 // a pointer parameter, size parameter and alignment parameter then this
1672 // will be the selected deallocation function, otherwise if lookup finds a
1673 // usual deallocation function with both a pointer parameter and a size
1674 // parameter, then this will be the selected deallocation function.
1675 // Otherwise, if lookup finds a usual deallocation function with only a
1676 // pointer parameter, then this will be the selected deallocation
1679 // So we are not forced to pass alignment to the deallocation function.
1680 if (S
.getLangOpts().CoroAlignedAllocation
&&
1681 OpDeleteType
->getNumParams() > DeleteArgs
.size() &&
1682 S
.getASTContext().hasSameUnqualifiedType(
1683 OpDeleteType
->getParamType(DeleteArgs
.size()),
1684 FrameAlignment
->getType()))
1685 DeleteArgs
.push_back(FrameAlignment
);
1687 ExprResult DeleteExpr
=
1688 S
.BuildCallExpr(S
.getCurScope(), DeleteRef
.get(), Loc
, DeleteArgs
, Loc
);
1690 S
.ActOnFinishFullExpr(DeleteExpr
.get(), /*DiscardedValue*/ false);
1691 if (DeleteExpr
.isInvalid())
1694 this->Allocate
= NewExpr
.get();
1695 this->Deallocate
= DeleteExpr
.get();
1700 bool CoroutineStmtBuilder::makeOnFallthrough() {
1701 assert(!IsPromiseDependentType
&&
1702 "cannot make statement while the promise type is dependent");
1704 // [dcl.fct.def.coroutine]/p6
1705 // If searches for the names return_void and return_value in the scope of
1706 // the promise type each find any declarations, the program is ill-formed.
1707 // [Note 1: If return_void is found, flowing off the end of a coroutine is
1708 // equivalent to a co_return with no operand. Otherwise, flowing off the end
1709 // of a coroutine results in undefined behavior ([stmt.return.coroutine]). —
1711 bool HasRVoid
, HasRValue
;
1712 LookupResult LRVoid
=
1713 lookupMember(S
, "return_void", PromiseRecordDecl
, Loc
, HasRVoid
);
1714 LookupResult LRValue
=
1715 lookupMember(S
, "return_value", PromiseRecordDecl
, Loc
, HasRValue
);
1717 StmtResult Fallthrough
;
1718 if (HasRVoid
&& HasRValue
) {
1719 // FIXME Improve this diagnostic
1720 S
.Diag(FD
.getLocation(),
1721 diag::err_coroutine_promise_incompatible_return_functions
)
1722 << PromiseRecordDecl
;
1723 S
.Diag(LRVoid
.getRepresentativeDecl()->getLocation(),
1724 diag::note_member_first_declared_here
)
1725 << LRVoid
.getLookupName();
1726 S
.Diag(LRValue
.getRepresentativeDecl()->getLocation(),
1727 diag::note_member_first_declared_here
)
1728 << LRValue
.getLookupName();
1730 } else if (!HasRVoid
&& !HasRValue
) {
1731 // We need to set 'Fallthrough'. Otherwise the other analysis part might
1732 // think the coroutine has defined a return_value method. So it might emit
1733 // **false** positive warning. e.g.,
1735 // promise_without_return_func foo() {
1736 // co_await something();
1739 // Then AnalysisBasedWarning would emit a warning about `foo()` lacking a
1740 // co_return statements, which isn't correct.
1741 Fallthrough
= S
.ActOnNullStmt(PromiseRecordDecl
->getLocation());
1742 if (Fallthrough
.isInvalid())
1744 } else if (HasRVoid
) {
1745 Fallthrough
= S
.BuildCoreturnStmt(FD
.getLocation(), nullptr,
1746 /*IsImplicit*/false);
1747 Fallthrough
= S
.ActOnFinishFullStmt(Fallthrough
.get());
1748 if (Fallthrough
.isInvalid())
1752 this->OnFallthrough
= Fallthrough
.get();
1756 bool CoroutineStmtBuilder::makeOnException() {
1757 // Try to form 'p.unhandled_exception();'
1758 assert(!IsPromiseDependentType
&&
1759 "cannot make statement while the promise type is dependent");
1761 const bool RequireUnhandledException
= S
.getLangOpts().CXXExceptions
;
1763 if (!lookupMember(S
, "unhandled_exception", PromiseRecordDecl
, Loc
)) {
1765 RequireUnhandledException
1766 ? diag::err_coroutine_promise_unhandled_exception_required
1768 warn_coroutine_promise_unhandled_exception_required_with_exceptions
;
1769 S
.Diag(Loc
, DiagID
) << PromiseRecordDecl
;
1770 S
.Diag(PromiseRecordDecl
->getLocation(), diag::note_defined_here
)
1771 << PromiseRecordDecl
;
1772 return !RequireUnhandledException
;
1775 // If exceptions are disabled, don't try to build OnException.
1776 if (!S
.getLangOpts().CXXExceptions
)
1779 ExprResult UnhandledException
= buildPromiseCall(
1780 S
, Fn
.CoroutinePromise
, Loc
, "unhandled_exception", std::nullopt
);
1781 UnhandledException
= S
.ActOnFinishFullExpr(UnhandledException
.get(), Loc
,
1782 /*DiscardedValue*/ false);
1783 if (UnhandledException
.isInvalid())
1786 // Since the body of the coroutine will be wrapped in try-catch, it will
1787 // be incompatible with SEH __try if present in a function.
1788 if (!S
.getLangOpts().Borland
&& Fn
.FirstSEHTryLoc
.isValid()) {
1789 S
.Diag(Fn
.FirstSEHTryLoc
, diag::err_seh_in_a_coroutine_with_cxx_exceptions
);
1790 S
.Diag(Fn
.FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
1791 << Fn
.getFirstCoroutineStmtKeyword();
1795 this->OnException
= UnhandledException
.get();
1799 bool CoroutineStmtBuilder::makeReturnObject() {
1800 // [dcl.fct.def.coroutine]p7
1801 // The expression promise.get_return_object() is used to initialize the
1802 // returned reference or prvalue result object of a call to a coroutine.
1803 ExprResult ReturnObject
= buildPromiseCall(S
, Fn
.CoroutinePromise
, Loc
,
1804 "get_return_object", std::nullopt
);
1805 if (ReturnObject
.isInvalid())
1808 this->ReturnValue
= ReturnObject
.get();
1812 static void noteMemberDeclaredHere(Sema
&S
, Expr
*E
, FunctionScopeInfo
&Fn
) {
1813 if (auto *MbrRef
= dyn_cast
<CXXMemberCallExpr
>(E
)) {
1814 auto *MethodDecl
= MbrRef
->getMethodDecl();
1815 S
.Diag(MethodDecl
->getLocation(), diag::note_member_declared_here
)
1818 S
.Diag(Fn
.FirstCoroutineStmtLoc
, diag::note_declared_coroutine_here
)
1819 << Fn
.getFirstCoroutineStmtKeyword();
1822 bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1823 assert(!IsPromiseDependentType
&&
1824 "cannot make statement while the promise type is dependent");
1825 assert(this->ReturnValue
&& "ReturnValue must be already formed");
1827 QualType
const GroType
= this->ReturnValue
->getType();
1828 assert(!GroType
->isDependentType() &&
1829 "get_return_object type must no longer be dependent");
1831 QualType
const FnRetType
= FD
.getReturnType();
1832 assert(!FnRetType
->isDependentType() &&
1833 "get_return_object type must no longer be dependent");
1835 // The call to get_return_object is sequenced before the call to
1836 // initial_suspend and is invoked at most once, but there are caveats
1837 // regarding on whether the prvalue result object may be initialized
1838 // directly/eager or delayed, depending on the types involved.
1840 // More info at https://github.com/cplusplus/papers/issues/1414
1841 bool GroMatchesRetType
= S
.getASTContext().hasSameType(GroType
, FnRetType
);
1843 if (FnRetType
->isVoidType()) {
1845 S
.ActOnFinishFullExpr(this->ReturnValue
, Loc
, /*DiscardedValue*/ false);
1846 if (Res
.isInvalid())
1849 if (!GroMatchesRetType
)
1850 this->ResultDecl
= Res
.get();
1854 if (GroType
->isVoidType()) {
1855 // Trigger a nice error message.
1856 InitializedEntity Entity
=
1857 InitializedEntity::InitializeResult(Loc
, FnRetType
);
1858 S
.PerformCopyInitialization(Entity
, SourceLocation(), ReturnValue
);
1859 noteMemberDeclaredHere(S
, ReturnValue
, Fn
);
1863 StmtResult ReturnStmt
;
1864 clang::VarDecl
*GroDecl
= nullptr;
1865 if (GroMatchesRetType
) {
1866 ReturnStmt
= S
.BuildReturnStmt(Loc
, ReturnValue
);
1868 GroDecl
= VarDecl::Create(
1869 S
.Context
, &FD
, FD
.getLocation(), FD
.getLocation(),
1870 &S
.PP
.getIdentifierTable().get("__coro_gro"), GroType
,
1871 S
.Context
.getTrivialTypeSourceInfo(GroType
, Loc
), SC_None
);
1872 GroDecl
->setImplicit();
1874 S
.CheckVariableDeclarationType(GroDecl
);
1875 if (GroDecl
->isInvalidDecl())
1878 InitializedEntity Entity
= InitializedEntity::InitializeVariable(GroDecl
);
1880 S
.PerformCopyInitialization(Entity
, SourceLocation(), ReturnValue
);
1881 if (Res
.isInvalid())
1884 Res
= S
.ActOnFinishFullExpr(Res
.get(), /*DiscardedValue*/ false);
1885 if (Res
.isInvalid())
1888 S
.AddInitializerToDecl(GroDecl
, Res
.get(),
1889 /*DirectInit=*/false);
1891 S
.FinalizeDeclaration(GroDecl
);
1893 // Form a declaration statement for the return declaration, so that AST
1894 // visitors can more easily find it.
1895 StmtResult GroDeclStmt
=
1896 S
.ActOnDeclStmt(S
.ConvertDeclToDeclGroup(GroDecl
), Loc
, Loc
);
1897 if (GroDeclStmt
.isInvalid())
1900 this->ResultDecl
= GroDeclStmt
.get();
1902 ExprResult declRef
= S
.BuildDeclRefExpr(GroDecl
, GroType
, VK_LValue
, Loc
);
1903 if (declRef
.isInvalid())
1906 ReturnStmt
= S
.BuildReturnStmt(Loc
, declRef
.get());
1909 if (ReturnStmt
.isInvalid()) {
1910 noteMemberDeclaredHere(S
, ReturnValue
, Fn
);
1914 if (!GroMatchesRetType
&&
1915 cast
<clang::ReturnStmt
>(ReturnStmt
.get())->getNRVOCandidate() == GroDecl
)
1916 GroDecl
->setNRVOVariable(true);
1918 this->ReturnStmt
= ReturnStmt
.get();
1922 // Create a static_cast\<T&&>(expr).
1923 static Expr
*castForMoving(Sema
&S
, Expr
*E
, QualType T
= QualType()) {
1926 QualType TargetType
= S
.BuildReferenceType(
1927 T
, /*SpelledAsLValue*/ false, SourceLocation(), DeclarationName());
1928 SourceLocation ExprLoc
= E
->getBeginLoc();
1929 TypeSourceInfo
*TargetLoc
=
1930 S
.Context
.getTrivialTypeSourceInfo(TargetType
, ExprLoc
);
1933 .BuildCXXNamedCast(ExprLoc
, tok::kw_static_cast
, TargetLoc
, E
,
1934 SourceRange(ExprLoc
, ExprLoc
), E
->getSourceRange())
1938 /// Build a variable declaration for move parameter.
1939 static VarDecl
*buildVarDecl(Sema
&S
, SourceLocation Loc
, QualType Type
,
1940 IdentifierInfo
*II
) {
1941 TypeSourceInfo
*TInfo
= S
.Context
.getTrivialTypeSourceInfo(Type
, Loc
);
1942 VarDecl
*Decl
= VarDecl::Create(S
.Context
, S
.CurContext
, Loc
, Loc
, II
, Type
,
1944 Decl
->setImplicit();
1948 // Build statements that move coroutine function parameters to the coroutine
1949 // frame, and store them on the function scope info.
1950 bool Sema::buildCoroutineParameterMoves(SourceLocation Loc
) {
1951 assert(isa
<FunctionDecl
>(CurContext
) && "not in a function scope");
1952 auto *FD
= cast
<FunctionDecl
>(CurContext
);
1954 auto *ScopeInfo
= getCurFunction();
1955 if (!ScopeInfo
->CoroutineParameterMoves
.empty())
1958 // [dcl.fct.def.coroutine]p13
1959 // When a coroutine is invoked, after initializing its parameters
1960 // ([expr.call]), a copy is created for each coroutine parameter. For a
1961 // parameter of type cv T, the copy is a variable of type cv T with
1962 // automatic storage duration that is direct-initialized from an xvalue of
1963 // type T referring to the parameter.
1964 for (auto *PD
: FD
->parameters()) {
1965 if (PD
->getType()->isDependentType())
1968 // Preserve the referenced state for unused parameter diagnostics.
1969 bool DeclReferenced
= PD
->isReferenced();
1971 ExprResult PDRefExpr
=
1972 BuildDeclRefExpr(PD
, PD
->getType().getNonReferenceType(),
1973 ExprValueKind::VK_LValue
, Loc
); // FIXME: scope?
1975 PD
->setReferenced(DeclReferenced
);
1977 if (PDRefExpr
.isInvalid())
1980 Expr
*CExpr
= nullptr;
1981 if (PD
->getType()->getAsCXXRecordDecl() ||
1982 PD
->getType()->isRValueReferenceType())
1983 CExpr
= castForMoving(*this, PDRefExpr
.get());
1985 CExpr
= PDRefExpr
.get();
1986 // [dcl.fct.def.coroutine]p13
1987 // The initialization and destruction of each parameter copy occurs in the
1988 // context of the called coroutine.
1989 auto *D
= buildVarDecl(*this, Loc
, PD
->getType(), PD
->getIdentifier());
1990 AddInitializerToDecl(D
, CExpr
, /*DirectInit=*/true);
1992 // Convert decl to a statement.
1993 StmtResult Stmt
= ActOnDeclStmt(ConvertDeclToDeclGroup(D
), Loc
, Loc
);
1994 if (Stmt
.isInvalid())
1997 ScopeInfo
->CoroutineParameterMoves
.insert(std::make_pair(PD
, Stmt
.get()));
2002 StmtResult
Sema::BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args
) {
2003 CoroutineBodyStmt
*Res
= CoroutineBodyStmt::Create(Context
, Args
);
2009 ClassTemplateDecl
*Sema::lookupCoroutineTraits(SourceLocation KwLoc
,
2010 SourceLocation FuncLoc
) {
2011 if (StdCoroutineTraitsCache
)
2012 return StdCoroutineTraitsCache
;
2014 IdentifierInfo
const &TraitIdent
=
2015 PP
.getIdentifierTable().get("coroutine_traits");
2017 NamespaceDecl
*StdSpace
= getStdNamespace();
2018 LookupResult
Result(*this, &TraitIdent
, FuncLoc
, LookupOrdinaryName
);
2019 bool Found
= StdSpace
&& LookupQualifiedName(Result
, StdSpace
);
2022 // The goggles, we found nothing!
2023 Diag(KwLoc
, diag::err_implied_coroutine_type_not_found
)
2024 << "std::coroutine_traits";
2028 // coroutine_traits is required to be a class template.
2029 StdCoroutineTraitsCache
= Result
.getAsSingle
<ClassTemplateDecl
>();
2030 if (!StdCoroutineTraitsCache
) {
2031 Result
.suppressDiagnostics();
2032 NamedDecl
*Found
= *Result
.begin();
2033 Diag(Found
->getLocation(), diag::err_malformed_std_coroutine_traits
);
2037 return StdCoroutineTraitsCache
;