From: Anders Carlsson Date: Sun, 30 Nov 2008 19:50:32 +0000 (+0000) Subject: Add Sema::VerifyIntegerConstantExpression X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e21555e666004b9aea0c8122358bc4cd3e61c4e7;p=clang Add Sema::VerifyIntegerConstantExpression git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60305 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 044bfbd73b..7b69de5cc2 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1347,6 +1347,11 @@ public: void InitBuiltinVaListType(); + /// VerifyIntegerConstantExpression - verifies that an expression is an ICE, + /// and reports the appropriate diagnostics. Returns false on success. + /// Can optionally return the value of the expression. + bool VerifyIntegerConstantExpression(const Expr* E, llvm::APSInt *Result = 0); + //===--------------------------------------------------------------------===// // Extra semantic analysis beyond the C type system private: diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index fb964692b3..0c17c75fce 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3673,3 +3673,36 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, << SrcExpr->getSourceRange(); return isInvalid; } + +bool Sema::VerifyIntegerConstantExpression(const Expr* E, llvm::APSInt *Result) +{ + Expr::EvalResult EvalResult; + + if (!E->Evaluate(EvalResult, Context) || !EvalResult.Val.isInt() || + EvalResult.HasSideEffects) { + Diag(E->getExprLoc(), diag::err_expr_not_ice) << E->getSourceRange(); + + if (EvalResult.Diag) { + // We only show the note if it's not the usual "invalid subexpression" + // or if it's actually in a subexpression. + if (EvalResult.Diag != diag::note_invalid_subexpr_in_ice || + E->IgnoreParens() != EvalResult.DiagExpr->IgnoreParens()) + Diag(EvalResult.DiagLoc, EvalResult.Diag); + } + + return true; + } + + if (EvalResult.Diag) { + Diag(E->getExprLoc(), diag::ext_expr_not_ice) << + E->getSourceRange(); + + // Print the reason it's not a constant. + if (Diags.getDiagnosticLevel(diag::ext_expr_not_ice) != Diagnostic::Ignored) + Diag(EvalResult.DiagLoc, EvalResult.Diag); + } + + if (Result) + *Result = EvalResult.Val.getInt(); + return false; +}