<div dir="ltr">Ah I'm sorry, I've reproduced this with a `-triple armeb-none-eabi` argument. Douglas, do you mind if I fix forward?<div><br></div><div>- Brian</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Feb 16, 2018 at 8:55 AM, Brian Gesiak <span dir="ltr"><<a href="mailto:modocache@gmail.com" target="_blank">modocache@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Douglas, thanks for letting me know. I'm looking into this now.<div><br></div><div>At first these error messages made me think <a href="https://reviews.llvm.org/rL325291" target="_blank">https://reviews.llvm.org/<wbr>rL325291</a> was merged in, but not <a href="https://reviews.llvm.org/rL325288" target="_blank">https://reviews.llvm.org/<wbr>rL325288</a>. But I guess that's not possible.</div><div><br></div><div>Is there a way to find out the host triple used on this buildbot? Off the top of my head I can't think of any reasons why frontend diagnostics would be output for this platform but not others.</div><div><br></div><div>Thanks for your patience!</div><div><br></div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Feb 16, 2018 at 5:31 AM,  <span dir="ltr"><<a href="mailto:douglas.yung@sony.com" target="_blank">douglas.yung@sony.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Brian,<br>
<br>
Your change is causing a test failure on the clang-cmake-armv7-a15 bot in the test Clang::SemaCXX/coroutines.cpp.<br>
<br>
<a href="http://lab.llvm.org:8011/builders/clang-cmake-armv7-a15/builds/15742" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/build<wbr>ers/clang-cmake-armv7-a15/<wbr>builds/15742</a><br>
<br>
error: 'error' diagnostics seen but not expected:<br>
  File /home/buildslave/buildslave/cl<wbr>ang-cmake-armv7-a15/llvm/tools<wbr>/clang/test/SemaCXX/coroutines<wbr>.cpp Line 790: 'operator new' takes type size_t ('unsigned int') as first parameter<br>
  File /home/buildslave/buildslave/cl<wbr>ang-cmake-armv7-a15/llvm/tools<wbr>/clang/test/SemaCXX/coroutines<wbr>.cpp Line 806: 'operator new' takes type size_t ('unsigned int') as first parameter<br>
  File /home/buildslave/buildslave/cl<wbr>ang-cmake-armv7-a15/llvm/tools<wbr>/clang/test/SemaCXX/coroutines<wbr>.cpp Line 816: 'operator new' takes type size_t ('unsigned int') as first parameter<br>
  File /home/buildslave/buildslave/cl<wbr>ang-cmake-armv7-a15/llvm/tools<wbr>/clang/test/SemaCXX/coroutines<wbr>.cpp Line 839: 'operator new' takes type size_t ('unsigned int') as first parameter<br>
  File /home/buildslave/buildslave/cl<wbr>ang-cmake-armv7-a15/llvm/tools<wbr>/clang/test/SemaCXX/coroutines<wbr>.cpp Line 856: 'operator new' takes type size_t ('unsigned int') as first parameter<br>
  File /home/buildslave/buildslave/cl<wbr>ang-cmake-armv7-a15/llvm/tools<wbr>/clang/test/SemaCXX/coroutines<wbr>.cpp Line 872: 'operator new' takes type size_t ('unsigned int') as first parameter<br>
error: 'note' diagnostics expected but not seen:<br>
  File /home/buildslave/buildslave/cl<wbr>ang-cmake-armv7-a15/llvm/tools<wbr>/clang/test/SemaCXX/coroutines<wbr>.cpp Line 816 (directive at /home/buildslave/buildslave/cl<wbr>ang-cmake-armv7-a15/llvm/tools<wbr>/clang/test/SemaCXX/coroutines<wbr>.cpp:815): candidate function not viable: requires 2 arguments, but 1 was provided<br>
  File /home/buildslave/buildslave/cl<wbr>ang-cmake-armv7-a15/llvm/tools<wbr>/clang/test/SemaCXX/coroutines<wbr>.cpp Line 839 (directive at /home/buildslave/buildslave/cl<wbr>ang-cmake-armv7-a15/llvm/tools<wbr>/clang/test/SemaCXX/coroutines<wbr>.cpp:838): candidate function not viable: requires 4 arguments, but 1 was provided<br>
8 errors generated.<br>
<br>
Can you take a look?<br>
<br>
Douglas Yung<br>
<div><div class="m_-7360792217038773832h5"><br>
> -----Original Message-----<br>
> From: cfe-commits [mailto:<a href="mailto:cfe-commits-bounces@lists.llvm.org" target="_blank">cfe-commits-bounces@li<wbr>sts.llvm.org</a>] On Behalf Of<br>
> Brian Gesiak via cfe-commits<br>
> Sent: Thursday, February 15, 2018 12:37<br>
> To: <a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
> Subject: r325291 - [Coroutines] Use allocator overload when available<br>
><br>
> Author: modocache<br>
> Date: Thu Feb 15 12:37:22 2018<br>
> New Revision: 325291<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=325291&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=325291&view=rev</a><br>
> Log:<br>
> [Coroutines] Use allocator overload when available<br>
><br>
> Summary:<br>
> Depends on <a href="https://reviews.llvm.org/D42605" rel="noreferrer" target="_blank">https://reviews.llvm.org/D4260<wbr>5</a>.<br>
><br>
> An implementation of the behavior described in `[dcl.fct.def.coroutine]/7`:<br>
> when a promise type overloads `operator new` using a "placement new"<br>
> that takes the same argument types as the coroutine function, that overload is<br>
> used when allocating the coroutine frame.<br>
><br>
> Simply passing references to the coroutine function parameters directly to<br>
> `operator new` results in invariant violations in LLVM's coroutine splitting<br>
> pass, so this implementation modifies Clang codegen to produce allocator-<br>
> specific alloc/store/loads for each parameter being forwarded to the<br>
> allocator.<br>
><br>
> Test Plan: `check-clang`<br>
><br>
> Reviewers: rsmith, GorNishanov, eric_niebler<br>
><br>
> Reviewed By: GorNishanov<br>
><br>
> Subscribers: lewissbaker, EricWF, cfe-commits<br>
><br>
> Differential Revision: <a href="https://reviews.llvm.org/D42606" rel="noreferrer" target="_blank">https://reviews.llvm.org/D4260<wbr>6</a><br>
><br>
> Modified:<br>
>     cfe/trunk/lib/Sema/SemaCorout<wbr>ine.cpp<br>
>     cfe/trunk/test/CodeGenCorouti<wbr>nes/coro-alloc.cpp<br>
>     cfe/trunk/test/CodeGenCorouti<wbr>nes/coro-gro-nrvo.cpp<br>
>     cfe/trunk/test/CodeGenCorouti<wbr>nes/coro-params.cpp<br>
>     cfe/trunk/test/SemaCXX/corout<wbr>ines.cpp<br>
><br>
> Modified: cfe/trunk/lib/Sema/SemaCorouti<wbr>ne.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/cfe/trunk/lib/Sema/Sem<wbr>aCoroutine.cpp?rev=325291&r1=<wbr>325290&r2=325291&vi<br>
> ew=diff<br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/lib/Sema/SemaCorouti<wbr>ne.cpp (original)<br>
> +++ cfe/trunk/lib/Sema/SemaCorouti<wbr>ne.cpp Thu Feb 15 12:37:22 2018<br>
> @@ -12,6 +12,7 @@<br>
>  //===-------------------------<wbr>------------------------------<wbr>---------------<br>
> ===//<br>
><br>
>  #include "CoroutineStmtBuilder.h"<br>
> +#include "clang/AST/ASTLambda.h"<br>
>  #include "clang/AST/Decl.h"<br>
>  #include "clang/AST/ExprCXX.h"<br>
>  #include "clang/AST/StmtCXX.h"<br>
> @@ -506,24 +507,15 @@ VarDecl *Sema::buildCoroutinePromise(S<wbr>ou<br>
><br>
>      auto RefExpr = ExprEmpty();<br>
>      auto Move = Moves.find(PD);<br>
> -    if (Move != Moves.end()) {<br>
> -      // If a reference to the function parameter exists in the coroutine<br>
> -      // frame, use that reference.<br>
> -      auto *MoveDecl =<br>
> -          cast<VarDecl>(cast<DeclStmt>(M<wbr>ove->second)->getSingleDecl())<wbr>;<br>
> -      RefExpr = BuildDeclRefExpr(MoveDecl, MoveDecl->getType(),<br>
> -                                 ExprValueKind::VK_LValue, FD-<br>
> >getLocation());<br>
> -    } else {<br>
> -      // If the function parameter doesn't exist in the coroutine frame, it<br>
> -      // must be a scalar value. Use it directly.<br>
> -      assert(!PD->getType()->getAsCX<wbr>XRecordDecl() &&<br>
> -             "Non-scalar types should have been moved and inserted into the "<br>
> -             "parameter moves map");<br>
> -      RefExpr =<br>
> -          BuildDeclRefExpr(PD, PD->getOriginalType().getNonRe<wbr>ferenceType(),<br>
> -                           ExprValueKind::VK_LValue, FD->getLocation());<br>
> -    }<br>
> -<br>
> +    assert(Move != Moves.end() &&<br>
> +           "Coroutine function parameter not inserted into move map");<br>
> +    // If a reference to the function parameter exists in the coroutine<br>
> +    // frame, use that reference.<br>
> +    auto *MoveDecl =<br>
> +        cast<VarDecl>(cast<DeclStmt>(M<wbr>ove->second)->getSingleDecl())<wbr>;<br>
> +    RefExpr =<br>
> +        BuildDeclRefExpr(MoveDecl, MoveDecl->getType().getNonRefe<wbr>renceType(),<br>
> +                         ExprValueKind::VK_LValue, FD->getLocation());<br>
>      if (RefExpr.isInvalid())<br>
>        return nullptr;<br>
>      CtorArgExprs.push_back(RefExpr<wbr>.get());<br>
> @@ -1050,7 +1042,12 @@ bool CoroutineStmtBuilder::makeNewA<wbr>ndDel<br>
><br>
>    const bool RequiresNoThrowAlloc = ReturnStmtOnAllocFailure != nullptr;<br>
><br>
> -  // FIXME: Add support for stateful allocators.<br>
> +  // [dcl.fct.def.coroutine]/7<br>
> +  // Lookup allocation functions using a parameter list composed of the<br>
> + // requested size of the coroutine state being allocated, followed by<br>
> + // the coroutine function's arguments. If a matching allocation<br>
</div></div>> + function  // exists, use it. Otherwise, use an allocation function<br>
> + that just takes  // the requested size.<br>
<span>><br>
>    FunctionDecl *OperatorNew = nullptr;<br>
>    FunctionDecl *OperatorDelete = nullptr; @@ -1058,10 +1055,62 @@ bool<br>
> CoroutineStmtBuilder::makeNewA<wbr>ndDel<br>
>    bool PassAlignment = false;<br>
>    SmallVector<Expr *, 1> PlacementArgs;<br>
><br>
> +  // [dcl.fct.def.coroutine]/7<br>
> +  // "The allocation function’s name is looked up in the scope of P.<br>
> +  // [...] If the lookup finds an allocation function in the scope of<br>
</span>> + P,  // overload resolution is performed on a function call created by<br>
> + assembling  // an argument list. The first argument is the amount of<br>
> + space requested,  // and has type std::size_t. The lvalues p1 ... pn<br>
> + are the succeeding  // arguments."<br>
<span>> +  //<br>
> +  // ...where "p1 ... pn" are defined earlier as:<br>
> +  //<br>
> +  // [dcl.fct.def.coroutine]/3<br>
> +  // "For a coroutine f that is a non-static member function, let P1<br>
</span>> + denote the  // type of the implicit object parameter (13.3.1) and P2<br>
> + ... Pn be the types  // of the function parameters; otherwise let P1<br>
> + ... Pn be the types of the  // function parameters. Let p1 ... pn be lvalues<br>
<div><div class="m_-7360792217038773832h5">> denoting those objects."<br>
> +  if (auto *MD = dyn_cast<CXXMethodDecl>(&FD)) {<br>
> +    if (MD->isInstance() && !isLambdaCallOperator(MD)) {<br>
> +      ExprResult ThisExpr = S.ActOnCXXThis(Loc);<br>
> +      if (ThisExpr.isInvalid())<br>
> +        return false;<br>
> +      ThisExpr = S.CreateBuiltinUnaryOp(Loc, UO_Deref, ThisExpr.get());<br>
> +      if (ThisExpr.isInvalid())<br>
> +        return false;<br>
> +      PlacementArgs.push_back(ThisEx<wbr>pr.get());<br>
> +    }<br>
> +  }<br>
> +  for (auto *PD : FD.parameters()) {<br>
> +    if (PD->getType()->isDependentTyp<wbr>e())<br>
> +      continue;<br>
> +<br>
> +    // Build a reference to the parameter.<br>
> +    auto PDLoc = PD->getLocation();<br>
> +    ExprResult PDRefExpr =<br>
> +        S.BuildDeclRefExpr(PD, PD->getOriginalType().getNonRe<wbr>ferenceType(),<br>
> +                           ExprValueKind::VK_LValue, PDLoc);<br>
> +    if (PDRefExpr.isInvalid())<br>
> +      return false;<br>
> +<br>
> +    PlacementArgs.push_back(PDRefE<wbr>xpr.get());<br>
> +  }<br>
>    S.FindAllocationFunctions(Loc, SourceRange(),<br>
>                              /*UseGlobal*/ false, PromiseType,<br>
>                              /*isArray*/ false, PassAlignment, PlacementArgs,<br>
> -                            OperatorNew, UnusedResult);<br>
> +                            OperatorNew, UnusedResult, /*Diagnose*/<br>
</div></div>> + false);<br>
<span>> +<br>
> +  // [dcl.fct.def.coroutine]/7<br>
> +  // "If no matching function is found, overload resolution is<br>
</span>> + performed again  // on a function call created by passing just the<br>
> + amount of space required as  // an argument of type std::size_t."<br>
<span>> +  if (!OperatorNew && !PlacementArgs.empty()) {<br>
> +    PlacementArgs.clear();<br>
> +    S.FindAllocationFunctions(Loc, SourceRange(),<br>
> +                              /*UseGlobal*/ false, PromiseType,<br>
> +                              /*isArray*/ false, PassAlignment,<br>
> +                              PlacementArgs, OperatorNew,<br>
</span>> + UnusedResult);  }<br>
<div><div class="m_-7360792217038773832h5">><br>
>    bool IsGlobalOverload =<br>
>        OperatorNew && !isa<CXXRecordDecl>(OperatorNe<wbr>w->getDeclContext());<br>
> @@ -1080,7 +1129,8 @@ bool CoroutineStmtBuilder::makeNewA<wbr>ndDel<br>
>                                OperatorNew, UnusedResult);<br>
>    }<br>
><br>
> -  assert(OperatorNew && "expected definition of operator new to be found");<br>
> +  if (!OperatorNew)<br>
> +    return false;<br>
><br>
>    if (RequiresNoThrowAlloc) {<br>
>      const auto *FT = OperatorNew->getType()->getAs<<wbr>FunctionProtoType>();<br>
> @@ -1386,25 +1436,28 @@ bool Sema::buildCoroutineParameterM<wbr>oves(<br>
>      if (PD->getType()->isDependentTyp<wbr>e())<br>
>        continue;<br>
><br>
> -    // No need to copy scalars, LLVM will take care of them.<br>
> -    if (PD->getType()->getAsCXXRecord<wbr>Decl()) {<br>
> -      ExprResult PDRefExpr = BuildDeclRefExpr(<br>
> -          PD, PD->getType(), ExprValueKind::VK_LValue, Loc); // FIXME: scope?<br>
> -      if (PDRefExpr.isInvalid())<br>
> -        return false;<br>
> +    ExprResult PDRefExpr =<br>
> +        BuildDeclRefExpr(PD, PD->getType().getNonReferenceT<wbr>ype(),<br>
> +                         ExprValueKind::VK_LValue, Loc); // FIXME: scope?<br>
> +    if (PDRefExpr.isInvalid())<br>
> +      return false;<br>
><br>
> -      Expr *CExpr = castForMoving(*this, PDRefExpr.get());<br>
> +    Expr *CExpr = nullptr;<br>
> +    if (PD->getType()->getAsCXXRecord<wbr>Decl() ||<br>
> +        PD->getType()->isRValueReferen<wbr>ceType())<br>
> +      CExpr = castForMoving(*this, PDRefExpr.get());<br>
> +    else<br>
> +      CExpr = PDRefExpr.get();<br>
><br>
> -      auto D = buildVarDecl(*this, Loc, PD->getType(), PD->getIdentifier());<br>
> -      AddInitializerToDecl(D, CExpr, /*DirectInit=*/true);<br>
> +    auto D = buildVarDecl(*this, Loc, PD->getType(), PD->getIdentifier());<br>
> +    AddInitializerToDecl(D, CExpr, /*DirectInit=*/true);<br>
><br>
> -      // Convert decl to a statement.<br>
> -      StmtResult Stmt = ActOnDeclStmt(ConvertDeclToDec<wbr>lGroup(D), Loc, Loc);<br>
> -      if (Stmt.isInvalid())<br>
> -        return false;<br>
> +    // Convert decl to a statement.<br>
> +    StmtResult Stmt = ActOnDeclStmt(ConvertDeclToDec<wbr>lGroup(D), Loc, Loc);<br>
> +    if (Stmt.isInvalid())<br>
> +      return false;<br>
><br>
> -      ScopeInfo->CoroutineParameterM<wbr>oves.insert(std::make_pair(PD,<br>
> Stmt.get()));<br>
> -    }<br>
> +    ScopeInfo->CoroutineParameterM<wbr>oves.insert(std::make_pair(PD,<br>
</div></div>> + Stmt.get()));<br>
<span>>    }<br>
>    return true;<br>
>  }<br>
><br>
> Modified: cfe/trunk/test/CodeGenCoroutin<wbr>es/coro-alloc.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/cfe/trunk/test/CodeGen<wbr>Coroutines/coro-<br>
> alloc.cpp?rev=325291&r1=325290<wbr>&r2=325291&view=diff<br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/CodeGenCoroutin<wbr>es/coro-alloc.cpp (original)<br>
> +++ cfe/trunk/test/CodeGenCoroutin<wbr>es/coro-alloc.cpp Thu Feb 15 12:37:22<br>
</span>> +++ 2018<br>
<span>> @@ -106,6 +106,34 @@ extern "C" void f1(promise_new_tag ) {<br>
>    co_return;<br>
>  }<br>
><br>
> +struct promise_matching_placement_new<wbr>_tag {};<br>
> +<br>
> +template<><br>
> +struct std::experimental::coroutine_t<wbr>raits<void,<br>
</span>> +promise_matching_placement_ne<wbr>w_tag, int, float, double> {<br>
<span>> +  struct promise_type {<br>
> +    void *operator new(unsigned long, promise_matching_placement_new<wbr>_tag,<br>
> +                       int, float, double);<br>
> +    void get_return_object() {}<br>
> +    suspend_always initial_suspend() { return {}; }<br>
> +    suspend_always final_suspend() { return {}; }<br>
> +    void return_void() {}<br>
> +  };<br>
> +};<br>
> +<br>
> +// CHECK-LABEL: f1a(<br>
> +extern "C" void f1a(promise_matching_placement<wbr>_new_tag, int x, float y<br>
</span>> +, double z) {<br>
<span>> +  // CHECK: store i32 %x, i32* %x.addr, align 4<br>
> +  // CHECK: store float %y, float* %y.addr, align 4<br>
> +  // CHECK: store double %z, double* %z.addr, align 8<br>
> +  // CHECK: %[[ID:.+]] = call token @<a href="http://llvm.coro.id" rel="noreferrer" target="_blank">llvm.coro.id</a>(i32 16<br>
> +  // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()<br>
> +  // CHECK: %[[INT:.+]] = load i32, i32* %x.addr, align 4<br>
> +  // CHECK: %[[FLOAT:.+]] = load float, float* %y.addr, align 4<br>
> +  // CHECK: %[[DOUBLE:.+]] = load double, double* %z.addr, align 8<br>
> +  // CHECK: call i8*<br>
</span>> +@_ZNSt12experimental16corouti<wbr>ne_traitsIJv34promise_<wbr>matching_placement_n<br>
> +ew_tagifdEE12promise_typenwEm<wbr>S1_ifd(i64 %[[SIZE]], i32 %[[INT]], float<br>
> +%[[FLOAT]], double %[[DOUBLE]])<br>
<span>> +  co_return;<br>
> +}<br>
> +<br>
>  struct promise_delete_tag {};<br>
><br>
>  template<><br>
><br>
> Modified: cfe/trunk/test/CodeGenCoroutin<wbr>es/coro-gro-nrvo.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/cfe/trunk/test/CodeGen<wbr>Coroutines/coro-gro-<br>
> nrvo.cpp?rev=325291&r1=325290&<wbr>r2=325291&view=diff<br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/CodeGenCoroutin<wbr>es/coro-gro-nrvo.cpp (original)<br>
> +++ cfe/trunk/test/CodeGenCoroutin<wbr>es/coro-gro-nrvo.cpp Thu Feb 15<br>
</span>> +++ 12:37:22 2018<br>
<span>> @@ -41,7 +41,7 @@ coro f(int) {<br>
><br>
>  // CHECK: {{.*}}[[CoroInit]]:<br>
>  // CHECK: store i1 false, i1* %gro.active -// CHECK-NEXT: call void<br>
> @{{.*get_return_objectEv}}(%st<wbr>ruct.coro* sret %agg.result<br>
> +// CHECK: call void @{{.*get_return_objectEv}}(%st<wbr>ruct.coro* sret<br>
</span>> +%agg.result<br>
<span>>  // CHECK-NEXT: store i1 true, i1* %gro.active<br>
>    co_return;<br>
>  }<br>
> @@ -78,7 +78,7 @@ struct coro_two {<br>
><br>
>  // CHECK: {{.*}}[[InitOnSuccess]]:<br>
>  // CHECK: store i1 false, i1* %gro.active -// CHECK-NEXT: call void<br>
> @{{.*get_return_objectEv}}(%st<wbr>ruct.coro_two* sret %agg.result<br>
> +// CHECK: call void @{{.*get_return_objectEv}}(%st<wbr>ruct.coro_two* sret<br>
</span>> +%agg.result<br>
<span>>  // CHECK-NEXT: store i1 true, i1* %gro.active<br>
><br>
>  // CHECK: [[RetLabel]]:<br>
><br>
> Modified: cfe/trunk/test/CodeGenCoroutin<wbr>es/coro-params.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/cfe/trunk/test/CodeGen<wbr>Coroutines/coro-<br>
> params.cpp?rev=325291&r1=32529<wbr>0&r2=325291&view=diff<br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/CodeGenCoroutin<wbr>es/coro-params.cpp (original)<br>
> +++ cfe/trunk/test/CodeGenCoroutin<wbr>es/coro-params.cpp Thu Feb 15 12:37:22<br>
</span>> +++ 2018<br>
<span>> @@ -69,12 +69,12 @@ void f(int val, MoveOnly moParam, MoveAn<br>
>    // CHECK: store i32 %val, i32* %[[ValAddr:.+]]<br>
><br>
>    // CHECK: call i8* @llvm.coro.begin(<br>
> -  // CHECK-NEXT: call void @_ZN8MoveOnlyC1EOS_(%struct.Mo<wbr>veOnly* %[[MoCopy]],<br>
> %struct.MoveOnly* dereferenceable(4) %[[MoParam]])<br>
> +  // CHECK: call void @_ZN8MoveOnlyC1EOS_(%struct.Mo<wbr>veOnly*<br>
</span>> + %[[MoCopy]], %struct.MoveOnly* dereferenceable(4) %[[MoParam]])<br>
<span>>    // CHECK-NEXT: call void @_ZN11MoveAndCopyC1EOS_(%struc<wbr>t.MoveAndCopy*<br>
> %[[McCopy]], %struct.MoveAndCopy* dereferenceable(4) %[[McParam]]) #<br>
>    // CHECK-NEXT: invoke void<br>
> @_ZNSt12experimental16coroutin<wbr>e_traitsIJvi8MoveOnly11MoveAnd<wbr>CopyEE12promise_ty<br>
> peC1Ev(<br>
><br>
>    // CHECK: call void @_ZN14suspend_always12await_re<wbr>sumeEv(<br>
> -  // CHECK: %[[IntParam:.+]] = load i32, i32* %val.addr<br>
> +  // CHECK: %[[IntParam:.+]] = load i32, i32* %val1<br>
>    // CHECK: %[[MoGep:.+]] = getelementptr inbounds %struct.MoveOnly,<br>
> %struct.MoveOnly* %[[MoCopy]], i32 0, i32 0<br>
>    // CHECK: %[[MoVal:.+]] = load i32, i32* %[[MoGep]]<br>
>    // CHECK: %[[McGep:.+]] =  getelementptr inbounds %struct.MoveAndCopy,<br>
> %struct.MoveAndCopy* %[[McCopy]], i32 0, i32 0 @@ -150,9 +150,9 @@ struct<br>
> std::experimental::coroutine_t<wbr>rai<br>
><br>
>  // CHECK-LABEL: void<br>
> @_Z38coroutine_matching_promis<wbr>e_constructor28promise_matchin<wbr>g_constructorifd(i<br>
> 32, float, double)  void<br>
> coroutine_matching_promise_con<wbr>structor(promise_matching_cons<wbr>tructor, int,<br>
> float, double) {<br>
> -  // CHECK: %[[INT:.+]] = load i32, i32* %.addr, align 4<br>
> -  // CHECK: %[[FLOAT:.+]] = load float, float* %.addr1, align 4<br>
> -  // CHECK: %[[DOUBLE:.+]] = load double, double* %.addr2, align 8<br>
</span>> +  // CHECK: %[[INT:.+]] = load i32, i32* %5, align 4  // CHECK:<br>
> + %[[FLOAT:.+]] = load float, float* %6, align 4  // CHECK:<br>
> + %[[DOUBLE:.+]] = load double, double* %7, align 8<br>
<span>>    // CHECK: invoke void<br>
> @_ZNSt12experimental16coroutin<wbr>e_traitsIJv28promise_matching_<wbr>constructorifdEE12<br>
> promise_typeC1ES1_ifd(%"struct<wbr>.std::experimental::coroutine_<wbr>traits<void,<br>
> promise_matching_constructor, int, float, double>::promise_type"* %__promise,<br>
> i32 %[[INT]], float %[[FLOAT]], double %[[DOUBLE]])<br>
>    co_return;<br>
>  }<br>
><br>
> Modified: cfe/trunk/test/SemaCXX/corouti<wbr>nes.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-</a><br>
> project/cfe/trunk/test/SemaCXX<wbr>/coroutines.cpp?rev=325291&r1=<wbr>325290&r2=325291&v<br>
> iew=diff<br>
> ==============================<wbr>==============================<wbr>==================<br>
> --- cfe/trunk/test/SemaCXX/corouti<wbr>nes.cpp (original)<br>
> +++ cfe/trunk/test/SemaCXX/corouti<wbr>nes.cpp Thu Feb 15 12:37:22 2018<br>
> @@ -781,6 +781,102 @@ coro<T> dependent_uses_nothrow_new(T) {  }  template<br>
> coro<good_promise_13> dependent_uses_nothrow_new(goo<wbr>d_promise_13);<br>
><br>
> +struct good_promise_custom_new_operat<wbr>or {<br>
> +  coro<good_promise_custom_new_o<wbr>perator> get_return_object();<br>
> +  suspend_always initial_suspend();<br>
> +  suspend_always final_suspend();<br>
> +  void return_void();<br>
> +  void unhandled_exception();<br>
> +  void *operator new(unsigned long, double, float, int); };<br>
> +<br>
</span><span>> +coro<good_promise_custom_new_<wbr>operator><br>
> +good_coroutine_calls_custom_n<wbr>ew_operator(double, float, int) {<br>
> +  co_return;<br>
> +}<br>
> +<br>
> +struct coroutine_nonstatic_member_str<wbr>uct;<br>
> +<br>
> +struct good_promise_nonstatic_member_<wbr>custom_new_operator {<br>
> +  coro<good_promise_nonstatic_me<wbr>mber_custom_new_operator><br>
</span>> +get_return_object();<br>
<span>> +  suspend_always initial_suspend();<br>
> +  suspend_always final_suspend();<br>
> +  void return_void();<br>
> +  void unhandled_exception();<br>
> +  void *operator new(unsigned long, coroutine_nonstatic_member_str<wbr>uct<br>
</span>> +&, double); };<br>
<span>> +<br>
> +struct bad_promise_nonstatic_member_m<wbr>ismatched_custom_new_operator {<br>
> +  coro<bad_promise_nonstatic_mem<wbr>ber_mismatched_custom_new_oper<wbr>ator><br>
</span>> +get_return_object();<br>
<span>> +  suspend_always initial_suspend();<br>
> +  suspend_always final_suspend();<br>
> +  void return_void();<br>
> +  void unhandled_exception();<br>
> +  // expected-note@+1 {{candidate function not viable: requires 2<br>
</span>> +arguments, but 1 was provided}}<br>
<span>> +  void *operator new(unsigned long, double); };<br>
> +<br>
</span><span>> +struct coroutine_nonstatic_member_str<wbr>uct {<br>
> +  coro<good_promise_nonstatic_me<wbr>mber_custom_new_operator><br>
> +  good_coroutine_calls_nonstatic<wbr>_member_custom_new_operator(<wbr>double) {<br>
> +    co_return;<br>
> +  }<br>
> +<br>
> +  coro<bad_promise_nonstatic_mem<wbr>ber_mismatched_custom_new_oper<wbr>ator><br>
> +<br>
> bad_coroutine_calls_nonstatic_<wbr>member_mistmatched_custom_new_<wbr>operator(double) {<br>
> +    // expected-error@-1 {{no matching function for call to 'operator new'}}<br>
> +    co_return;<br>
> +  }<br>
> +};<br>
> +<br>
> +struct bad_promise_mismatched_custom_<wbr>new_operator {<br>
> +  coro<bad_promise_mismatched_cu<wbr>stom_new_operator> get_return_object();<br>
> +  suspend_always initial_suspend();<br>
> +  suspend_always final_suspend();<br>
> +  void return_void();<br>
> +  void unhandled_exception();<br>
> +  // expected-note@+1 {{candidate function not viable: requires 4<br>
</span>> +arguments, but 1 was provided}}<br>
<span>> +  void *operator new(unsigned long, double, float, int); };<br>
> +<br>
</span><span>> +coro<bad_promise_mismatched_c<wbr>ustom_new_operator><br>
> +bad_coroutine_calls_mismatche<wbr>d_custom_new_operator(double) {<br>
> +  // expected-error@-1 {{no matching function for call to 'operator<br>
</span>> +new'}}<br>
<span>> +  co_return;<br>
> +}<br>
> +<br>
> +struct bad_promise_throwing_custom_ne<wbr>w_operator {<br>
> +  static coro<bad_promise_throwing_cust<wbr>om_new_operator><br>
</span>> +get_return_object_on_allocati<wbr>on_failure();<br>
<span>> +  coro<bad_promise_throwing_cust<wbr>om_new_operator> get_return_object();<br>
> +  suspend_always initial_suspend();<br>
> +  suspend_always final_suspend();<br>
> +  void return_void();<br>
> +  void unhandled_exception();<br>
> +  // expected-error@+1 {{'operator new' is required to have a<br>
</span>> +non-throwing noexcept specification when the promise type declares<br>
> +'get_return_object_on_allocat<wbr>ion_failure()'}}<br>
<span>> +  void *operator new(unsigned long, double, float, int); };<br>
> +<br>
</span><span>> +coro<bad_promise_throwing_cus<wbr>tom_new_operator><br>
> +bad_coroutine_calls_throwing_<wbr>custom_new_operator(double, float, int) {<br>
> +  // expected-note@-1 {{call to 'operator new' implicitly required by<br>
</span>> +coroutine function here}}<br>
<span>> +  co_return;<br>
> +}<br>
> +<br>
> +struct good_promise_noexcept_custom_n<wbr>ew_operator {<br>
> +  static coro<good_promise_noexcept_cus<wbr>tom_new_operator><br>
</span>> +get_return_object_on_allocati<wbr>on_failure();<br>
<span class="m_-7360792217038773832im m_-7360792217038773832HOEnZb">> +  coro<good_promise_noexcept_cus<wbr>tom_new_operator> get_return_object();<br>
> +  suspend_always initial_suspend();<br>
> +  suspend_always final_suspend();<br>
> +  void return_void();<br>
> +  void unhandled_exception();<br>
> +  void *operator new(unsigned long, double, float, int) noexcept; };<br>
> +<br>
</span><div class="m_-7360792217038773832HOEnZb"><div class="m_-7360792217038773832h5">> +coro<good_promise_noexcept_cu<wbr>stom_new_operator><br>
> +good_coroutine_calls_noexcept<wbr>_custom_new_operator(double, float, int) {<br>
> +  co_return;<br>
> +}<br>
> +<br>
>  struct mismatch_gro_type_tag1 {};<br>
>  template<><br>
>  struct std::experimental::coroutine_t<wbr>raits<int, mismatch_gro_type_tag1> {<br>
><br>
><br>
> ______________________________<wbr>_________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>