Should be a bit improved in r194052.
On Sun, Nov 3, 2013 at 9:30 PM, Richard Smith <[email protected]> wrote: > > > > On Fri, Oct 25, 2013 at 2:12 AM, David Majnemer > <[email protected]>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 >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >> > >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
