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
