EricWF updated this revision to Diff 101291. EricWF added a comment. - Diagnose non-moveable but otherwise unnamed parameters. - Have TreeTransform.h check if building the move params is successful.
https://reviews.llvm.org/D33797 Files: lib/Sema/CoroutineStmtBuilder.h lib/Sema/SemaCoroutine.cpp lib/Sema/TreeTransform.h test/CodeGenCoroutines/coro-params.cpp test/SemaCXX/coroutines.cpp
Index: test/SemaCXX/coroutines.cpp =================================================================== --- test/SemaCXX/coroutines.cpp +++ test/SemaCXX/coroutines.cpp @@ -892,3 +892,16 @@ co_await d; // OK } } + +template <int ID = 0> +struct NoCopy { + NoCopy(NoCopy const&) = delete; // expected-note 2 {{deleted here}} +}; +template <class T, class U> +void test_dependent_param(T t, U) { + // expected-error@-1 {{call to deleted constructor of 'NoCopy<0>'}} + // expected-error@-2 {{call to deleted constructor of 'NoCopy<1>'}} + ((void)t); + co_return 42; +} +template void test_dependent_param(NoCopy<0>, NoCopy<1>); // expected-note {{requested here}} Index: test/CodeGenCoroutines/coro-params.cpp =================================================================== --- test/CodeGenCoroutines/coro-params.cpp +++ test/CodeGenCoroutines/coro-params.cpp @@ -93,3 +93,34 @@ // CHECK-NEXT: call void @_ZN8MoveOnlyD1Ev(%struct.MoveOnly* %[[MoCopy]] // CHECK-NEXT: call i8* @llvm.coro.free( } + +// CHECK-LABEL: void @_Z16dependent_paramsI1A1BEvT_T0_(%struct.A* %x, %struct.B*) +template <typename T, typename U> +void dependent_params(T x, U) { + // CHECK: %[[x_copy:.+]] = alloca %struct.A + // CHECK-NOT: alloca %struct.B + + // CHECK: call i8* @llvm.coro.begin + // CHECK-NEXT: call void @_ZN1AC1EOS_(%struct.A* %[[x_copy]], %struct.A* dereferenceable(512) %x) + // CHECK-NEXT: invoke void @_ZNSt12experimental16coroutine_traitsIJv1A1BEE12promise_typeC1Ev + + co_return; +} + +struct A { + int WontFitIntoRegisterForSure[128]; + A(); + A(A&&) noexcept; + ~A(); +}; + +struct B { + int WontFitIntoRegisterForSure[128]; + B(); + B(B&&) noexcept; + ~B(); +}; + +void call_dependent_params() { + dependent_params(A{}, B{}); +} Index: lib/Sema/TreeTransform.h =================================================================== --- lib/Sema/TreeTransform.h +++ lib/Sema/TreeTransform.h @@ -6959,6 +6959,8 @@ Builder.ReturnStmt = Res.get(); } } + if (!Builder.buildParameterMoves()) + return StmtError(); return getDerived().RebuildCoroutineBodyStmt(Builder); } Index: lib/Sema/SemaCoroutine.cpp =================================================================== --- lib/Sema/SemaCoroutine.cpp +++ lib/Sema/SemaCoroutine.cpp @@ -832,6 +832,12 @@ return this->IsValid; } +bool CoroutineStmtBuilder::buildParameterMoves() { + assert(this->IsValid && "coroutine already invalid"); + assert(this->ParamMoves.empty() && "param moves already built"); + return this->IsValid = makeParamMoves(); +} + bool CoroutineStmtBuilder::makePromiseStmt() { // Form a declaration statement for the promise declaration, so that AST // visitors can more easily find it. @@ -1244,14 +1250,13 @@ .get(); } + /// \brief Build a variable declaration for move parameter. static VarDecl *buildVarDecl(Sema &S, SourceLocation Loc, QualType Type, - StringRef Name) { - DeclContext *DC = S.CurContext; - IdentifierInfo *II = &S.PP.getIdentifierTable().get(Name); + IdentifierInfo *II) { TypeSourceInfo *TInfo = S.Context.getTrivialTypeSourceInfo(Type, Loc); VarDecl *Decl = - VarDecl::Create(S.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); + VarDecl::Create(S.Context, S.CurContext, Loc, Loc, II, Type, TInfo, SC_None); Decl->setImplicit(); return Decl; } @@ -1264,21 +1269,22 @@ // No need to copy scalars, llvm will take care of them. if (Ty->getAsCXXRecordDecl()) { - if (!paramDecl->getIdentifier()) - continue; - ExprResult ParamRef = S.BuildDeclRefExpr(paramDecl, paramDecl->getType(), ExprValueKind::VK_LValue, Loc); // FIXME: scope? if (ParamRef.isInvalid()) return false; Expr *RCast = castForMoving(S, ParamRef.get()); - auto D = buildVarDecl(S, Loc, Ty, paramDecl->getIdentifier()->getName()); - + auto D = buildVarDecl(S, Loc, Ty, paramDecl->getIdentifier()); S.AddInitializerToDecl(D, RCast, /*DirectInit=*/true); + // Throw away the build declaration if the parameter is unnamed. + // We needed to check it, but we don't need to generate code for it. + if (!paramDecl->getIdentifier()) + continue; + // Convert decl to a statement. StmtResult Stmt = S.ActOnDeclStmt(S.ConvertDeclToDeclGroup(D), Loc, Loc); if (Stmt.isInvalid()) Index: lib/Sema/CoroutineStmtBuilder.h =================================================================== --- lib/Sema/CoroutineStmtBuilder.h +++ lib/Sema/CoroutineStmtBuilder.h @@ -51,6 +51,9 @@ /// name lookup. bool buildDependentStatements(); + /// \brief Build just parameter moves. To use for rebuilding in TreeTransform. + bool buildParameterMoves(); + bool isInvalid() const { return !this->IsValid; } private:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits