1//===-- SemaCoroutine.cpp - Semantic Analysis for Coroutines --------------===//
2//
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
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements semantic analysis for C++ Coroutines.
10//
11// This file contains references to sections of the Coroutines TS, which
12// can be found at http://wg21.link/coroutines.
13//
14//===----------------------------------------------------------------------===//
15
16#include "CoroutineStmtBuilder.h"
17#include "clang/AST/ASTLambda.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/Expr.h"
20#include "clang/AST/ExprCXX.h"
21#include "clang/AST/IgnoreExpr.h"
22#include "clang/AST/StmtCXX.h"
23#include "clang/Basic/Builtins.h"
24#include "clang/Lex/Preprocessor.h"
25#include "clang/Sema/EnterExpressionEvaluationContext.h"
26#include "clang/Sema/Initialization.h"
27#include "clang/Sema/Overload.h"
28#include "clang/Sema/ScopeInfo.h"
29
30using namespace clang;
31using namespace sema;
32
33static LookupResult lookupMember(Sema &S, const char *Name, CXXRecordDecl *RD,
34 SourceLocation Loc, bool &Res) {
35 DeclarationName DN = S.PP.getIdentifierInfo(Name);
36 LookupResult LR(S, DN, Loc, Sema::LookupMemberName);
37 // Suppress diagnostics when a private member is selected. The same warnings
38 // will be produced again when building the call.
39 LR.suppressDiagnostics();
40 Res = S.LookupQualifiedName(R&: LR, LookupCtx: RD);
41 return LR;
42}
43
44static bool lookupMember(Sema &S, const char *Name, CXXRecordDecl *RD,
45 SourceLocation Loc) {
46 bool Res;
47 lookupMember(S, Name, RD, Loc, Res);
48 return Res;
49}
50
51/// Look up the std::coroutine_traits<...>::promise_type for the given
52/// function type.
53static QualType lookupPromiseType(Sema &S, const FunctionDecl *FD,
54 SourceLocation KwLoc) {
55 const FunctionProtoType *FnType = FD->getType()->castAs<FunctionProtoType>();
56 const SourceLocation FuncLoc = FD->getLocation();
57
58 ClassTemplateDecl *CoroTraits =
59 S.lookupCoroutineTraits(KwLoc, FuncLoc);
60 if (!CoroTraits)
61 return QualType();
62
63 // Form template argument list for coroutine_traits<R, P1, P2, ...> according
64 // to [dcl.fct.def.coroutine]3
65 TemplateArgumentListInfo Args(KwLoc, KwLoc);
66 auto AddArg = [&](QualType T) {
67 Args.addArgument(Loc: TemplateArgumentLoc(
68 TemplateArgument(T), S.Context.getTrivialTypeSourceInfo(T, Loc: KwLoc)));
69 };
70 AddArg(FnType->getReturnType());
71 // If the function is a non-static member function, add the type
72 // of the implicit object parameter before the formal parameters.
73 if (auto *MD = dyn_cast<CXXMethodDecl>(Val: FD)) {
74 if (MD->isImplicitObjectMemberFunction()) {
75 // [over.match.funcs]4
76 // For non-static member functions, the type of the implicit object
77 // parameter is
78 // -- "lvalue reference to cv X" for functions declared without a
79 // ref-qualifier or with the & ref-qualifier
80 // -- "rvalue reference to cv X" for functions declared with the &&
81 // ref-qualifier
82 QualType T = MD->getFunctionObjectParameterType();
83 T = FnType->getRefQualifier() == RQ_RValue
84 ? S.Context.getRValueReferenceType(T)
85 : S.Context.getLValueReferenceType(T, /*SpelledAsLValue*/ true);
86 AddArg(T);
87 }
88 }
89 for (QualType T : FnType->getParamTypes())
90 AddArg(T);
91
92 // Build the template-id.
93 QualType CoroTrait = S.CheckTemplateIdType(
94 Keyword: ElaboratedTypeKeyword::None, Template: TemplateName(CoroTraits), TemplateLoc: KwLoc, TemplateArgs&: Args,
95 /*Scope=*/nullptr, /*ForNestedNameSpecifier=*/false);
96 if (CoroTrait.isNull())
97 return QualType();
98 if (S.RequireCompleteType(Loc: KwLoc, T: CoroTrait,
99 DiagID: diag::err_coroutine_type_missing_specialization))
100 return QualType();
101
102 auto *RD = CoroTrait->getAsCXXRecordDecl();
103 assert(RD && "specialization of class template is not a class?");
104
105 // Look up the ::promise_type member.
106 LookupResult R(S, &S.PP.getIdentifierTable().get(Name: "promise_type"), KwLoc,
107 Sema::LookupOrdinaryName);
108 S.LookupQualifiedName(R, LookupCtx: RD);
109 auto *Promise = R.getAsSingle<TypeDecl>();
110 if (!Promise) {
111 S.Diag(Loc: FuncLoc,
112 DiagID: diag::err_implied_std_coroutine_traits_promise_type_not_found)
113 << RD;
114 return QualType();
115 }
116
117 NestedNameSpecifier Qualifier(CoroTrait.getTypePtr());
118 QualType PromiseType = S.Context.getTypeDeclType(Keyword: ElaboratedTypeKeyword::None,
119 Qualifier, Decl: Promise);
120 // The promise type is required to be a class type.
121 if (!PromiseType->getAsCXXRecordDecl()) {
122 S.Diag(Loc: FuncLoc,
123 DiagID: diag::err_implied_std_coroutine_traits_promise_type_not_class)
124 << PromiseType;
125 return QualType();
126 }
127 if (S.RequireCompleteType(Loc: FuncLoc, T: PromiseType,
128 DiagID: diag::err_coroutine_promise_type_incomplete))
129 return QualType();
130
131 return PromiseType;
132}
133
134/// Look up the std::coroutine_handle<PromiseType>.
135static QualType lookupCoroutineHandleType(Sema &S, QualType PromiseType,
136 SourceLocation Loc) {
137 if (PromiseType.isNull())
138 return QualType();
139
140 NamespaceDecl *CoroNamespace = S.getStdNamespace();
141 assert(CoroNamespace && "Should already be diagnosed");
142
143 LookupResult Result(S, &S.PP.getIdentifierTable().get(Name: "coroutine_handle"),
144 Loc, Sema::LookupOrdinaryName);
145 if (!S.LookupQualifiedName(R&: Result, LookupCtx: CoroNamespace)) {
146 S.Diag(Loc, DiagID: diag::err_implied_coroutine_type_not_found)
147 << "std::coroutine_handle";
148 return QualType();
149 }
150
151 ClassTemplateDecl *CoroHandle = Result.getAsSingle<ClassTemplateDecl>();
152 if (!CoroHandle) {
153 Result.suppressDiagnostics();
154 // We found something weird. Complain about the first thing we found.
155 NamedDecl *Found = *Result.begin();
156 S.Diag(Loc: Found->getLocation(), DiagID: diag::err_malformed_std_coroutine_handle);
157 return QualType();
158 }
159
160 // Form template argument list for coroutine_handle<Promise>.
161 TemplateArgumentListInfo Args(Loc, Loc);
162 Args.addArgument(Loc: TemplateArgumentLoc(
163 TemplateArgument(PromiseType),
164 S.Context.getTrivialTypeSourceInfo(T: PromiseType, Loc)));
165
166 // Build the template-id.
167 QualType CoroHandleType = S.CheckTemplateIdType(
168 Keyword: ElaboratedTypeKeyword::None, Template: TemplateName(CoroHandle), TemplateLoc: Loc, TemplateArgs&: Args,
169 /*Scope=*/nullptr, /*ForNestedNameSpecifier=*/false);
170 if (CoroHandleType.isNull())
171 return QualType();
172 if (S.RequireCompleteType(Loc, T: CoroHandleType,
173 DiagID: diag::err_coroutine_type_missing_specialization))
174 return QualType();
175
176 return CoroHandleType;
177}
178
179static bool isValidCoroutineContext(Sema &S, SourceLocation Loc,
180 StringRef Keyword) {
181 // [expr.await]p2 dictates that 'co_await' and 'co_yield' must be used within
182 // a function body.
183 // FIXME: This also covers [expr.await]p2: "An await-expression shall not
184 // appear in a default argument." But the diagnostic QoI here could be
185 // improved to inform the user that default arguments specifically are not
186 // allowed.
187 auto *FD = dyn_cast<FunctionDecl>(Val: S.CurContext);
188 if (!FD) {
189 S.Diag(Loc, DiagID: isa<ObjCMethodDecl>(Val: S.CurContext)
190 ? diag::err_coroutine_objc_method
191 : diag::err_coroutine_outside_function) << Keyword;
192 return false;
193 }
194
195 // An enumeration for mapping the diagnostic type to the correct diagnostic
196 // selection index.
197 enum InvalidFuncDiag {
198 DiagCtor = 0,
199 DiagDtor,
200 DiagMain,
201 DiagConstexpr,
202 DiagAutoRet,
203 DiagVarargs,
204 DiagConsteval,
205 };
206 bool Diagnosed = false;
207 auto DiagInvalid = [&](InvalidFuncDiag ID) {
208 S.Diag(Loc, DiagID: diag::err_coroutine_invalid_func_context) << ID << Keyword;
209 Diagnosed = true;
210 return false;
211 };
212
213 // Diagnose when a constructor, destructor
214 // or the function 'main' are declared as a coroutine.
215 auto *MD = dyn_cast<CXXMethodDecl>(Val: FD);
216 // [class.ctor]p11: "A constructor shall not be a coroutine."
217 if (MD && isa<CXXConstructorDecl>(Val: MD))
218 return DiagInvalid(DiagCtor);
219 // [class.dtor]p17: "A destructor shall not be a coroutine."
220 else if (MD && isa<CXXDestructorDecl>(Val: MD))
221 return DiagInvalid(DiagDtor);
222 // [basic.start.main]p3: "The function main shall not be a coroutine."
223 else if (FD->isMain())
224 return DiagInvalid(DiagMain);
225
226 // Emit a diagnostics for each of the following conditions which is not met.
227 // [expr.const]p2: "An expression e is a core constant expression unless the
228 // evaluation of e [...] would evaluate one of the following expressions:
229 // [...] an await-expression [...] a yield-expression."
230 if (FD->isConstexpr())
231 DiagInvalid(FD->isConsteval() ? DiagConsteval : DiagConstexpr);
232 // [dcl.spec.auto]p15: "A function declared with a return type that uses a
233 // placeholder type shall not be a coroutine."
234 if (FD->getReturnType()->isUndeducedType())
235 DiagInvalid(DiagAutoRet);
236 // [dcl.fct.def.coroutine]p1
237 // The parameter-declaration-clause of the coroutine shall not terminate with
238 // an ellipsis that is not part of a parameter-declaration.
239 if (FD->isVariadic())
240 DiagInvalid(DiagVarargs);
241
242 return !Diagnosed;
243}
244
245/// Build a call to 'operator co_await' if there is a suitable operator for
246/// the given expression.
247ExprResult Sema::BuildOperatorCoawaitCall(SourceLocation Loc, Expr *E,
248 UnresolvedLookupExpr *Lookup) {
249 UnresolvedSet<16> Functions;
250 Functions.append(I: Lookup->decls_begin(), E: Lookup->decls_end());
251 return CreateOverloadedUnaryOp(OpLoc: Loc, Opc: UO_Coawait, Fns: Functions, input: E);
252}
253
254static ExprResult buildOperatorCoawaitCall(Sema &SemaRef, Scope *S,
255 SourceLocation Loc, Expr *E) {
256 ExprResult R = SemaRef.BuildOperatorCoawaitLookupExpr(S, Loc);
257 if (R.isInvalid())
258 return ExprError();
259 return SemaRef.BuildOperatorCoawaitCall(Loc, E,
260 Lookup: cast<UnresolvedLookupExpr>(Val: R.get()));
261}
262
263static ExprResult buildCoroutineHandle(Sema &S, QualType PromiseType,
264 SourceLocation Loc) {
265 QualType CoroHandleType = lookupCoroutineHandleType(S, PromiseType, Loc);
266 if (CoroHandleType.isNull())
267 return ExprError();
268
269 DeclContext *LookupCtx = S.computeDeclContext(T: CoroHandleType);
270 LookupResult Found(S, &S.PP.getIdentifierTable().get(Name: "from_address"), Loc,
271 Sema::LookupOrdinaryName);
272 if (!S.LookupQualifiedName(R&: Found, LookupCtx)) {
273 S.Diag(Loc, DiagID: diag::err_coroutine_handle_missing_member)
274 << "from_address";
275 return ExprError();
276 }
277
278 Expr *FramePtr =
279 S.BuildBuiltinCallExpr(Loc, Id: Builtin::BI__builtin_coro_frame, CallArgs: {});
280
281 CXXScopeSpec SS;
282 ExprResult FromAddr =
283 S.BuildDeclarationNameExpr(SS, R&: Found, /*NeedsADL=*/false);
284 if (FromAddr.isInvalid())
285 return ExprError();
286
287 return S.BuildCallExpr(S: nullptr, Fn: FromAddr.get(), LParenLoc: Loc, ArgExprs: FramePtr, RParenLoc: Loc);
288}
289
290struct ReadySuspendResumeResult {
291 enum AwaitCallType { ACT_Ready, ACT_Suspend, ACT_Resume };
292 Expr *Results[3];
293 OpaqueValueExpr *OpaqueValue;
294 bool IsInvalid;
295};
296
297static ExprResult buildMemberCall(Sema &S, Expr *Base, SourceLocation Loc,
298 StringRef Name, MultiExprArg Args) {
299 DeclarationNameInfo NameInfo(&S.PP.getIdentifierTable().get(Name), Loc);
300
301 // FIXME: Fix BuildMemberReferenceExpr to take a const CXXScopeSpec&.
302 CXXScopeSpec SS;
303 ExprResult Result = S.BuildMemberReferenceExpr(
304 Base, BaseType: Base->getType(), OpLoc: Loc, /*IsPtr=*/IsArrow: false, SS,
305 TemplateKWLoc: SourceLocation(), FirstQualifierInScope: nullptr, NameInfo, /*TemplateArgs=*/nullptr,
306 /*Scope=*/S: nullptr);
307 if (Result.isInvalid())
308 return ExprError();
309
310 auto EndLoc = Args.empty() ? Loc : Args.back()->getEndLoc();
311 return S.BuildCallExpr(S: nullptr, Fn: Result.get(), LParenLoc: Loc, ArgExprs: Args, RParenLoc: EndLoc, ExecConfig: nullptr);
312}
313
314// See if return type is coroutine-handle and if so, invoke builtin coro-resume
315// on its address. This is to enable the support for coroutine-handle
316// returning await_suspend that results in a guaranteed tail call to the target
317// coroutine.
318static Expr *maybeTailCall(Sema &S, QualType RetType, Expr *E,
319 SourceLocation Loc) {
320 if (RetType->isReferenceType())
321 return nullptr;
322 Type const *T = RetType.getTypePtr();
323 if (!T->isClassType() && !T->isStructureType())
324 return nullptr;
325
326 // FIXME: Add convertability check to coroutine_handle<>. Possibly via
327 // EvaluateBinaryTypeTrait(BTT_IsConvertible, ...) which is at the moment
328 // a private function in SemaExprCXX.cpp
329
330 ExprResult AddressExpr = buildMemberCall(S, Base: E, Loc, Name: "address", Args: {});
331 if (AddressExpr.isInvalid())
332 return nullptr;
333
334 Expr *JustAddress = AddressExpr.get();
335
336 // Check that the type of AddressExpr is void*
337 if (!JustAddress->getType().getTypePtr()->isVoidPointerType())
338 S.Diag(Loc: cast<CallExpr>(Val: JustAddress)->getCalleeDecl()->getLocation(),
339 DiagID: diag::warn_coroutine_handle_address_invalid_return_type)
340 << JustAddress->getType();
341
342 // Clean up temporary objects, because the resulting expression
343 // will become the body of await_suspend wrapper.
344 return S.MaybeCreateExprWithCleanups(SubExpr: JustAddress);
345}
346
347/// Build calls to await_ready, await_suspend, and await_resume for a co_await
348/// expression.
349/// The generated AST tries to clean up temporary objects as early as
350/// possible so that they don't live across suspension points if possible.
351/// Having temporary objects living across suspension points unnecessarily can
352/// lead to large frame size, and also lead to memory corruptions if the
353/// coroutine frame is destroyed after coming back from suspension. This is done
354/// by wrapping both the await_ready call and the await_suspend call with
355/// ExprWithCleanups. In the end of this function, we also need to explicitly
356/// set cleanup state so that the CoawaitExpr is also wrapped with an
357/// ExprWithCleanups to clean up the awaiter associated with the co_await
358/// expression.
359static ReadySuspendResumeResult buildCoawaitCalls(Sema &S, VarDecl *CoroPromise,
360 SourceLocation Loc, Expr *E) {
361 OpaqueValueExpr *Operand = new (S.Context)
362 OpaqueValueExpr(Loc, E->getType(), VK_LValue, E->getObjectKind(), E);
363
364 // Assume valid until we see otherwise.
365 // Further operations are responsible for setting IsInalid to true.
366 ReadySuspendResumeResult Calls = {.Results: {}, .OpaqueValue: Operand, /*IsInvalid=*/false};
367
368 using ACT = ReadySuspendResumeResult::AwaitCallType;
369
370 auto BuildSubExpr = [&](ACT CallType, StringRef Func,
371 MultiExprArg Arg) -> Expr * {
372 ExprResult Result = buildMemberCall(S, Base: Operand, Loc, Name: Func, Args: Arg);
373 if (Result.isInvalid()) {
374 Calls.IsInvalid = true;
375 return nullptr;
376 }
377 Calls.Results[CallType] = Result.get();
378 return Result.get();
379 };
380
381 CallExpr *AwaitReady =
382 cast_or_null<CallExpr>(Val: BuildSubExpr(ACT::ACT_Ready, "await_ready", {}));
383 if (!AwaitReady)
384 return Calls;
385 if (!AwaitReady->getType()->isDependentType()) {
386 // [expr.await]p3 [...]
387 // — await-ready is the expression e.await_ready(), contextually converted
388 // to bool.
389 ExprResult Conv = S.PerformContextuallyConvertToBool(From: AwaitReady);
390 if (Conv.isInvalid()) {
391 S.Diag(Loc: AwaitReady->getDirectCallee()->getBeginLoc(),
392 DiagID: diag::note_await_ready_no_bool_conversion);
393 S.Diag(Loc, DiagID: diag::note_coroutine_promise_call_implicitly_required)
394 << AwaitReady->getDirectCallee() << E->getSourceRange();
395 Calls.IsInvalid = true;
396 } else
397 Calls.Results[ACT::ACT_Ready] = S.MaybeCreateExprWithCleanups(SubExpr: Conv.get());
398 }
399
400 ExprResult CoroHandleRes =
401 buildCoroutineHandle(S, PromiseType: CoroPromise->getType(), Loc);
402 if (CoroHandleRes.isInvalid()) {
403 Calls.IsInvalid = true;
404 return Calls;
405 }
406 Expr *CoroHandle = CoroHandleRes.get();
407 CallExpr *AwaitSuspend = cast_or_null<CallExpr>(
408 Val: BuildSubExpr(ACT::ACT_Suspend, "await_suspend", CoroHandle));
409 if (!AwaitSuspend)
410 return Calls;
411 if (!AwaitSuspend->getType()->isDependentType()) {
412 // [expr.await]p3 [...]
413 // - await-suspend is the expression e.await_suspend(h), which shall be
414 // a prvalue of type void, bool, or std::coroutine_handle<Z> for some
415 // type Z.
416 QualType RetType = AwaitSuspend->getCallReturnType(Ctx: S.Context);
417
418 // Support for coroutine_handle returning await_suspend.
419 if (Expr *TailCallSuspend =
420 maybeTailCall(S, RetType, E: AwaitSuspend, Loc))
421 // Note that we don't wrap the expression with ExprWithCleanups here
422 // because that might interfere with tailcall contract (e.g. inserting
423 // clean up instructions in-between tailcall and return). Instead
424 // ExprWithCleanups is wrapped within maybeTailCall() prior to the resume
425 // call.
426 Calls.Results[ACT::ACT_Suspend] = TailCallSuspend;
427 else {
428 // non-class prvalues always have cv-unqualified types
429 if (RetType->isReferenceType() ||
430 (!RetType->isBooleanType() && !RetType->isVoidType())) {
431 S.Diag(Loc: AwaitSuspend->getCalleeDecl()->getLocation(),
432 DiagID: diag::err_await_suspend_invalid_return_type)
433 << RetType;
434 S.Diag(Loc, DiagID: diag::note_coroutine_promise_call_implicitly_required)
435 << AwaitSuspend->getDirectCallee();
436 Calls.IsInvalid = true;
437 } else
438 Calls.Results[ACT::ACT_Suspend] =
439 S.MaybeCreateExprWithCleanups(SubExpr: AwaitSuspend);
440 }
441 }
442
443 BuildSubExpr(ACT::ACT_Resume, "await_resume", {});
444
445 // Make sure the awaiter object gets a chance to be cleaned up.
446 S.Cleanup.setExprNeedsCleanups(true);
447
448 return Calls;
449}
450
451static ExprResult buildPromiseCall(Sema &S, VarDecl *Promise,
452 SourceLocation Loc, StringRef Name,
453 MultiExprArg Args) {
454
455 // Form a reference to the promise.
456 ExprResult PromiseRef = S.BuildDeclRefExpr(
457 D: Promise, Ty: Promise->getType().getNonReferenceType(), VK: VK_LValue, Loc);
458 if (PromiseRef.isInvalid())
459 return ExprError();
460
461 return buildMemberCall(S, Base: PromiseRef.get(), Loc, Name, Args);
462}
463
464VarDecl *Sema::buildCoroutinePromise(SourceLocation Loc) {
465 assert(isa<FunctionDecl>(CurContext) && "not in a function scope");
466 auto *FD = cast<FunctionDecl>(Val: CurContext);
467 bool IsThisDependentType = [&] {
468 if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(Val: FD))
469 return MD->isImplicitObjectMemberFunction() &&
470 MD->getThisType()->isDependentType();
471 return false;
472 }();
473
474 QualType T = FD->getType()->isDependentType() || IsThisDependentType
475 ? Context.DependentTy
476 : lookupPromiseType(S&: *this, FD, KwLoc: Loc);
477 if (T.isNull())
478 return nullptr;
479
480 auto *VD = VarDecl::Create(C&: Context, DC: FD, StartLoc: FD->getLocation(), IdLoc: FD->getLocation(),
481 Id: &PP.getIdentifierTable().get(Name: "__promise"), T,
482 TInfo: Context.getTrivialTypeSourceInfo(T, Loc), S: SC_None);
483 VD->setImplicit();
484 CheckVariableDeclarationType(NewVD: VD);
485 if (VD->isInvalidDecl())
486 return nullptr;
487
488 auto *ScopeInfo = getCurFunction();
489
490 // Build a list of arguments, based on the coroutine function's arguments,
491 // that if present will be passed to the promise type's constructor.
492 llvm::SmallVector<Expr *, 4> CtorArgExprs;
493
494 // Add implicit object parameter.
495 if (auto *MD = dyn_cast<CXXMethodDecl>(Val: FD)) {
496 if (MD->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD)) {
497 ExprResult ThisExpr = ActOnCXXThis(Loc);
498 if (ThisExpr.isInvalid())
499 return nullptr;
500 ThisExpr = CreateBuiltinUnaryOp(OpLoc: Loc, Opc: UO_Deref, InputExpr: ThisExpr.get());
501 if (ThisExpr.isInvalid())
502 return nullptr;
503 CtorArgExprs.push_back(Elt: ThisExpr.get());
504 }
505 }
506
507 // Add the coroutine function's parameters.
508 auto &Moves = ScopeInfo->CoroutineParameterMoves;
509 for (auto *PD : FD->parameters()) {
510 if (PD->getType()->isDependentType())
511 continue;
512
513 auto RefExpr = ExprEmpty();
514 auto Move = Moves.find(Key: PD);
515 assert(Move != Moves.end() &&
516 "Coroutine function parameter not inserted into move map");
517 // If a reference to the function parameter exists in the coroutine
518 // frame, use that reference.
519 auto *MoveDecl =
520 cast<VarDecl>(Val: cast<DeclStmt>(Val: Move->second)->getSingleDecl());
521 RefExpr =
522 BuildDeclRefExpr(D: MoveDecl, Ty: MoveDecl->getType().getNonReferenceType(),
523 VK: ExprValueKind::VK_LValue, Loc: FD->getLocation());
524 if (RefExpr.isInvalid())
525 return nullptr;
526 CtorArgExprs.push_back(Elt: RefExpr.get());
527 }
528
529 // If we have a non-zero number of constructor arguments, try to use them.
530 // Otherwise, fall back to the promise type's default constructor.
531 if (!CtorArgExprs.empty()) {
532 // Create an initialization sequence for the promise type using the
533 // constructor arguments, wrapped in a parenthesized list expression.
534 Expr *PLE = ParenListExpr::Create(Ctx: Context, LParenLoc: FD->getLocation(),
535 Exprs: CtorArgExprs, RParenLoc: FD->getLocation());
536 InitializedEntity Entity = InitializedEntity::InitializeVariable(Var: VD);
537 InitializationKind Kind = InitializationKind::CreateForInit(
538 Loc: VD->getLocation(), /*DirectInit=*/true, Init: PLE);
539 InitializationSequence InitSeq(*this, Entity, Kind, CtorArgExprs,
540 /*TopLevelOfInitList=*/false,
541 /*TreatUnavailableAsInvalid=*/false);
542
543 // [dcl.fct.def.coroutine]5.7
544 // promise-constructor-arguments is determined as follows: overload
545 // resolution is performed on a promise constructor call created by
546 // assembling an argument list q_1 ... q_n . If a viable constructor is
547 // found ([over.match.viable]), then promise-constructor-arguments is ( q_1
548 // , ..., q_n ), otherwise promise-constructor-arguments is empty.
549 if (InitSeq) {
550 ExprResult Result = InitSeq.Perform(S&: *this, Entity, Kind, Args: CtorArgExprs);
551 if (Result.isInvalid()) {
552 VD->setInvalidDecl();
553 } else if (Result.get()) {
554 VD->setInit(MaybeCreateExprWithCleanups(SubExpr: Result.get()));
555 VD->setInitStyle(VarDecl::CallInit);
556 CheckCompleteVariableDeclaration(VD);
557 }
558 } else
559 ActOnUninitializedDecl(dcl: VD);
560 } else
561 ActOnUninitializedDecl(dcl: VD);
562
563 FD->addDecl(D: VD);
564 return VD;
565}
566
567/// Check that this is a context in which a coroutine suspension can appear.
568static FunctionScopeInfo *checkCoroutineContext(Sema &S, SourceLocation Loc,
569 StringRef Keyword,
570 bool IsImplicit = false) {
571 if (!isValidCoroutineContext(S, Loc, Keyword))
572 return nullptr;
573
574 assert(isa<FunctionDecl>(S.CurContext) && "not in a function scope");
575
576 auto *ScopeInfo = S.getCurFunction();
577 assert(ScopeInfo && "missing function scope for function");
578
579 if (ScopeInfo->FirstCoroutineStmtLoc.isInvalid() && !IsImplicit)
580 ScopeInfo->setFirstCoroutineStmt(Loc, Keyword);
581
582 if (ScopeInfo->CoroutinePromise)
583 return ScopeInfo;
584
585 if (!S.buildCoroutineParameterMoves(Loc))
586 return nullptr;
587
588 ScopeInfo->CoroutinePromise = S.buildCoroutinePromise(Loc);
589 if (!ScopeInfo->CoroutinePromise)
590 return nullptr;
591
592 return ScopeInfo;
593}
594
595/// Recursively check \p E and all its children to see if any call target
596/// (including constructor call) is declared noexcept. Also any value returned
597/// from the call has a noexcept destructor.
598static void checkNoThrow(Sema &S, const Stmt *E,
599 llvm::SmallPtrSetImpl<const Decl *> &ThrowingDecls) {
600 auto checkDeclNoexcept = [&](const Decl *D, bool IsDtor = false) {
601 // In the case of dtor, the call to dtor is implicit and hence we should
602 // pass nullptr to canCalleeThrow.
603 if (Sema::canCalleeThrow(S, E: IsDtor ? nullptr : cast<Expr>(Val: E), D)) {
604 if (const auto *FD = dyn_cast<FunctionDecl>(Val: D)) {
605 // co_await promise.final_suspend() could end up calling
606 // __builtin_coro_resume for symmetric transfer if await_suspend()
607 // returns a handle. In that case, even __builtin_coro_resume is not
608 // declared as noexcept and may throw, it does not throw _into_ the
609 // coroutine that just suspended, but rather throws back out from
610 // whoever called coroutine_handle::resume(), hence we claim that
611 // logically it does not throw.
612 if (FD->getBuiltinID() == Builtin::BI__builtin_coro_resume)
613 return;
614 }
615 if (ThrowingDecls.empty()) {
616 // [dcl.fct.def.coroutine]p15
617 // The expression co_await promise.final_suspend() shall not be
618 // potentially-throwing ([except.spec]).
619 //
620 // First time seeing an error, emit the error message.
621 S.Diag(Loc: cast<FunctionDecl>(Val: S.CurContext)->getLocation(),
622 DiagID: diag::err_coroutine_promise_final_suspend_requires_nothrow);
623 }
624 ThrowingDecls.insert(Ptr: D);
625 }
626 };
627
628 if (auto *CE = dyn_cast<CXXConstructExpr>(Val: E)) {
629 CXXConstructorDecl *Ctor = CE->getConstructor();
630 checkDeclNoexcept(Ctor);
631 // Check the corresponding destructor of the constructor.
632 checkDeclNoexcept(Ctor->getParent()->getDestructor(), /*IsDtor=*/true);
633 } else if (auto *CE = dyn_cast<CallExpr>(Val: E)) {
634 if (CE->isTypeDependent())
635 return;
636
637 checkDeclNoexcept(CE->getCalleeDecl());
638 QualType ReturnType = CE->getCallReturnType(Ctx: S.getASTContext());
639 // Check the destructor of the call return type, if any.
640 if (ReturnType.isDestructedType() ==
641 QualType::DestructionKind::DK_cxx_destructor) {
642 const auto *T =
643 cast<RecordType>(Val: ReturnType.getCanonicalType().getTypePtr());
644 checkDeclNoexcept(
645 cast<CXXRecordDecl>(Val: T->getDecl())->getDefinition()->getDestructor(),
646 /*IsDtor=*/true);
647 }
648 } else
649 for (const auto *Child : E->children()) {
650 if (!Child)
651 continue;
652 checkNoThrow(S, E: Child, ThrowingDecls);
653 }
654}
655
656bool Sema::checkFinalSuspendNoThrow(const Stmt *FinalSuspend) {
657 llvm::SmallPtrSet<const Decl *, 4> ThrowingDecls;
658 // We first collect all declarations that should not throw but not declared
659 // with noexcept. We then sort them based on the location before printing.
660 // This is to avoid emitting the same note multiple times on the same
661 // declaration, and also provide a deterministic order for the messages.
662 checkNoThrow(S&: *this, E: FinalSuspend, ThrowingDecls);
663 auto SortedDecls = llvm::SmallVector<const Decl *, 4>{ThrowingDecls.begin(),
664 ThrowingDecls.end()};
665 sort(C&: SortedDecls, Comp: [](const Decl *A, const Decl *B) {
666 return A->getEndLoc() < B->getEndLoc();
667 });
668 for (const auto *D : SortedDecls) {
669 Diag(Loc: D->getEndLoc(), DiagID: diag::note_coroutine_function_declare_noexcept);
670 }
671 return ThrowingDecls.empty();
672}
673
674// [stmt.return.coroutine]p1:
675// A coroutine shall not enclose a return statement ([stmt.return]).
676static void checkReturnStmtInCoroutine(Sema &S, FunctionScopeInfo *FSI) {
677 assert(FSI && "FunctionScopeInfo is null");
678 assert(FSI->FirstCoroutineStmtLoc.isValid() &&
679 "first coroutine location not set");
680 if (FSI->FirstReturnLoc.isInvalid())
681 return;
682 S.Diag(Loc: FSI->FirstReturnLoc, DiagID: diag::err_return_in_coroutine);
683 S.Diag(Loc: FSI->FirstCoroutineStmtLoc, DiagID: diag::note_declared_coroutine_here)
684 << FSI->getFirstCoroutineStmtKeyword();
685}
686
687bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc,
688 StringRef Keyword) {
689 // Ignore previous expr evaluation contexts.
690 EnterExpressionEvaluationContextForFunction PotentiallyEvaluated(
691 *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
692 dyn_cast_or_null<FunctionDecl>(Val: CurContext));
693
694 if (!checkCoroutineContext(S&: *this, Loc: KWLoc, Keyword))
695 return false;
696 auto *ScopeInfo = getCurFunction();
697 assert(ScopeInfo->CoroutinePromise);
698
699 // Avoid duplicate errors, report only on first keyword.
700 if (ScopeInfo->FirstCoroutineStmtLoc == KWLoc)
701 checkReturnStmtInCoroutine(S&: *this, FSI: ScopeInfo);
702
703 // If we have existing coroutine statements then we have already built
704 // the initial and final suspend points.
705 if (!ScopeInfo->NeedsCoroutineSuspends)
706 return true;
707
708 ScopeInfo->setNeedsCoroutineSuspends(false);
709
710 auto *Fn = cast<FunctionDecl>(Val: CurContext);
711 SourceLocation Loc = Fn->getLocation();
712 // Build the initial suspend point
713 auto buildSuspends = [&](StringRef Name) mutable -> StmtResult {
714 ExprResult Operand =
715 buildPromiseCall(S&: *this, Promise: ScopeInfo->CoroutinePromise, Loc, Name, Args: {});
716 if (Operand.isInvalid())
717 return StmtError();
718 ExprResult Suspend =
719 buildOperatorCoawaitCall(SemaRef&: *this, S: SC, Loc, E: Operand.get());
720 if (Suspend.isInvalid())
721 return StmtError();
722 Suspend = BuildResolvedCoawaitExpr(KwLoc: Loc, Operand: Operand.get(), Awaiter: Suspend.get(),
723 /*IsImplicit*/ true);
724 Suspend = ActOnFinishFullExpr(Expr: Suspend.get(), /*DiscardedValue*/ false);
725 if (Suspend.isInvalid()) {
726 Diag(Loc, DiagID: diag::note_coroutine_promise_suspend_implicitly_required)
727 << ((Name == "initial_suspend") ? 0 : 1);
728 Diag(Loc: KWLoc, DiagID: diag::note_declared_coroutine_here) << Keyword;
729 return StmtError();
730 }
731 return cast<Stmt>(Val: Suspend.get());
732 };
733
734 StmtResult InitSuspend = buildSuspends("initial_suspend");
735 if (InitSuspend.isInvalid())
736 return true;
737
738 StmtResult FinalSuspend = buildSuspends("final_suspend");
739 if (FinalSuspend.isInvalid() || !checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
740 return true;
741
742 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
743
744 return true;
745}
746
747// Recursively walks up the scope hierarchy until either a 'catch' or a function
748// scope is found, whichever comes first.
749static bool isWithinCatchScope(Scope *S) {
750 // 'co_await' and 'co_yield' keywords are disallowed within catch blocks, but
751 // lambdas that use 'co_await' are allowed. The loop below ends when a
752 // function scope is found in order to ensure the following behavior:
753 //
754 // void foo() { // <- function scope
755 // try { //
756 // co_await x; // <- 'co_await' is OK within a function scope
757 // } catch { // <- catch scope
758 // co_await x; // <- 'co_await' is not OK within a catch scope
759 // []() { // <- function scope
760 // co_await x; // <- 'co_await' is OK within a function scope
761 // }();
762 // }
763 // }
764 while (S && !S->isFunctionScope()) {
765 if (S->isCatchScope())
766 return true;
767 S = S->getParent();
768 }
769 return false;
770}
771
772// [expr.await]p2, emphasis added: "An await-expression shall appear only in
773// a *potentially evaluated* expression within the compound-statement of a
774// function-body *outside of a handler* [...] A context within a function
775// where an await-expression can appear is called a suspension context of the
776// function."
777static bool checkSuspensionContext(Sema &S, SourceLocation Loc,
778 StringRef Keyword) {
779 // First emphasis of [expr.await]p2: must be a potentially evaluated context.
780 // That is, 'co_await' and 'co_yield' cannot appear in subexpressions of
781 // \c sizeof.
782 const auto ExprContext = S.currentEvaluationContext().ExprContext;
783 const bool BadContext =
784 S.isUnevaluatedContext() ||
785 (ExprContext != Sema::ExpressionEvaluationContextRecord::EK_Other &&
786 ExprContext != Sema::ExpressionEvaluationContextRecord::EK_VariableInit);
787 if (BadContext) {
788 S.Diag(Loc, DiagID: diag::err_coroutine_unevaluated_context) << Keyword;
789 return false;
790 }
791
792 // Second emphasis of [expr.await]p2: must be outside of an exception handler.
793 if (isWithinCatchScope(S: S.getCurScope())) {
794 S.Diag(Loc, DiagID: diag::err_coroutine_within_handler) << Keyword;
795 return false;
796 }
797 return true;
798}
799
800ExprResult Sema::ActOnCoawaitExpr(Scope *S, SourceLocation Loc, Expr *E) {
801 if (!checkSuspensionContext(S&: *this, Loc, Keyword: "co_await"))
802 return ExprError();
803
804 if (!ActOnCoroutineBodyStart(SC: S, KWLoc: Loc, Keyword: "co_await")) {
805 return ExprError();
806 }
807
808 if (E->hasPlaceholderType()) {
809 ExprResult R = CheckPlaceholderExpr(E);
810 if (R.isInvalid()) return ExprError();
811 E = R.get();
812 }
813
814 ExprResult Lookup = BuildOperatorCoawaitLookupExpr(S, Loc);
815 if (Lookup.isInvalid())
816 return ExprError();
817 return BuildUnresolvedCoawaitExpr(KwLoc: Loc, Operand: E,
818 Lookup: cast<UnresolvedLookupExpr>(Val: Lookup.get()));
819}
820
821ExprResult Sema::BuildOperatorCoawaitLookupExpr(Scope *S, SourceLocation Loc) {
822 DeclarationName OpName =
823 Context.DeclarationNames.getCXXOperatorName(Op: OO_Coawait);
824 LookupResult Operators(*this, OpName, SourceLocation(),
825 Sema::LookupOperatorName);
826 LookupName(R&: Operators, S);
827
828 assert(!Operators.isAmbiguous() && "Operator lookup cannot be ambiguous");
829 const auto &Functions = Operators.asUnresolvedSet();
830 Expr *CoawaitOp = UnresolvedLookupExpr::Create(
831 Context, /*NamingClass*/ nullptr, QualifierLoc: NestedNameSpecifierLoc(),
832 NameInfo: DeclarationNameInfo(OpName, Loc), /*RequiresADL*/ true, Begin: Functions.begin(),
833 End: Functions.end(), /*KnownDependent=*/false,
834 /*KnownInstantiationDependent=*/false);
835 assert(CoawaitOp);
836 return CoawaitOp;
837}
838
839static bool isAttributedCoroAwaitElidable(const QualType &QT) {
840 auto *Record = QT->getAsCXXRecordDecl();
841 return Record && Record->hasAttr<CoroAwaitElidableAttr>();
842}
843
844static void applySafeElideContext(Expr *Operand) {
845 // Strip both implicit nodes and parentheses to find the underlying CallExpr.
846 // The AST may have these in either order, so we apply both transformations
847 // iteratively until reaching a fixed point.
848 auto *Call = dyn_cast<CallExpr>(Val: IgnoreExprNodes(
849 E: Operand, Fns&: IgnoreImplicitSingleStep, Fns&: IgnoreParensSingleStep));
850 if (!Call || !Call->isPRValue())
851 return;
852
853 if (!isAttributedCoroAwaitElidable(QT: Call->getType()))
854 return;
855
856 Call->setCoroElideSafe();
857
858 // Check parameter
859 auto *Fn = llvm::dyn_cast_if_present<FunctionDecl>(Val: Call->getCalleeDecl());
860 if (!Fn)
861 return;
862
863 size_t ParmIdx = 0;
864 for (ParmVarDecl *PD : Fn->parameters()) {
865 if (PD->hasAttr<CoroAwaitElidableArgumentAttr>())
866 applySafeElideContext(Operand: Call->getArg(Arg: ParmIdx));
867
868 ParmIdx++;
869 }
870}
871
872// Attempts to resolve and build a CoawaitExpr from "raw" inputs, bailing out to
873// DependentCoawaitExpr if needed.
874ExprResult Sema::BuildUnresolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
875 UnresolvedLookupExpr *Lookup) {
876 auto *FSI = checkCoroutineContext(S&: *this, Loc, Keyword: "co_await");
877 if (!FSI)
878 return ExprError();
879
880 if (Operand->hasPlaceholderType()) {
881 ExprResult R = CheckPlaceholderExpr(E: Operand);
882 if (R.isInvalid())
883 return ExprError();
884 Operand = R.get();
885 }
886
887 auto *Promise = FSI->CoroutinePromise;
888 if (Promise->getType()->isDependentType()) {
889 Expr *Res = new (Context)
890 DependentCoawaitExpr(Loc, Context.DependentTy, Operand, Lookup);
891 return Res;
892 }
893
894 auto *RD = Promise->getType()->getAsCXXRecordDecl();
895
896 bool CurFnAwaitElidable = isAttributedCoroAwaitElidable(
897 QT: getCurFunctionDecl(/*AllowLambda=*/true)->getReturnType());
898
899 if (CurFnAwaitElidable)
900 applySafeElideContext(Operand);
901
902 Expr *Transformed = Operand;
903 if (lookupMember(S&: *this, Name: "await_transform", RD, Loc)) {
904 ExprResult R =
905 buildPromiseCall(S&: *this, Promise, Loc, Name: "await_transform", Args: Operand);
906 if (R.isInvalid()) {
907 Diag(Loc,
908 DiagID: diag::note_coroutine_promise_implicit_await_transform_required_here)
909 << Operand->getSourceRange();
910 return ExprError();
911 }
912 Transformed = R.get();
913 }
914 ExprResult Awaiter = BuildOperatorCoawaitCall(Loc, E: Transformed, Lookup);
915 if (Awaiter.isInvalid())
916 return ExprError();
917
918 return BuildResolvedCoawaitExpr(KwLoc: Loc, Operand, Awaiter: Awaiter.get());
919}
920
921ExprResult Sema::BuildResolvedCoawaitExpr(SourceLocation Loc, Expr *Operand,
922 Expr *Awaiter, bool IsImplicit) {
923 auto *Coroutine = checkCoroutineContext(S&: *this, Loc, Keyword: "co_await", IsImplicit);
924 if (!Coroutine)
925 return ExprError();
926
927 if (Awaiter->hasPlaceholderType()) {
928 ExprResult R = CheckPlaceholderExpr(E: Awaiter);
929 if (R.isInvalid()) return ExprError();
930 Awaiter = R.get();
931 }
932
933 if (Awaiter->getType()->isDependentType()) {
934 Expr *Res = new (Context)
935 CoawaitExpr(Loc, Context.DependentTy, Operand, Awaiter, IsImplicit);
936 return Res;
937 }
938
939 // If the expression is a temporary, materialize it as an lvalue so that we
940 // can use it multiple times.
941 if (Awaiter->isPRValue())
942 Awaiter = CreateMaterializeTemporaryExpr(T: Awaiter->getType(), Temporary: Awaiter, BoundToLvalueReference: true);
943
944 // The location of the `co_await` token cannot be used when constructing
945 // the member call expressions since it's before the location of `Expr`, which
946 // is used as the start of the member call expression.
947 SourceLocation CallLoc = Awaiter->getExprLoc();
948
949 // Build the await_ready, await_suspend, await_resume calls.
950 ReadySuspendResumeResult RSS =
951 buildCoawaitCalls(S&: *this, CoroPromise: Coroutine->CoroutinePromise, Loc: CallLoc, E: Awaiter);
952 if (RSS.IsInvalid)
953 return ExprError();
954
955 Expr *Res = new (Context)
956 CoawaitExpr(Loc, Operand, Awaiter, RSS.Results[0], RSS.Results[1],
957 RSS.Results[2], RSS.OpaqueValue, IsImplicit);
958
959 return Res;
960}
961
962ExprResult Sema::ActOnCoyieldExpr(Scope *S, SourceLocation Loc, Expr *E) {
963 if (!checkSuspensionContext(S&: *this, Loc, Keyword: "co_yield"))
964 return ExprError();
965
966 if (!ActOnCoroutineBodyStart(SC: S, KWLoc: Loc, Keyword: "co_yield")) {
967 return ExprError();
968 }
969
970 // Build yield_value call.
971 ExprResult Awaitable = buildPromiseCall(
972 S&: *this, Promise: getCurFunction()->CoroutinePromise, Loc, Name: "yield_value", Args: E);
973 if (Awaitable.isInvalid())
974 return ExprError();
975
976 // Build 'operator co_await' call.
977 Awaitable = buildOperatorCoawaitCall(SemaRef&: *this, S, Loc, E: Awaitable.get());
978 if (Awaitable.isInvalid())
979 return ExprError();
980
981 return BuildCoyieldExpr(KwLoc: Loc, E: Awaitable.get());
982}
983ExprResult Sema::BuildCoyieldExpr(SourceLocation Loc, Expr *E) {
984 auto *Coroutine = checkCoroutineContext(S&: *this, Loc, Keyword: "co_yield");
985 if (!Coroutine)
986 return ExprError();
987
988 if (E->hasPlaceholderType()) {
989 ExprResult R = CheckPlaceholderExpr(E);
990 if (R.isInvalid()) return ExprError();
991 E = R.get();
992 }
993
994 Expr *Operand = E;
995
996 if (E->getType()->isDependentType()) {
997 Expr *Res = new (Context) CoyieldExpr(Loc, Context.DependentTy, Operand, E);
998 return Res;
999 }
1000
1001 // If the expression is a temporary, materialize it as an lvalue so that we
1002 // can use it multiple times.
1003 if (E->isPRValue())
1004 E = CreateMaterializeTemporaryExpr(T: E->getType(), Temporary: E, BoundToLvalueReference: true);
1005
1006 // Build the await_ready, await_suspend, await_resume calls.
1007 ReadySuspendResumeResult RSS = buildCoawaitCalls(
1008 S&: *this, CoroPromise: Coroutine->CoroutinePromise, Loc, E);
1009 if (RSS.IsInvalid)
1010 return ExprError();
1011
1012 Expr *Res =
1013 new (Context) CoyieldExpr(Loc, Operand, E, RSS.Results[0], RSS.Results[1],
1014 RSS.Results[2], RSS.OpaqueValue);
1015
1016 return Res;
1017}
1018
1019StmtResult Sema::ActOnCoreturnStmt(Scope *S, SourceLocation Loc, Expr *E) {
1020 if (!ActOnCoroutineBodyStart(SC: S, KWLoc: Loc, Keyword: "co_return")) {
1021 return StmtError();
1022 }
1023 return BuildCoreturnStmt(KwLoc: Loc, E);
1024}
1025
1026StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E,
1027 bool IsImplicit) {
1028 auto *FSI = checkCoroutineContext(S&: *this, Loc, Keyword: "co_return", IsImplicit);
1029 if (!FSI)
1030 return StmtError();
1031
1032 if (E && E->hasPlaceholderType() &&
1033 !E->hasPlaceholderType(K: BuiltinType::Overload)) {
1034 ExprResult R = CheckPlaceholderExpr(E);
1035 if (R.isInvalid()) return StmtError();
1036 E = R.get();
1037 }
1038
1039 VarDecl *Promise = FSI->CoroutinePromise;
1040 ExprResult PC;
1041 if (E && (isa<InitListExpr>(Val: E) || !E->getType()->isVoidType())) {
1042 getNamedReturnInfo(E, Mode: SimplerImplicitMoveMode::ForceOn);
1043 PC = buildPromiseCall(S&: *this, Promise, Loc, Name: "return_value", Args: E);
1044 } else {
1045 E = MakeFullDiscardedValueExpr(Arg: E).get();
1046 PC = buildPromiseCall(S&: *this, Promise, Loc, Name: "return_void", Args: {});
1047 }
1048 if (PC.isInvalid())
1049 return StmtError();
1050
1051 Expr *PCE = ActOnFinishFullExpr(Expr: PC.get(), /*DiscardedValue*/ false).get();
1052
1053 Stmt *Res = new (Context) CoreturnStmt(Loc, E, PCE, IsImplicit);
1054 return Res;
1055}
1056
1057/// Look up the std::nothrow object.
1058static Expr *buildStdNoThrowDeclRef(Sema &S, SourceLocation Loc) {
1059 NamespaceDecl *Std = S.getStdNamespace();
1060 assert(Std && "Should already be diagnosed");
1061
1062 LookupResult Result(S, &S.PP.getIdentifierTable().get(Name: "nothrow"), Loc,
1063 Sema::LookupOrdinaryName);
1064 if (!S.LookupQualifiedName(R&: Result, LookupCtx: Std)) {
1065 // <coroutine> is not requred to include <new>, so we couldn't omit
1066 // the check here.
1067 S.Diag(Loc, DiagID: diag::err_implicit_coroutine_std_nothrow_type_not_found);
1068 return nullptr;
1069 }
1070
1071 auto *VD = Result.getAsSingle<VarDecl>();
1072 if (!VD) {
1073 Result.suppressDiagnostics();
1074 // We found something weird. Complain about the first thing we found.
1075 NamedDecl *Found = *Result.begin();
1076 S.Diag(Loc: Found->getLocation(), DiagID: diag::err_malformed_std_nothrow);
1077 return nullptr;
1078 }
1079
1080 ExprResult DR = S.BuildDeclRefExpr(D: VD, Ty: VD->getType(), VK: VK_LValue, Loc);
1081 if (DR.isInvalid())
1082 return nullptr;
1083
1084 return DR.get();
1085}
1086
1087static TypeSourceInfo *getTypeSourceInfoForStdAlignValT(Sema &S,
1088 SourceLocation Loc) {
1089 EnumDecl *StdAlignValDecl = S.getStdAlignValT();
1090 CanQualType StdAlignValT = S.Context.getCanonicalTagType(TD: StdAlignValDecl);
1091 return S.Context.getTrivialTypeSourceInfo(T: StdAlignValT);
1092}
1093
1094// When searching for custom allocators on the PromiseType we want to
1095// warn that we will ignore type aware allocators.
1096static bool DiagnoseTypeAwareAllocators(Sema &S, SourceLocation Loc,
1097 unsigned DiagnosticID,
1098 DeclarationName Name,
1099 QualType PromiseType) {
1100 assert(PromiseType->isRecordType());
1101
1102 LookupResult R(S, Name, Loc, Sema::LookupOrdinaryName);
1103 S.LookupQualifiedName(R, LookupCtx: PromiseType->getAsCXXRecordDecl());
1104 bool HaveIssuedWarning = false;
1105 for (auto Decl : R) {
1106 if (!Decl->getUnderlyingDecl()
1107 ->getAsFunction()
1108 ->isTypeAwareOperatorNewOrDelete())
1109 continue;
1110 if (!HaveIssuedWarning) {
1111 S.Diag(Loc, DiagID: DiagnosticID) << Name;
1112 HaveIssuedWarning = true;
1113 }
1114 S.Diag(Loc: Decl->getLocation(), DiagID: diag::note_type_aware_operator_declared)
1115 << /* isTypeAware=*/1 << Decl << Decl->getDeclContext();
1116 }
1117 R.suppressDiagnostics();
1118 return HaveIssuedWarning;
1119}
1120
1121// Find an appropriate delete for the promise.
1122static bool findDeleteForPromise(Sema &S, SourceLocation Loc, QualType PromiseType,
1123 FunctionDecl *&OperatorDelete) {
1124 DeclarationName DeleteName =
1125 S.Context.DeclarationNames.getCXXOperatorName(Op: OO_Delete);
1126 DiagnoseTypeAwareAllocators(S, Loc,
1127 DiagnosticID: diag::warn_coroutine_type_aware_allocator_ignored,
1128 Name: DeleteName, PromiseType);
1129 auto *PointeeRD = PromiseType->getAsCXXRecordDecl();
1130 assert(PointeeRD && "PromiseType must be a CxxRecordDecl type");
1131
1132 const bool Overaligned = S.getLangOpts().CoroAlignedAllocation;
1133
1134 // [dcl.fct.def.coroutine]p12
1135 // The deallocation function's name is looked up by searching for it in the
1136 // scope of the promise type. If nothing is found, a search is performed in
1137 // the global scope.
1138 ImplicitDeallocationParameters IDP = {
1139 alignedAllocationModeFromBool(IsAligned: Overaligned), SizedDeallocationMode::Yes};
1140 if (S.FindDeallocationFunction(StartLoc: Loc, RD: PointeeRD, Name: DeleteName, Operator&: OperatorDelete,
1141 IDP, /*Diagnose=*/true))
1142 return false;
1143
1144 // [dcl.fct.def.coroutine]p12
1145 // If both a usual deallocation function with only a pointer parameter and a
1146 // usual deallocation function with both a pointer parameter and a size
1147 // parameter are found, then the selected deallocation function shall be the
1148 // one with two parameters. Otherwise, the selected deallocation function
1149 // shall be the function with one parameter.
1150 if (!OperatorDelete) {
1151 // Look for a global declaration.
1152 // Sema::FindUsualDeallocationFunction will try to find the one with two
1153 // parameters first. It will return the deallocation function with one
1154 // parameter if failed.
1155 // Coroutines can always provide their required size.
1156 IDP.PassSize = SizedDeallocationMode::Yes;
1157 OperatorDelete = S.FindUsualDeallocationFunction(StartLoc: Loc, IDP, Name: DeleteName);
1158
1159 if (!OperatorDelete)
1160 return false;
1161 }
1162
1163 assert(!OperatorDelete->isTypeAwareOperatorNewOrDelete());
1164 S.MarkFunctionReferenced(Loc, Func: OperatorDelete);
1165 return true;
1166}
1167
1168
1169void Sema::CheckCompletedCoroutineBody(FunctionDecl *FD, Stmt *&Body) {
1170 FunctionScopeInfo *Fn = getCurFunction();
1171 assert(Fn && Fn->isCoroutine() && "not a coroutine");
1172 if (!Body) {
1173 assert(FD->isInvalidDecl() &&
1174 "a null body is only allowed for invalid declarations");
1175 return;
1176 }
1177 // We have a function that uses coroutine keywords, but we failed to build
1178 // the promise type.
1179 if (!Fn->CoroutinePromise)
1180 return FD->setInvalidDecl();
1181
1182 if (isa<CoroutineBodyStmt>(Val: Body)) {
1183 // Nothing todo. the body is already a transformed coroutine body statement.
1184 return;
1185 }
1186
1187 // The always_inline attribute doesn't reliably apply to a coroutine,
1188 // because the coroutine will be split into pieces and some pieces
1189 // might be called indirectly, as in a virtual call. Even the ramp
1190 // function cannot be inlined at -O0, due to pipeline ordering
1191 // problems (see https://llvm.org/PR53413). Tell the user about it.
1192 if (FD->hasAttr<AlwaysInlineAttr>())
1193 Diag(Loc: FD->getLocation(), DiagID: diag::warn_always_inline_coroutine);
1194
1195 // The design of coroutines means we cannot allow use of VLAs within one, so
1196 // diagnose if we've seen a VLA in the body of this function.
1197 if (Fn->FirstVLALoc.isValid())
1198 Diag(Loc: Fn->FirstVLALoc, DiagID: diag::err_vla_in_coroutine_unsupported);
1199
1200 // Coroutines will get splitted into pieces. The GNU address of label
1201 // extension wouldn't be meaningful in coroutines.
1202 for (AddrLabelExpr *ALE : Fn->AddrLabels)
1203 Diag(Loc: ALE->getBeginLoc(), DiagID: diag::err_coro_invalid_addr_of_label);
1204
1205 // Coroutines always return a handle, so they can't be [[noreturn]].
1206 if (FD->isNoReturn())
1207 Diag(Loc: FD->getLocation(), DiagID: diag::warn_noreturn_coroutine) << FD;
1208
1209 CoroutineStmtBuilder Builder(*this, *FD, *Fn, Body);
1210 if (Builder.isInvalid() || !Builder.buildStatements())
1211 return FD->setInvalidDecl();
1212
1213 // Build body for the coroutine wrapper statement.
1214 Body = CoroutineBodyStmt::Create(C: Context, Args: Builder);
1215}
1216
1217static CompoundStmt *buildCoroutineBody(Stmt *Body, ASTContext &Context) {
1218 if (auto *CS = dyn_cast<CompoundStmt>(Val: Body))
1219 return CS;
1220
1221 // The body of the coroutine may be a try statement if it is in
1222 // 'function-try-block' syntax. Here we wrap it into a compound
1223 // statement for consistency.
1224 assert(isa<CXXTryStmt>(Body) && "Unimaged coroutine body type");
1225 return CompoundStmt::Create(C: Context, Stmts: {Body}, FPFeatures: FPOptionsOverride(),
1226 LB: SourceLocation(), RB: SourceLocation());
1227}
1228
1229CoroutineStmtBuilder::CoroutineStmtBuilder(Sema &S, FunctionDecl &FD,
1230 sema::FunctionScopeInfo &Fn,
1231 Stmt *Body)
1232 : S(S), FD(FD), Fn(Fn), Loc(FD.getLocation()),
1233 IsPromiseDependentType(
1234 !Fn.CoroutinePromise ||
1235 Fn.CoroutinePromise->getType()->isDependentType()) {
1236 this->Body = buildCoroutineBody(Body, Context&: S.getASTContext());
1237
1238 for (auto KV : Fn.CoroutineParameterMoves)
1239 this->ParamMovesVector.push_back(Elt: KV.second);
1240 this->ParamMoves = this->ParamMovesVector;
1241
1242 if (!IsPromiseDependentType) {
1243 PromiseRecordDecl = Fn.CoroutinePromise->getType()->getAsCXXRecordDecl();
1244 assert(PromiseRecordDecl && "Type should have already been checked");
1245 }
1246 this->IsValid = makePromiseStmt() && makeInitialAndFinalSuspend();
1247}
1248
1249bool CoroutineStmtBuilder::buildStatements() {
1250 assert(this->IsValid && "coroutine already invalid");
1251 this->IsValid = makeReturnObject();
1252 if (this->IsValid && !IsPromiseDependentType)
1253 buildDependentStatements();
1254 return this->IsValid;
1255}
1256
1257bool CoroutineStmtBuilder::buildDependentStatements() {
1258 assert(this->IsValid && "coroutine already invalid");
1259 assert(!this->IsPromiseDependentType &&
1260 "coroutine cannot have a dependent promise type");
1261 this->IsValid = makeOnException() && makeOnFallthrough() &&
1262 makeGroDeclAndReturnStmt() && makeReturnOnAllocFailure() &&
1263 makeNewAndDeleteExpr();
1264 return this->IsValid;
1265}
1266
1267bool CoroutineStmtBuilder::makePromiseStmt() {
1268 // Form a declaration statement for the promise declaration, so that AST
1269 // visitors can more easily find it.
1270 StmtResult PromiseStmt =
1271 S.ActOnDeclStmt(Decl: S.ConvertDeclToDeclGroup(Ptr: Fn.CoroutinePromise), StartLoc: Loc, EndLoc: Loc);
1272 if (PromiseStmt.isInvalid())
1273 return false;
1274
1275 this->Promise = PromiseStmt.get();
1276 return true;
1277}
1278
1279bool CoroutineStmtBuilder::makeInitialAndFinalSuspend() {
1280 if (Fn.hasInvalidCoroutineSuspends())
1281 return false;
1282 this->InitialSuspend = cast<Expr>(Val: Fn.CoroutineSuspends.first);
1283 this->FinalSuspend = cast<Expr>(Val: Fn.CoroutineSuspends.second);
1284 return true;
1285}
1286
1287static bool diagReturnOnAllocFailure(Sema &S, Expr *E,
1288 CXXRecordDecl *PromiseRecordDecl,
1289 FunctionScopeInfo &Fn) {
1290 auto Loc = E->getExprLoc();
1291 if (auto *DeclRef = dyn_cast_or_null<DeclRefExpr>(Val: E)) {
1292 auto *Decl = DeclRef->getDecl();
1293 if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(Val: Decl)) {
1294 if (Method->isStatic())
1295 return true;
1296 else
1297 Loc = Decl->getLocation();
1298 }
1299 }
1300
1301 S.Diag(
1302 Loc,
1303 DiagID: diag::err_coroutine_promise_get_return_object_on_allocation_failure)
1304 << PromiseRecordDecl;
1305 S.Diag(Loc: Fn.FirstCoroutineStmtLoc, DiagID: diag::note_declared_coroutine_here)
1306 << Fn.getFirstCoroutineStmtKeyword();
1307 return false;
1308}
1309
1310bool CoroutineStmtBuilder::makeReturnOnAllocFailure() {
1311 assert(!IsPromiseDependentType &&
1312 "cannot make statement while the promise type is dependent");
1313
1314 // [dcl.fct.def.coroutine]p10
1315 // If a search for the name get_return_object_on_allocation_failure in
1316 // the scope of the promise type ([class.member.lookup]) finds any
1317 // declarations, then the result of a call to an allocation function used to
1318 // obtain storage for the coroutine state is assumed to return nullptr if it
1319 // fails to obtain storage, ... If the allocation function returns nullptr,
1320 // ... and the return value is obtained by a call to
1321 // T::get_return_object_on_allocation_failure(), where T is the
1322 // promise type.
1323 DeclarationName DN =
1324 S.PP.getIdentifierInfo(Name: "get_return_object_on_allocation_failure");
1325 LookupResult Found(S, DN, Loc, Sema::LookupMemberName);
1326 if (!S.LookupQualifiedName(R&: Found, LookupCtx: PromiseRecordDecl))
1327 return true;
1328
1329 CXXScopeSpec SS;
1330 ExprResult DeclNameExpr =
1331 S.BuildDeclarationNameExpr(SS, R&: Found, /*NeedsADL=*/false);
1332 if (DeclNameExpr.isInvalid())
1333 return false;
1334
1335 if (!diagReturnOnAllocFailure(S, E: DeclNameExpr.get(), PromiseRecordDecl, Fn))
1336 return false;
1337
1338 ExprResult ReturnObjectOnAllocationFailure =
1339 S.BuildCallExpr(S: nullptr, Fn: DeclNameExpr.get(), LParenLoc: Loc, ArgExprs: {}, RParenLoc: Loc);
1340 if (ReturnObjectOnAllocationFailure.isInvalid())
1341 return false;
1342
1343 StmtResult ReturnStmt =
1344 S.BuildReturnStmt(ReturnLoc: Loc, RetValExp: ReturnObjectOnAllocationFailure.get());
1345 if (ReturnStmt.isInvalid()) {
1346 S.Diag(Loc: Found.getFoundDecl()->getLocation(), DiagID: diag::note_member_declared_here)
1347 << DN;
1348 S.Diag(Loc: Fn.FirstCoroutineStmtLoc, DiagID: diag::note_declared_coroutine_here)
1349 << Fn.getFirstCoroutineStmtKeyword();
1350 return false;
1351 }
1352
1353 this->ReturnStmtOnAllocFailure = ReturnStmt.get();
1354 return true;
1355}
1356
1357// Collect placement arguments for allocation function of coroutine FD.
1358// Return true if we collect placement arguments succesfully. Return false,
1359// otherwise.
1360static bool collectPlacementArgs(Sema &S, FunctionDecl &FD, SourceLocation Loc,
1361 SmallVectorImpl<Expr *> &PlacementArgs) {
1362 if (auto *MD = dyn_cast<CXXMethodDecl>(Val: &FD)) {
1363 if (MD->isImplicitObjectMemberFunction() && !isLambdaCallOperator(MD)) {
1364 ExprResult ThisExpr = S.ActOnCXXThis(Loc);
1365 if (ThisExpr.isInvalid())
1366 return false;
1367 ThisExpr = S.CreateBuiltinUnaryOp(OpLoc: Loc, Opc: UO_Deref, InputExpr: ThisExpr.get());
1368 if (ThisExpr.isInvalid())
1369 return false;
1370 PlacementArgs.push_back(Elt: ThisExpr.get());
1371 }
1372 }
1373
1374 for (auto *PD : FD.parameters()) {
1375 if (PD->getType()->isDependentType())
1376 continue;
1377
1378 // Build a reference to the parameter.
1379 auto PDLoc = PD->getLocation();
1380 ExprResult PDRefExpr =
1381 S.BuildDeclRefExpr(D: PD, Ty: PD->getOriginalType().getNonReferenceType(),
1382 VK: ExprValueKind::VK_LValue, Loc: PDLoc);
1383 if (PDRefExpr.isInvalid())
1384 return false;
1385
1386 PlacementArgs.push_back(Elt: PDRefExpr.get());
1387 }
1388
1389 return true;
1390}
1391
1392bool CoroutineStmtBuilder::makeNewAndDeleteExpr() {
1393 // Form and check allocation and deallocation calls.
1394 assert(!IsPromiseDependentType &&
1395 "cannot make statement while the promise type is dependent");
1396 QualType PromiseType = Fn.CoroutinePromise->getType();
1397
1398 if (S.RequireCompleteType(Loc, T: PromiseType, DiagID: diag::err_incomplete_type))
1399 return false;
1400
1401 const bool RequiresNoThrowAlloc = ReturnStmtOnAllocFailure != nullptr;
1402
1403 // According to [dcl.fct.def.coroutine]p9, Lookup allocation functions using a
1404 // parameter list composed of the requested size of the coroutine state being
1405 // allocated, followed by the coroutine function's arguments. If a matching
1406 // allocation function exists, use it. Otherwise, use an allocation function
1407 // that just takes the requested size.
1408 //
1409 // [dcl.fct.def.coroutine]p9
1410 // An implementation may need to allocate additional storage for a
1411 // coroutine.
1412 // This storage is known as the coroutine state and is obtained by calling a
1413 // non-array allocation function ([basic.stc.dynamic.allocation]). The
1414 // allocation function's name is looked up by searching for it in the scope of
1415 // the promise type.
1416 // - If any declarations are found, overload resolution is performed on a
1417 // function call created by assembling an argument list. The first argument is
1418 // the amount of space requested, and has type std::size_t. The
1419 // lvalues p1 ... pn are the succeeding arguments.
1420 //
1421 // ...where "p1 ... pn" are defined earlier as:
1422 //
1423 // [dcl.fct.def.coroutine]p3
1424 // The promise type of a coroutine is `std::coroutine_traits<R, P1, ...,
1425 // Pn>`
1426 // , where R is the return type of the function, and `P1, ..., Pn` are the
1427 // sequence of types of the non-object function parameters, preceded by the
1428 // type of the object parameter ([dcl.fct]) if the coroutine is a non-static
1429 // member function. [dcl.fct.def.coroutine]p4 In the following, p_i is an
1430 // lvalue of type P_i, where p1 denotes the object parameter and p_i+1 denotes
1431 // the i-th non-object function parameter for a non-static member function,
1432 // and p_i denotes the i-th function parameter otherwise. For a non-static
1433 // member function, q_1 is an lvalue that denotes *this; any other q_i is an
1434 // lvalue that denotes the parameter copy corresponding to p_i.
1435
1436 FunctionDecl *OperatorNew = nullptr;
1437 SmallVector<Expr *, 1> PlacementArgs;
1438 DeclarationName NewName =
1439 S.getASTContext().DeclarationNames.getCXXOperatorName(Op: OO_New);
1440
1441 const bool PromiseContainsNew = [this, &PromiseType, NewName]() -> bool {
1442 LookupResult R(S, NewName, Loc, Sema::LookupOrdinaryName);
1443
1444 if (PromiseType->isRecordType())
1445 S.LookupQualifiedName(R, LookupCtx: PromiseType->getAsCXXRecordDecl());
1446
1447 return !R.empty() && !R.isAmbiguous();
1448 }();
1449
1450 // Helper function to indicate whether the last lookup found the aligned
1451 // allocation function.
1452 ImplicitAllocationParameters IAP(
1453 alignedAllocationModeFromBool(IsAligned: S.getLangOpts().CoroAlignedAllocation));
1454 auto LookupAllocationFunction = [&](AllocationFunctionScope NewScope =
1455 AllocationFunctionScope::Both,
1456 bool WithoutPlacementArgs = false,
1457 bool ForceNonAligned = false) {
1458 // [dcl.fct.def.coroutine]p9
1459 // The allocation function's name is looked up by searching for it in the
1460 // scope of the promise type.
1461 // - If any declarations are found, ...
1462 // - If no declarations are found in the scope of the promise type, a search
1463 // is performed in the global scope.
1464 if (NewScope == AllocationFunctionScope::Both)
1465 NewScope = PromiseContainsNew ? AllocationFunctionScope::Class
1466 : AllocationFunctionScope::Global;
1467
1468 bool ShouldUseAlignedAlloc =
1469 !ForceNonAligned && S.getLangOpts().CoroAlignedAllocation;
1470 IAP = ImplicitAllocationParameters(
1471 alignedAllocationModeFromBool(IsAligned: ShouldUseAlignedAlloc));
1472
1473 FunctionDecl *UnusedResult = nullptr;
1474 S.FindAllocationFunctions(
1475 StartLoc: Loc, Range: SourceRange(), NewScope,
1476 /*DeleteScope=*/AllocationFunctionScope::Both, AllocType: PromiseType,
1477 /*isArray=*/IsArray: false, IAP,
1478 PlaceArgs: WithoutPlacementArgs ? MultiExprArg{} : PlacementArgs, OperatorNew,
1479 OperatorDelete&: UnusedResult, /*Diagnose=*/false);
1480 assert(!OperatorNew || !OperatorNew->isTypeAwareOperatorNewOrDelete());
1481 };
1482
1483 // We don't expect to call to global operator new with (size, p0, …, pn).
1484 // So if we choose to lookup the allocation function in global scope, we
1485 // shouldn't lookup placement arguments.
1486 if (PromiseContainsNew && !collectPlacementArgs(S, FD, Loc, PlacementArgs))
1487 return false;
1488
1489 LookupAllocationFunction();
1490
1491 if (PromiseContainsNew && !PlacementArgs.empty()) {
1492 // [dcl.fct.def.coroutine]p9
1493 // If no viable function is found ([over.match.viable]), overload
1494 // resolution
1495 // is performed again on a function call created by passing just the amount
1496 // of space required as an argument of type std::size_t.
1497 //
1498 // Proposed Change of [dcl.fct.def.coroutine]p9 in P2014R0:
1499 // Otherwise, overload resolution is performed again on a function call
1500 // created
1501 // by passing the amount of space requested as an argument of type
1502 // std::size_t as the first argument, and the requested alignment as
1503 // an argument of type std:align_val_t as the second argument.
1504 if (!OperatorNew || (S.getLangOpts().CoroAlignedAllocation &&
1505 !isAlignedAllocation(Mode: IAP.PassAlignment)))
1506 LookupAllocationFunction(/*NewScope*/ AllocationFunctionScope::Class,
1507 /*WithoutPlacementArgs*/ true);
1508 }
1509
1510 // Proposed Change of [dcl.fct.def.coroutine]p12 in P2014R0:
1511 // Otherwise, overload resolution is performed again on a function call
1512 // created
1513 // by passing the amount of space requested as an argument of type
1514 // std::size_t as the first argument, and the lvalues p1 ... pn as the
1515 // succeeding arguments. Otherwise, overload resolution is performed again
1516 // on a function call created by passing just the amount of space required as
1517 // an argument of type std::size_t.
1518 //
1519 // So within the proposed change in P2014RO, the priority order of aligned
1520 // allocation functions wiht promise_type is:
1521 //
1522 // void* operator new( std::size_t, std::align_val_t, placement_args... );
1523 // void* operator new( std::size_t, std::align_val_t);
1524 // void* operator new( std::size_t, placement_args... );
1525 // void* operator new( std::size_t);
1526
1527 // Helper variable to emit warnings.
1528 bool FoundNonAlignedInPromise = false;
1529 if (PromiseContainsNew && S.getLangOpts().CoroAlignedAllocation)
1530 if (!OperatorNew || !isAlignedAllocation(Mode: IAP.PassAlignment)) {
1531 FoundNonAlignedInPromise = OperatorNew;
1532
1533 LookupAllocationFunction(/*NewScope*/ AllocationFunctionScope::Class,
1534 /*WithoutPlacementArgs*/ false,
1535 /*ForceNonAligned*/ true);
1536
1537 if (!OperatorNew && !PlacementArgs.empty())
1538 LookupAllocationFunction(/*NewScope*/ AllocationFunctionScope::Class,
1539 /*WithoutPlacementArgs*/ true,
1540 /*ForceNonAligned*/ true);
1541 }
1542
1543 bool IsGlobalOverload =
1544 OperatorNew && !isa<CXXRecordDecl>(Val: OperatorNew->getDeclContext());
1545 // If we didn't find a class-local new declaration and non-throwing new
1546 // was is required then we need to lookup the non-throwing global operator
1547 // instead.
1548 if (RequiresNoThrowAlloc && (!OperatorNew || IsGlobalOverload)) {
1549 auto *StdNoThrow = buildStdNoThrowDeclRef(S, Loc);
1550 if (!StdNoThrow)
1551 return false;
1552 PlacementArgs = {StdNoThrow};
1553 OperatorNew = nullptr;
1554 LookupAllocationFunction(AllocationFunctionScope::Global);
1555 }
1556
1557 // If we found a non-aligned allocation function in the promise_type,
1558 // it indicates the user forgot to update the allocation function. Let's emit
1559 // a warning here.
1560 if (FoundNonAlignedInPromise) {
1561 S.Diag(Loc: OperatorNew->getLocation(),
1562 DiagID: diag::warn_non_aligned_allocation_function)
1563 << &FD;
1564 }
1565
1566 if (!OperatorNew) {
1567 if (PromiseContainsNew) {
1568 S.Diag(Loc, DiagID: diag::err_coroutine_unusable_new) << PromiseType << &FD;
1569 DiagnoseTypeAwareAllocators(
1570 S, Loc, DiagnosticID: diag::note_coroutine_unusable_type_aware_allocators, Name: NewName,
1571 PromiseType);
1572 } else if (RequiresNoThrowAlloc)
1573 S.Diag(Loc, DiagID: diag::err_coroutine_unfound_nothrow_new)
1574 << &FD << S.getLangOpts().CoroAlignedAllocation;
1575
1576 return false;
1577 }
1578 assert(!OperatorNew->isTypeAwareOperatorNewOrDelete());
1579
1580 DiagnoseTypeAwareAllocators(S, Loc,
1581 DiagnosticID: diag::warn_coroutine_type_aware_allocator_ignored,
1582 Name: NewName, PromiseType);
1583
1584 if (RequiresNoThrowAlloc) {
1585 const auto *FT = OperatorNew->getType()->castAs<FunctionProtoType>();
1586 if (!FT->isNothrow(/*ResultIfDependent*/ false)) {
1587 S.Diag(Loc: OperatorNew->getLocation(),
1588 DiagID: diag::err_coroutine_promise_new_requires_nothrow)
1589 << OperatorNew;
1590 S.Diag(Loc, DiagID: diag::note_coroutine_promise_call_implicitly_required)
1591 << OperatorNew;
1592 return false;
1593 }
1594 }
1595
1596 FunctionDecl *OperatorDelete = nullptr;
1597 if (!findDeleteForPromise(S, Loc, PromiseType, OperatorDelete)) {
1598 // FIXME: We should add an error here. According to:
1599 // [dcl.fct.def.coroutine]p12
1600 // If no usual deallocation function is found, the program is ill-formed.
1601 return false;
1602 }
1603
1604 assert(!OperatorDelete->isTypeAwareOperatorNewOrDelete());
1605
1606 Expr *FramePtr =
1607 S.BuildBuiltinCallExpr(Loc, Id: Builtin::BI__builtin_coro_frame, CallArgs: {});
1608
1609 Expr *FrameSize =
1610 S.BuildBuiltinCallExpr(Loc, Id: Builtin::BI__builtin_coro_size, CallArgs: {});
1611
1612 Expr *FrameAlignment = nullptr;
1613
1614 if (S.getLangOpts().CoroAlignedAllocation) {
1615 FrameAlignment =
1616 S.BuildBuiltinCallExpr(Loc, Id: Builtin::BI__builtin_coro_align, CallArgs: {});
1617
1618 TypeSourceInfo *AlignValTy = getTypeSourceInfoForStdAlignValT(S, Loc);
1619 if (!AlignValTy)
1620 return false;
1621
1622 FrameAlignment = S.BuildCXXNamedCast(OpLoc: Loc, Kind: tok::kw_static_cast, Ty: AlignValTy,
1623 E: FrameAlignment, AngleBrackets: SourceRange(Loc, Loc),
1624 Parens: SourceRange(Loc, Loc))
1625 .get();
1626 }
1627
1628 // Make new call.
1629 ExprResult NewRef =
1630 S.BuildDeclRefExpr(D: OperatorNew, Ty: OperatorNew->getType(), VK: VK_LValue, Loc);
1631 if (NewRef.isInvalid())
1632 return false;
1633
1634 SmallVector<Expr *, 2> NewArgs(1, FrameSize);
1635 if (S.getLangOpts().CoroAlignedAllocation &&
1636 isAlignedAllocation(Mode: IAP.PassAlignment))
1637 NewArgs.push_back(Elt: FrameAlignment);
1638
1639 if (OperatorNew->getNumParams() > NewArgs.size())
1640 llvm::append_range(C&: NewArgs, R&: PlacementArgs);
1641
1642 ExprResult NewExpr =
1643 S.BuildCallExpr(S: S.getCurScope(), Fn: NewRef.get(), LParenLoc: Loc, ArgExprs: NewArgs, RParenLoc: Loc);
1644 NewExpr = S.ActOnFinishFullExpr(Expr: NewExpr.get(), /*DiscardedValue*/ false);
1645 if (NewExpr.isInvalid())
1646 return false;
1647
1648 // Make delete call.
1649
1650 QualType OpDeleteQualType = OperatorDelete->getType();
1651
1652 ExprResult DeleteRef =
1653 S.BuildDeclRefExpr(D: OperatorDelete, Ty: OpDeleteQualType, VK: VK_LValue, Loc);
1654 if (DeleteRef.isInvalid())
1655 return false;
1656
1657 Expr *CoroFree =
1658 S.BuildBuiltinCallExpr(Loc, Id: Builtin::BI__builtin_coro_free, CallArgs: {FramePtr});
1659
1660 SmallVector<Expr *, 2> DeleteArgs{CoroFree};
1661
1662 // [dcl.fct.def.coroutine]p12
1663 // The selected deallocation function shall be called with the address of
1664 // the block of storage to be reclaimed as its first argument. If a
1665 // deallocation function with a parameter of type std::size_t is
1666 // used, the size of the block is passed as the corresponding argument.
1667 const auto *OpDeleteType =
1668 OpDeleteQualType.getTypePtr()->castAs<FunctionProtoType>();
1669 if (OpDeleteType->getNumParams() > DeleteArgs.size() &&
1670 S.getASTContext().hasSameUnqualifiedType(
1671 T1: OpDeleteType->getParamType(i: DeleteArgs.size()), T2: FrameSize->getType()))
1672 DeleteArgs.push_back(Elt: FrameSize);
1673
1674 // Proposed Change of [dcl.fct.def.coroutine]p12 in P2014R0:
1675 // If deallocation function lookup finds a usual deallocation function with
1676 // a pointer parameter, size parameter and alignment parameter then this
1677 // will be the selected deallocation function, otherwise if lookup finds a
1678 // usual deallocation function with both a pointer parameter and a size
1679 // parameter, then this will be the selected deallocation function.
1680 // Otherwise, if lookup finds a usual deallocation function with only a
1681 // pointer parameter, then this will be the selected deallocation
1682 // function.
1683 //
1684 // So we are not forced to pass alignment to the deallocation function.
1685 if (S.getLangOpts().CoroAlignedAllocation &&
1686 OpDeleteType->getNumParams() > DeleteArgs.size() &&
1687 S.getASTContext().hasSameUnqualifiedType(
1688 T1: OpDeleteType->getParamType(i: DeleteArgs.size()),
1689 T2: FrameAlignment->getType()))
1690 DeleteArgs.push_back(Elt: FrameAlignment);
1691
1692 ExprResult DeleteExpr =
1693 S.BuildCallExpr(S: S.getCurScope(), Fn: DeleteRef.get(), LParenLoc: Loc, ArgExprs: DeleteArgs, RParenLoc: Loc);
1694 DeleteExpr =
1695 S.ActOnFinishFullExpr(Expr: DeleteExpr.get(), /*DiscardedValue*/ false);
1696 if (DeleteExpr.isInvalid())
1697 return false;
1698
1699 this->Allocate = NewExpr.get();
1700 this->Deallocate = DeleteExpr.get();
1701
1702 return true;
1703}
1704
1705bool CoroutineStmtBuilder::makeOnFallthrough() {
1706 assert(!IsPromiseDependentType &&
1707 "cannot make statement while the promise type is dependent");
1708
1709 // [dcl.fct.def.coroutine]/p6
1710 // If searches for the names return_void and return_value in the scope of
1711 // the promise type each find any declarations, the program is ill-formed.
1712 // [Note 1: If return_void is found, flowing off the end of a coroutine is
1713 // equivalent to a co_return with no operand. Otherwise, flowing off the end
1714 // of a coroutine results in undefined behavior ([stmt.return.coroutine]). —
1715 // end note]
1716 bool HasRVoid, HasRValue;
1717 LookupResult LRVoid =
1718 lookupMember(S, Name: "return_void", RD: PromiseRecordDecl, Loc, Res&: HasRVoid);
1719 LookupResult LRValue =
1720 lookupMember(S, Name: "return_value", RD: PromiseRecordDecl, Loc, Res&: HasRValue);
1721
1722 StmtResult Fallthrough;
1723 if (HasRVoid && HasRValue) {
1724 // FIXME Improve this diagnostic
1725 S.Diag(Loc: FD.getLocation(),
1726 DiagID: diag::err_coroutine_promise_incompatible_return_functions)
1727 << PromiseRecordDecl;
1728 S.Diag(Loc: LRVoid.getRepresentativeDecl()->getLocation(),
1729 DiagID: diag::note_member_first_declared_here)
1730 << LRVoid.getLookupName();
1731 S.Diag(Loc: LRValue.getRepresentativeDecl()->getLocation(),
1732 DiagID: diag::note_member_first_declared_here)
1733 << LRValue.getLookupName();
1734 return false;
1735 } else if (!HasRVoid && !HasRValue) {
1736 // We need to set 'Fallthrough'. Otherwise the other analysis part might
1737 // think the coroutine has defined a return_value method. So it might emit
1738 // **false** positive warning. e.g.,
1739 //
1740 // promise_without_return_func foo() {
1741 // co_await something();
1742 // }
1743 //
1744 // Then AnalysisBasedWarning would emit a warning about `foo()` lacking a
1745 // co_return statements, which isn't correct.
1746 Fallthrough = S.ActOnNullStmt(SemiLoc: PromiseRecordDecl->getLocation());
1747 if (Fallthrough.isInvalid())
1748 return false;
1749 } else if (HasRVoid) {
1750 Fallthrough = S.BuildCoreturnStmt(Loc: FD.getLocation(), E: nullptr,
1751 /*IsImplicit=*/true);
1752 Fallthrough = S.ActOnFinishFullStmt(Stmt: Fallthrough.get());
1753 if (Fallthrough.isInvalid())
1754 return false;
1755 }
1756
1757 this->OnFallthrough = Fallthrough.get();
1758 return true;
1759}
1760
1761bool CoroutineStmtBuilder::makeOnException() {
1762 // Try to form 'p.unhandled_exception();'
1763 assert(!IsPromiseDependentType &&
1764 "cannot make statement while the promise type is dependent");
1765
1766 const bool RequireUnhandledException = S.getLangOpts().CXXExceptions;
1767
1768 if (!lookupMember(S, Name: "unhandled_exception", RD: PromiseRecordDecl, Loc)) {
1769 auto DiagID =
1770 RequireUnhandledException
1771 ? diag::err_coroutine_promise_unhandled_exception_required
1772 : diag::
1773 warn_coroutine_promise_unhandled_exception_required_with_exceptions;
1774 S.Diag(Loc, DiagID) << PromiseRecordDecl;
1775 S.Diag(Loc: PromiseRecordDecl->getLocation(), DiagID: diag::note_defined_here)
1776 << PromiseRecordDecl;
1777 return !RequireUnhandledException;
1778 }
1779
1780 // If exceptions are disabled, don't try to build OnException.
1781 if (!S.getLangOpts().CXXExceptions)
1782 return true;
1783
1784 ExprResult UnhandledException =
1785 buildPromiseCall(S, Promise: Fn.CoroutinePromise, Loc, Name: "unhandled_exception", Args: {});
1786 UnhandledException = S.ActOnFinishFullExpr(Expr: UnhandledException.get(), CC: Loc,
1787 /*DiscardedValue*/ false);
1788 if (UnhandledException.isInvalid())
1789 return false;
1790
1791 // Since the body of the coroutine will be wrapped in try-catch, it will
1792 // be incompatible with SEH __try if present in a function.
1793 if (!S.getLangOpts().Borland && Fn.FirstSEHTryLoc.isValid()) {
1794 S.Diag(Loc: Fn.FirstSEHTryLoc, DiagID: diag::err_seh_in_a_coroutine_with_cxx_exceptions);
1795 S.Diag(Loc: Fn.FirstCoroutineStmtLoc, DiagID: diag::note_declared_coroutine_here)
1796 << Fn.getFirstCoroutineStmtKeyword();
1797 return false;
1798 }
1799
1800 this->OnException = UnhandledException.get();
1801 return true;
1802}
1803
1804bool CoroutineStmtBuilder::makeReturnObject() {
1805 // [dcl.fct.def.coroutine]p7
1806 // The expression promise.get_return_object() is used to initialize the
1807 // returned reference or prvalue result object of a call to a coroutine.
1808 ExprResult ReturnObject =
1809 buildPromiseCall(S, Promise: Fn.CoroutinePromise, Loc, Name: "get_return_object", Args: {});
1810 if (ReturnObject.isInvalid())
1811 return false;
1812
1813 this->ReturnValue = ReturnObject.get();
1814 return true;
1815}
1816
1817static void noteMemberDeclaredHere(Sema &S, Expr *E, FunctionScopeInfo &Fn) {
1818 if (auto *MbrRef = dyn_cast<CXXMemberCallExpr>(Val: E)) {
1819 auto *MethodDecl = MbrRef->getMethodDecl();
1820 S.Diag(Loc: MethodDecl->getLocation(), DiagID: diag::note_member_declared_here)
1821 << MethodDecl;
1822 }
1823 S.Diag(Loc: Fn.FirstCoroutineStmtLoc, DiagID: diag::note_declared_coroutine_here)
1824 << Fn.getFirstCoroutineStmtKeyword();
1825}
1826
1827bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() {
1828 assert(!IsPromiseDependentType &&
1829 "cannot make statement while the promise type is dependent");
1830 assert(this->ReturnValue && "ReturnValue must be already formed");
1831
1832 QualType const GroType = this->ReturnValue->getType();
1833 assert(!GroType->isDependentType() &&
1834 "get_return_object type must no longer be dependent");
1835
1836 QualType const FnRetType = FD.getReturnType();
1837 assert(!FnRetType->isDependentType() &&
1838 "get_return_object type must no longer be dependent");
1839
1840 // The call to get_­return_­object is sequenced before the call to
1841 // initial_­suspend and is invoked at most once, but there are caveats
1842 // regarding on whether the prvalue result object may be initialized
1843 // directly/eager or delayed, depending on the types involved.
1844 //
1845 // More info at https://github.com/cplusplus/papers/issues/1414
1846 bool GroMatchesRetType = S.getASTContext().hasSameType(T1: GroType, T2: FnRetType);
1847
1848 if (FnRetType->isVoidType()) {
1849 ExprResult Res =
1850 S.ActOnFinishFullExpr(Expr: this->ReturnValue, CC: Loc, /*DiscardedValue*/ false);
1851 if (Res.isInvalid())
1852 return false;
1853
1854 if (!GroMatchesRetType)
1855 this->ResultDecl = Res.get();
1856 return true;
1857 }
1858
1859 if (GroType->isVoidType()) {
1860 // Trigger a nice error message.
1861 InitializedEntity Entity =
1862 InitializedEntity::InitializeResult(ReturnLoc: Loc, Type: FnRetType);
1863 S.PerformCopyInitialization(Entity, EqualLoc: SourceLocation(), Init: ReturnValue);
1864 noteMemberDeclaredHere(S, E: ReturnValue, Fn);
1865 return false;
1866 }
1867
1868 StmtResult ReturnStmt;
1869 clang::VarDecl *GroDecl = nullptr;
1870 if (GroMatchesRetType) {
1871 ReturnStmt = S.BuildReturnStmt(ReturnLoc: Loc, RetValExp: ReturnValue);
1872 } else {
1873 GroDecl = VarDecl::Create(
1874 C&: S.Context, DC: &FD, StartLoc: FD.getLocation(), IdLoc: FD.getLocation(),
1875 Id: &S.PP.getIdentifierTable().get(Name: "__coro_gro"), T: GroType,
1876 TInfo: S.Context.getTrivialTypeSourceInfo(T: GroType, Loc), S: SC_None);
1877 GroDecl->setImplicit();
1878
1879 S.CheckVariableDeclarationType(NewVD: GroDecl);
1880 if (GroDecl->isInvalidDecl())
1881 return false;
1882
1883 InitializedEntity Entity = InitializedEntity::InitializeVariable(Var: GroDecl);
1884 ExprResult Res =
1885 S.PerformCopyInitialization(Entity, EqualLoc: SourceLocation(), Init: ReturnValue);
1886 if (Res.isInvalid())
1887 return false;
1888
1889 Res = S.ActOnFinishFullExpr(Expr: Res.get(), /*DiscardedValue*/ false);
1890 if (Res.isInvalid())
1891 return false;
1892
1893 S.AddInitializerToDecl(dcl: GroDecl, init: Res.get(),
1894 /*DirectInit=*/false);
1895
1896 S.FinalizeDeclaration(D: GroDecl);
1897
1898 // Form a declaration statement for the return declaration, so that AST
1899 // visitors can more easily find it.
1900 StmtResult GroDeclStmt =
1901 S.ActOnDeclStmt(Decl: S.ConvertDeclToDeclGroup(Ptr: GroDecl), StartLoc: Loc, EndLoc: Loc);
1902 if (GroDeclStmt.isInvalid())
1903 return false;
1904
1905 this->ResultDecl = GroDeclStmt.get();
1906
1907 ExprResult declRef = S.BuildDeclRefExpr(D: GroDecl, Ty: GroType, VK: VK_LValue, Loc);
1908 if (declRef.isInvalid())
1909 return false;
1910
1911 ReturnStmt = S.BuildReturnStmt(ReturnLoc: Loc, RetValExp: declRef.get());
1912 }
1913
1914 if (ReturnStmt.isInvalid()) {
1915 noteMemberDeclaredHere(S, E: ReturnValue, Fn);
1916 return false;
1917 }
1918
1919 if (!GroMatchesRetType &&
1920 cast<clang::ReturnStmt>(Val: ReturnStmt.get())->getNRVOCandidate() == GroDecl)
1921 GroDecl->setNRVOVariable(true);
1922
1923 this->ReturnStmt = ReturnStmt.get();
1924 return true;
1925}
1926
1927// Create a static_cast\<T&&>(expr).
1928static Expr *castForMoving(Sema &S, Expr *E, QualType T = QualType()) {
1929 if (T.isNull())
1930 T = E->getType();
1931 QualType TargetType = S.BuildReferenceType(
1932 T, /*SpelledAsLValue*/ LValueRef: false, Loc: SourceLocation(), Entity: DeclarationName());
1933 SourceLocation ExprLoc = E->getBeginLoc();
1934 TypeSourceInfo *TargetLoc =
1935 S.Context.getTrivialTypeSourceInfo(T: TargetType, Loc: ExprLoc);
1936
1937 return S
1938 .BuildCXXNamedCast(OpLoc: ExprLoc, Kind: tok::kw_static_cast, Ty: TargetLoc, E,
1939 AngleBrackets: SourceRange(ExprLoc, ExprLoc), Parens: E->getSourceRange())
1940 .get();
1941}
1942
1943/// Build a variable declaration for move parameter.
1944static VarDecl *buildVarDecl(Sema &S, SourceLocation Loc, QualType Type,
1945 IdentifierInfo *II) {
1946 TypeSourceInfo *TInfo = S.Context.getTrivialTypeSourceInfo(T: Type, Loc);
1947 VarDecl *Decl = VarDecl::Create(C&: S.Context, DC: S.CurContext, StartLoc: Loc, IdLoc: Loc, Id: II, T: Type,
1948 TInfo, S: SC_None);
1949 Decl->setImplicit();
1950 return Decl;
1951}
1952
1953// Build statements that move coroutine function parameters to the coroutine
1954// frame, and store them on the function scope info.
1955bool Sema::buildCoroutineParameterMoves(SourceLocation Loc) {
1956 assert(isa<FunctionDecl>(CurContext) && "not in a function scope");
1957 auto *FD = cast<FunctionDecl>(Val: CurContext);
1958
1959 auto *ScopeInfo = getCurFunction();
1960 if (!ScopeInfo->CoroutineParameterMoves.empty())
1961 return false;
1962
1963 // [dcl.fct.def.coroutine]p13
1964 // When a coroutine is invoked, after initializing its parameters
1965 // ([expr.call]), a copy is created for each coroutine parameter. For a
1966 // parameter of type cv T, the copy is a variable of type cv T with
1967 // automatic storage duration that is direct-initialized from an xvalue of
1968 // type T referring to the parameter.
1969 for (auto *PD : FD->parameters()) {
1970 if (PD->getType()->isDependentType())
1971 continue;
1972
1973 // Preserve the referenced state for unused parameter diagnostics.
1974 bool DeclReferenced = PD->isReferenced();
1975
1976 ExprResult PDRefExpr =
1977 BuildDeclRefExpr(D: PD, Ty: PD->getType().getNonReferenceType(),
1978 VK: ExprValueKind::VK_LValue, Loc); // FIXME: scope?
1979
1980 PD->setReferenced(DeclReferenced);
1981
1982 if (PDRefExpr.isInvalid())
1983 return false;
1984
1985 Expr *CExpr = nullptr;
1986 if (PD->getType()->getAsCXXRecordDecl() ||
1987 PD->getType()->isRValueReferenceType())
1988 CExpr = castForMoving(S&: *this, E: PDRefExpr.get());
1989 else
1990 CExpr = PDRefExpr.get();
1991 // [dcl.fct.def.coroutine]p13
1992 // The initialization and destruction of each parameter copy occurs in the
1993 // context of the called coroutine.
1994 auto *D = buildVarDecl(S&: *this, Loc, Type: PD->getType(), II: PD->getIdentifier());
1995 AddInitializerToDecl(dcl: D, init: CExpr, /*DirectInit=*/true);
1996
1997 // Convert decl to a statement.
1998 StmtResult Stmt = ActOnDeclStmt(Decl: ConvertDeclToDeclGroup(Ptr: D), StartLoc: Loc, EndLoc: Loc);
1999 if (Stmt.isInvalid())
2000 return false;
2001
2002 ScopeInfo->CoroutineParameterMoves.insert(KV: std::make_pair(x&: PD, y: Stmt.get()));
2003 }
2004 return true;
2005}
2006
2007StmtResult Sema::BuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
2008 CoroutineBodyStmt *Res = CoroutineBodyStmt::Create(C: Context, Args);
2009 if (!Res)
2010 return StmtError();
2011 return Res;
2012}
2013
2014ClassTemplateDecl *Sema::lookupCoroutineTraits(SourceLocation KwLoc,
2015 SourceLocation FuncLoc) {
2016 if (StdCoroutineTraitsCache)
2017 return StdCoroutineTraitsCache;
2018
2019 IdentifierInfo const &TraitIdent =
2020 PP.getIdentifierTable().get(Name: "coroutine_traits");
2021
2022 NamespaceDecl *StdSpace = getStdNamespace();
2023 LookupResult Result(*this, &TraitIdent, FuncLoc, LookupOrdinaryName);
2024 bool Found = StdSpace && LookupQualifiedName(R&: Result, LookupCtx: StdSpace);
2025
2026 if (!Found) {
2027 // The goggles, we found nothing!
2028 Diag(Loc: KwLoc, DiagID: diag::err_implied_coroutine_type_not_found)
2029 << "std::coroutine_traits";
2030 return nullptr;
2031 }
2032
2033 // coroutine_traits is required to be a class template.
2034 StdCoroutineTraitsCache = Result.getAsSingle<ClassTemplateDecl>();
2035 if (!StdCoroutineTraitsCache) {
2036 Result.suppressDiagnostics();
2037 NamedDecl *Found = *Result.begin();
2038 Diag(Loc: Found->getLocation(), DiagID: diag::err_malformed_std_coroutine_traits);
2039 return nullptr;
2040 }
2041
2042 return StdCoroutineTraitsCache;
2043}
2044