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