diff options
author | David Majnemer <david.majnemer@gmail.com> | 2013-10-25 09:12:52 +0000 |
---|---|---|
committer | David Majnemer <david.majnemer@gmail.com> | 2013-10-25 09:12:52 +0000 |
commit | 9adc361008e25f5b7d9c3aa8968832384d21c12a (patch) | |
tree | 1498f839f6d8700423dd6911d4c648ff1a551e4f /clang/lib/Sema | |
parent | be9cdbb58cfd35291e51291390ac845fb7156095 (diff) | |
download | bcm5719-llvm-9adc361008e25f5b7d9c3aa8968832384d21c12a.tar.gz bcm5719-llvm-9adc361008e25f5b7d9c3aa8968832384d21c12a.zip |
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.
llvm-svn: 193397
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 21 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 13 |
2 files changed, 24 insertions, 10 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index c842ed035d8..69f8f2e739a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -10962,13 +10962,22 @@ void Sema::PopExpressionEvaluationContext() { 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. + 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. diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index c843da74cd2..2e1cd105a98 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1229,20 +1229,25 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, 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; |