r193397 - Sema: Do not allow lambda expressions to appear inside of constant expressions

David Majnemer david.majnemer at gmail.com
Tue Nov 5 00:05:24 PST 2013


Should be a bit improved in r194052.


On Sun, Nov 3, 2013 at 9:30 PM, Richard Smith <richard at metafoo.co.uk> wrote:

>
>
>
> On Fri, Oct 25, 2013 at 2:12 AM, David Majnemer <david.majnemer at gmail.com>wrote:
>
>> Author: majnemer
>> Date: Fri Oct 25 04:12:52 2013
>> New Revision: 193397
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=193397&view=rev
>> Log:
>> Sema: Do not allow lambda expressions to appear inside of constant
>> expressions
>>
>> We would previously not diagnose this which would lead to crashes (on
>> very strange code).
>>
>> This fixes PR17675.
>>
>> Modified:
>>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>     cfe/trunk/lib/Sema/SemaExpr.cpp
>>     cfe/trunk/lib/Sema/SemaLambda.cpp
>>     cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
>>     cfe/trunk/test/SemaCXX/new-delete-0x.cpp
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=193397&r1=193396&r2=193397&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Oct 25
>> 04:12:52 2013
>> @@ -5067,6 +5067,8 @@ let CategoryName = "Lambda Issue" in {
>>    def note_lambda_decl : Note<"lambda expression begins here">;
>>    def err_lambda_unevaluated_operand : Error<
>>      "lambda expression in an unevaluated operand">;
>> +  def err_lambda_in_constant_expression : Error<
>> +    "a lambda expression may not appear inside of a constant
>> expression">;
>>    def err_lambda_return_init_list : Error<
>>      "cannot deduce lambda return type from initializer list">;
>>    def err_lambda_capture_default_arg : Error<
>>
>> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=193397&r1=193396&r2=193397&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Oct 25 04:12:52 2013
>> @@ -10962,13 +10962,22 @@ void Sema::PopExpressionEvaluationContex
>>    ExpressionEvaluationContextRecord& Rec = ExprEvalContexts.back();
>>
>>    if (!Rec.Lambdas.empty()) {
>> -    if (Rec.isUnevaluated()) {
>> -      // C++11 [expr.prim.lambda]p2:
>> -      //   A lambda-expression shall not appear in an unevaluated operand
>> -      //   (Clause 5).
>> +    if (Rec.isUnevaluated() || Rec.Context == ConstantEvaluated) {
>> +      unsigned D;
>> +      if (Rec.isUnevaluated()) {
>> +        // C++11 [expr.prim.lambda]p2:
>> +        //   A lambda-expression shall not appear in an unevaluated
>> operand
>> +        //   (Clause 5).
>> +        D = diag::err_lambda_unevaluated_operand;
>> +      } else {
>> +        // C++1y [expr.const]p2:
>> +        //   A conditional-expression e is a core constant expression
>> unless the
>> +        //   evaluation of e, following the rules of the abstract
>> machine, would
>> +        //   evaluate [...] a lambda-expression.
>>
>
> Can we get a better comment here? This is not what the language rule says:
> a lambda is allowed as a subexpression of a constant expression if it
> happens to not be evaluated during the evaluation of the core constant
> expression. For instance: 0 && []{return false;}() is currently allowed.
> Instead, say this is subject to a DR (and if you can dig out the number,
> that'd be great).
>
>
>> +        D = diag::err_lambda_in_constant_expression;
>> +      }
>>        for (unsigned I = 0, N = Rec.Lambdas.size(); I != N; ++I)
>> -        Diag(Rec.Lambdas[I]->getLocStart(),
>> -             diag::err_lambda_unevaluated_operand);
>> +        Diag(Rec.Lambdas[I]->getLocStart(), D);
>>      } else {
>>        // Mark the capture expressions odr-used. This was deferred
>>        // during lambda expression creation.
>>
>> Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=193397&r1=193396&r2=193397&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaLambda.cpp Fri Oct 25 04:12:52 2013
>> @@ -1229,20 +1229,25 @@ ExprResult Sema::ActOnLambdaExpr(SourceL
>>                                            CaptureInits, ArrayIndexVars,
>>                                            ArrayIndexStarts,
>> Body->getLocEnd(),
>>
>>  ContainsUnexpandedParameterPack);
>> -  // C++11 [expr.prim.lambda]p2:
>> -  //   A lambda-expression shall not appear in an unevaluated operand
>> -  //   (Clause 5).
>> +
>>    if (!CurContext->isDependentContext()) {
>>      switch (ExprEvalContexts.back().Context) {
>> +    // C++11 [expr.prim.lambda]p2:
>> +    //   A lambda-expression shall not appear in an unevaluated operand
>> +    //   (Clause 5).
>>      case Unevaluated:
>>      case UnevaluatedAbstract:
>> +    // C++1y [expr.const]p2:
>> +    //   A conditional-expression e is a core constant expression unless
>> the
>> +    //   evaluation of e, following the rules of the abstract machine,
>> would
>> +    //   evaluate [...] a lambda-expression.
>> +    case ConstantEvaluated:
>>        // We don't actually diagnose this case immediately, because we
>>        // could be within a context where we might find out later that
>>        // the expression is potentially evaluated (e.g., for typeid).
>>        ExprEvalContexts.back().Lambdas.push_back(Lambda);
>>        break;
>>
>> -    case ConstantEvaluated:
>>      case PotentiallyEvaluated:
>>      case PotentiallyEvaluatedIfUsed:
>>        break;
>>
>> Modified: cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp?rev=193397&r1=193396&r2=193397&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp (original)
>> +++ cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp Fri Oct 25 04:12:52 2013
>> @@ -275,9 +275,7 @@ namespace UndefinedBehavior {
>>
>>  // - a lambda-expression (5.1.2);
>>  struct Lambda {
>> -  // FIXME: clang crashes when trying to parse this! Revisit this check
>> once
>> -  // lambdas are fully implemented.
>> -  //int n : []{ return 1; }();
>> +  int n : []{ return 1; }(); // expected-error {{constant expression}}
>> expected-error {{integral constant expression}}
>>  };
>>
>>  // - an lvalue-to-rvalue conversion (4.1) unless it is applied to
>>
>> Modified: cfe/trunk/test/SemaCXX/new-delete-0x.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/new-delete-0x.cpp?rev=193397&r1=193396&r2=193397&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/SemaCXX/new-delete-0x.cpp (original)
>> +++ cfe/trunk/test/SemaCXX/new-delete-0x.cpp Fri Oct 25 04:12:52 2013
>> @@ -21,7 +21,9 @@ void bad_news(int *ip)
>>    auto s = new int*[[]{return 1;}()][2]; // expected-error {{expected
>> ']'}}
>>    // ... but not here:
>>    auto t = new (int(*)[[]]); // expected-error {{an attribute list
>> cannot appear here}}
>> -  auto u = new (int(*)[[]{return 1;}()][2]); // expected-error {{C++11
>> only allows consecutive left square brackets when introducing an
>> attribute}} expected-error {{variably modified type}}
>> +  auto u = new (int(*)[[]{return 1;}()][2]); // expected-error {{C++11
>> only allows consecutive left square brackets when introducing an
>> attribute}} \
>> +                                                expected-error
>> {{variably modified type}} \
>> +                                                expected-error {{a
>> lambda expression may not appear inside of a constant expression}}
>>  }
>>
>>  void good_deletes()
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20131105/035e3db6/attachment.html>


More information about the cfe-commits mailing list