aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2011-12-14 23:32:26 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2011-12-14 23:32:26 +0000
commitdaaefc5381f9aafbb1cb6f88fb5ac6aaf34d65bf (patch)
tree8f5c84efdcc439b671448e168c779522ab53e81b /lib
parent0a36512b175103d60020aaa857363dca33f36558 (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')
-rw-r--r--lib/Sema/SemaDeclCXX.cpp13
-rw-r--r--lib/Sema/SemaExpr.cpp51
2 files changed, 38 insertions, 26 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp
index fb0307fb28..2176afa92d 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -9636,18 +9636,15 @@ Decl *Sema::ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc,
StringLiteral *AssertMessage = cast<StringLiteral>(AssertMessageExpr_);
if (!AssertExpr->isTypeDependent() && !AssertExpr->isValueDependent()) {
- llvm::APSInt Value(32);
- if (!AssertExpr->isIntegerConstantExpr(Value, Context)) {
- Diag(StaticAssertLoc,
- diag::err_static_assert_expression_is_not_constant) <<
- AssertExpr->getSourceRange();
+ llvm::APSInt Cond;
+ if (VerifyIntegerConstantExpression(AssertExpr, &Cond,
+ diag::err_static_assert_expression_is_not_constant,
+ /*AllowFold=*/false))
return 0;
- }
- if (Value == 0) {
+ if (!Cond)
Diag(StaticAssertLoc, diag::err_static_assert_failed)
<< AssertMessage->getString() << AssertExpr->getSourceRange();
- }
}
if (DiagnoseUnexpandedParameterPack(AssertExpr, UPPC_StaticAssertExpression))
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);