diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-12-14 23:32:26 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-12-14 23:32:26 +0000 |
commit | daaefc5381f9aafbb1cb6f88fb5ac6aaf34d65bf (patch) | |
tree | 8f5c84efdcc439b671448e168c779522ab53e81b /lib/Sema/SemaExpr.cpp | |
parent | 0a36512b175103d60020aaa857363dca33f36558 (diff) |
Produce more detailed diagnostics when static_assert condition is not an ICE.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146607 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 51 |
1 files changed, 33 insertions, 18 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index d9626369d9..8231cda75e 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -9232,30 +9232,45 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, return isInvalid; } -bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result){ - // FIXME: In C++11, this evaluates the expression even if it's not an ICE. - // Don't evaluate it a second time below just to get the diagnostics. - llvm::APSInt ICEResult; - if (E->isIntegerConstantExpr(ICEResult, Context)) { - if (Result) - *Result = ICEResult; - return false; +bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result, + unsigned DiagID, bool AllowFold) { + // Circumvent ICE checking in C++11 to avoid evaluating the expression twice + // in the non-ICE case. + if (!getLangOptions().CPlusPlus0x) { + if (E->isIntegerConstantExpr(Context)) { + if (Result) + *Result = E->EvaluateKnownConstInt(Context); + return false; + } } Expr::EvalResult EvalResult; llvm::SmallVector<PartialDiagnosticAt, 8> Notes; EvalResult.Diag = &Notes; - if (!E->EvaluateAsRValue(EvalResult, Context) || !EvalResult.Val.isInt() || - EvalResult.HasSideEffects) { - Diag(E->getExprLoc(), diag::err_expr_not_ice) << E->getSourceRange(); + // Try to evaluate the expression, and produce diagnostics explaining why it's + // not a constant expression as a side-effect. + bool Folded = E->EvaluateAsRValue(EvalResult, Context) && + EvalResult.Val.isInt() && !EvalResult.HasSideEffects; + + // In C++11, we can rely on diagnostics being produced for any expression + // which is not a constant expression. If no diagnostics were produced, then + // this is a constant expression. + if (Folded && getLangOptions().CPlusPlus0x && Notes.empty()) { + if (Result) + *Result = EvalResult.Val.getInt(); + return false; + } + + if (!Folded || !AllowFold) { + Diag(E->getSourceRange().getBegin(), + DiagID ? DiagID : diag::err_expr_not_ice) << E->getSourceRange(); // We only show the notes if they're not the usual "invalid subexpression" // or if they are actually in a subexpression. - if (!Notes.empty() && - (Notes.size() != 1 || - Notes[0].second.getDiagID() != diag::note_invalid_subexpr_in_const_expr - || Notes[0].first != E->IgnoreParens()->getExprLoc())) { + if (Notes.size() != 1 || + Notes[0].second.getDiagID() != diag::note_invalid_subexpr_in_const_expr + || Notes[0].first != E->IgnoreParens()->getExprLoc()) { for (unsigned I = 0, N = Notes.size(); I != N; ++I) Diag(Notes[I].first, Notes[I].second); } @@ -9263,10 +9278,10 @@ bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result){ return true; } - Diag(E->getExprLoc(), diag::ext_expr_not_ice) << E->getSourceRange(); + Diag(E->getSourceRange().getBegin(), diag::ext_expr_not_ice) + << E->getSourceRange(); - if (Notes.size() && - Diags.getDiagnosticLevel(diag::ext_expr_not_ice, E->getExprLoc()) + if (Diags.getDiagnosticLevel(diag::ext_expr_not_ice, E->getExprLoc()) != DiagnosticsEngine::Ignored) for (unsigned I = 0, N = Notes.size(); I != N; ++I) Diag(Notes[I].first, Notes[I].second); |