<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 9 January 2017 at 03:44, Faisal Vali <span dir="ltr"><<a href="mailto:faisalv@gmail.com" target="_blank">faisalv@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 class="HOEnZb"><div class="h5">On Mon, Jan 9, 2017 at 12:13 AM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br>
> On 8 January 2017 at 19:02, Faisal Vali via cfe-commits<br>
> <<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>> wrote:<br>
>><br>
>> Author: faisalv<br>
>> Date: Sun Jan  8 21:02:53 2017<br>
>> New Revision: 291416<br>
>><br>
>> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=291416&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project?rev=291416&view=rev</a><br>
>> Log:<br>
>> [cxx1z-constexpr-lambda] Implement constant evaluation of non-capturing<br>
>> lambda expressions.<br>
>><br>
>> Add a visitor for lambda expressions to RecordExprEvaluator in<br>
>> ExprConstant.cpp that creates an empty APValue of Struct type to represent<br>
>> the closure object. Additionally, add a LambdaExpr visitor to the<br>
>> TemporaryExprEvaluator that forwards constant evaluation of<br>
>> immediately-called-lambda-<wbr>expressions to the one in RecordExprEvaluator<br>
>> through VisitConstructExpr.<br>
>><br>
>> This patch supports:<br>
>> constexpr auto ID = [] (auto a) { return a; };<br>
>> static_assert(ID(3.14) == 3.14);<br>
>> static_assert([](auto a) { return a + 1; }(10) == 11);<br>
>><br>
>> Lambda captures are still not supported for constexpr lambdas.<br>
>><br>
>><br>
>> Modified:<br>
>>     cfe/trunk/lib/AST/<wbr>ExprConstant.cpp<br>
>>     cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp<br>
>>     cfe/trunk/test/SemaCXX/cxx1z-<wbr>constexpr-lambdas.cpp<br>
>><br>
>> Modified: cfe/trunk/lib/AST/<wbr>ExprConstant.cpp<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=291416&r1=291415&r2=291416&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/AST/<wbr>ExprConstant.cpp?rev=291416&<wbr>r1=291415&r2=291416&view=diff</a><br>
>><br>
>> ==============================<wbr>==============================<wbr>==================<br>
>> --- cfe/trunk/lib/AST/<wbr>ExprConstant.cpp (original)<br>
>> +++ cfe/trunk/lib/AST/<wbr>ExprConstant.cpp Sun Jan  8 21:02:53 2017<br>
>> @@ -5868,6 +5868,7 @@ namespace {<br>
>>      bool VisitCXXConstructExpr(const CXXConstructExpr *E) {<br>
>>        return VisitCXXConstructExpr(E, E->getType());<br>
>>      }<br>
>> +    bool VisitLambdaExpr(const LambdaExpr *E);<br>
>>      bool VisitCXXInheritedCtorInitExpr(<wbr>const CXXInheritedCtorInitExpr<br>
>> *E);<br>
>>      bool VisitCXXConstructExpr(const CXXConstructExpr *E, QualType T);<br>
>>      bool VisitCXXStdInitializerListExpr<wbr>(const CXXStdInitializerListExpr<br>
>> *E);<br>
>> @@ -6202,6 +6203,21 @@ bool RecordExprEvaluator::<wbr>VisitCXXStdIni<br>
>>    return true;<br>
>>  }<br>
>><br>
>> +bool RecordExprEvaluator::<wbr>VisitLambdaExpr(const LambdaExpr *E) {<br>
>> +  const CXXRecordDecl *ClosureClass = E->getLambdaClass();<br>
>> +  if (ClosureClass->isInvalidDecl()<wbr>) return false;<br>
>> +<br>
>> +  if (Info.<wbr>checkingPotentialConstantExpre<wbr>ssion()) return true;<br>
>> +  if (E->capture_size()) {<br>
>> +    Info.FFDiag(E, diag::note_unimplemented_<wbr>constexpr_lambda_feature_ast)<br>
>> +        << "can not evaluate lambda expressions with captures";<br>
>> +    return false;<br>
>> +  }<br>
>> +  // FIXME: Implement captures.<br>
>> +  Result = APValue(APValue::UninitStruct(<wbr>), /*NumBases*/0,<br>
>> /*NumFields*/0);<br>
>> +  return true;<br>
>> +}<br>
>> +<br>
>>  static bool EvaluateRecord(const Expr *E, const LValue &This,<br>
>>                             APValue &Result, EvalInfo &Info) {<br>
>>    assert(E->isRValue() && E->getType()->isRecordType() &&<br>
>> @@ -6251,6 +6267,9 @@ public:<br>
>>    bool VisitCXXStdInitializerListExpr<wbr>(const CXXStdInitializerListExpr *E)<br>
>> {<br>
>>      return VisitConstructExpr(E);<br>
>>    }<br>
>> +  bool VisitLambdaExpr(const LambdaExpr *E) {<br>
>> +    return VisitConstructExpr(E);<br>
>> +  }<br>
>>  };<br>
>>  } // end anonymous namespace<br>
>><br>
>><br>
>> Modified: cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp<br>
>> URL:<br>
>> <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=291416&r1=291415&r2=291416&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-<wbr>project/cfe/trunk/lib/Sema/<wbr>SemaExpr.cpp?rev=291416&r1=<wbr>291415&r2=291416&view=diff</a><br>
>><br>
>> ==============================<wbr>==============================<wbr>==================<br>
>> --- cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp (original)<br>
>> +++ cfe/trunk/lib/Sema/SemaExpr.<wbr>cpp Sun Jan  8 21:02:53 2017<br>
>> @@ -13097,8 +13097,10 @@ void Sema::<wbr>PopExpressionEvaluationContex<br>
>>          //   evaluate [...] a lambda-expression.<br>
>>          D = diag::err_lambda_in_constant_<wbr>expression;<br>
>>        }<br>
>> -      for (const auto *L : Rec.Lambdas)<br>
>> -        Diag(L->getLocStart(), D);<br>
>> +      // C++1z allows lambda expressions as core constant expressions.<br>
>> +      if (Rec.Context != ConstantEvaluated || !getLangOpts().CPlusPlus1z)<br>
>> +        for (const auto *L : Rec.Lambdas)<br>
>> +          Diag(L->getLocStart(), D);<br>
><br>
><br>
> We'll need an implementation of DR1607 before we're done here, since it<br>
> looks like this has removed the last restriction on lambda-expressions in<br>
> function template signatures in some contexts (array bounds, template<br>
> arguments).<br>
><br>
<br>
</div></div>Yes - I'll add those restrictions back (I suppose we'll need to check<br>
whether the nearest enclosing non-lambda context is a valid one [while<br>
still allowing them in default function arguments]) - but then we'll<br>
need to relax some of them when we implement P0315 in post-C++-17<br>
right?<br>
<br>
For e.g. these would be ok w P0315 right?<br>
<br>
template<int N = []{ return 5; }()> struct X { };<br>
<br>
X<[](auto a){ return a; }(10)> x;</blockquote><div><br></div><div>Who can say... P0315's direction is not finalized as far as I'm aware, and I don't expect it to apply retroactively, so we'll need the DR1607 rules anyway.</div></div></div></div>