Implement C++ DR299, which allows an implicit conversion from a class
type to an integral or enumeration type in the size of an array new
expression, e.g.,
new int[ConvertibleToInt(10)];
This is a GNU and C++0x extension.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@107229 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 86d4d42..3c64584 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -721,12 +721,29 @@
// or enumeration type with a non-negative value."
Expr *ArraySize = (Expr *)ArraySizeE.get();
if (ArraySize && !ArraySize->isTypeDependent()) {
+
QualType SizeType = ArraySize->getType();
+ OwningExprResult ConvertedSize
+ = ConvertToIntegralOrEnumerationType(StartLoc, move(ArraySizeE),
+ PDiag(diag::err_array_size_not_integral),
+ PDiag(diag::err_array_size_incomplete_type)
+ << ArraySize->getSourceRange(),
+ PDiag(diag::err_array_size_explicit_conversion),
+ PDiag(diag::note_array_size_conversion),
+ PDiag(diag::err_array_size_ambiguous_conversion),
+ PDiag(diag::note_array_size_conversion),
+ PDiag(getLangOptions().CPlusPlus0x? 0
+ : diag::ext_array_size_conversion));
+ if (ConvertedSize.isInvalid())
+ return ExprError();
+
+ ArraySize = ConvertedSize.takeAs<Expr>();
+ ArraySizeE = Owned(ArraySize);
+ SizeType = ArraySize->getType();
if (!SizeType->isIntegralOrEnumerationType())
- return ExprError(Diag(ArraySize->getSourceRange().getBegin(),
- diag::err_array_size_not_integral)
- << SizeType << ArraySize->getSourceRange());
+ return ExprError();
+
// Let's see if this is a constant < 0. If so, we reject it out of hand.
// We don't care about special rules, so we tell the machinery it's not
// evaluated - it gives us a result in more cases.