diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-04 09:53:13 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-02-04 09:53:13 +0000 |
commit | 282e7e66748cc6dd14d6f7f2cb52e5373c531e61 (patch) | |
tree | 65a943e4a9c8a0534b580dcbbbcb6791451b5a56 /lib/Sema/SemaInit.cpp | |
parent | f39aec17b89f8f0dd78e78c50ad2fa08f12272e3 (diff) |
In C++11 mode, when an integral constant expression is desired and we have a
value of class type, look for a unique conversion operator converting to
integral or unscoped enumeration type and use that. Implements [expr.const]p5.
Sema::VerifyIntegerConstantExpression now performs the conversion and returns
the converted result. Some important callers of Expr::isIntegralConstantExpr
have been switched over to using it (including all of those required for C++11
conformance); this switch brings a side-benefit of improved diagnostics and, in
several cases, simpler code. However, some language extensions and attributes
have not been moved across and will not perform implicit conversions on
constant expressions of literal class type where an ICE is required.
In passing, fix static_assert to perform a contextual conversion to bool on its
argument.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149776 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 096ca7c93b..aa45c8333a 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -2150,26 +2150,27 @@ void InitListChecker::UpdateStructuredListElement(InitListExpr *StructuredList, } /// Check that the given Index expression is a valid array designator -/// value. This is essentailly just a wrapper around +/// value. This is essentially just a wrapper around /// VerifyIntegerConstantExpression that also checks for negative values /// and produces a reasonable diagnostic if there is a -/// failure. Returns true if there was an error, false otherwise. If -/// everything went okay, Value will receive the value of the constant -/// expression. -static bool +/// failure. Returns the index expression, possibly with an implicit cast +/// added, on success. If everything went okay, Value will receive the +/// value of the constant expression. +static ExprResult CheckArrayDesignatorExpr(Sema &S, Expr *Index, llvm::APSInt &Value) { SourceLocation Loc = Index->getSourceRange().getBegin(); // Make sure this is an integer constant expression. - if (S.VerifyIntegerConstantExpression(Index, &Value)) - return true; + ExprResult Result = S.VerifyIntegerConstantExpression(Index, &Value); + if (Result.isInvalid()) + return Result; if (Value.isSigned() && Value.isNegative()) return S.Diag(Loc, diag::err_array_designator_negative) << Value.toString(10) << Index->getSourceRange(); Value.setIsUnsigned(true); - return false; + return Result; } ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig, @@ -2194,9 +2195,9 @@ ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig, case Designator::ArrayDesignator: { Expr *Index = static_cast<Expr *>(D.getArrayIndex()); llvm::APSInt IndexValue; - if (!Index->isTypeDependent() && - !Index->isValueDependent() && - CheckArrayDesignatorExpr(*this, Index, IndexValue)) + if (!Index->isTypeDependent() && !Index->isValueDependent()) + Index = CheckArrayDesignatorExpr(*this, Index, IndexValue).take(); + if (!Index) Invalid = true; else { Designators.push_back(ASTDesignator(InitExpressions.size(), @@ -2216,10 +2217,13 @@ ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig, StartIndex->isValueDependent(); bool EndDependent = EndIndex->isTypeDependent() || EndIndex->isValueDependent(); - if ((!StartDependent && - CheckArrayDesignatorExpr(*this, StartIndex, StartValue)) || - (!EndDependent && - CheckArrayDesignatorExpr(*this, EndIndex, EndValue))) + if (!StartDependent) + StartIndex = + CheckArrayDesignatorExpr(*this, StartIndex, StartValue).take(); + if (!EndDependent) + EndIndex = CheckArrayDesignatorExpr(*this, EndIndex, EndValue).take(); + + if (!StartIndex || !EndIndex) Invalid = true; else { // Make sure we're comparing values with the same bit width. |