summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2013-10-25 09:12:52 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2013-10-25 09:12:52 +0000
commit9adc361008e25f5b7d9c3aa8968832384d21c12a (patch)
tree1498f839f6d8700423dd6911d4c648ff1a551e4f /clang/lib/Sema
parentbe9cdbb58cfd35291e51291390ac845fb7156095 (diff)
downloadbcm5719-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.cpp21
-rw-r--r--clang/lib/Sema/SemaLambda.cpp13
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;
OpenPOWER on IntegriCloud