Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11788,6 +11788,11 @@ bool ArrayExprEvaluator::VisitCXXParenListOrInitListExpr(
LLVM_DEBUG(llvm::dbgs() << "The number of elements to initialize: "
<< NumEltsToInit << ".\n");

if (!Info.CheckArraySize(ExprToVisit->getExprLoc(),
CAT->getNumAddressingBits(Info.Ctx), NumEltsToInit,
/*Diag=*/true))
return false;

Result = APValue(APValue::UninitArray(), NumEltsToInit, NumElts);

// If the array was previously zero-initialized, preserve the
Expand Down Expand Up @@ -11919,6 +11924,9 @@ bool ArrayExprEvaluator::VisitCXXConstructExpr(const CXXConstructExpr *E,
if (const ConstantArrayType *CAT = Info.Ctx.getAsConstantArrayType(Type)) {
unsigned FinalSize = CAT->getZExtSize();

if (!CheckArraySize(Info, CAT, E->getExprLoc()))
return false;

// Preserve the array filler if we had prior zero-initialization.
APValue Filler =
HadZeroInit && Value->hasArrayFiller() ? Value->getArrayFiller()
Expand Down
42 changes: 42 additions & 0 deletions clang/test/SemaCXX/constant-expression-cxx2a.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1497,3 +1497,45 @@ namespace GH67317 {
// expected-note {{subobject of type 'const unsigned char' is not initialized}}
__builtin_bit_cast(unsigned char, *new char[3][1]);
};

namespace LargeArrays {
constexpr unsigned kNumberOfIterations = 2000000;
constexpr unsigned kThreadsNumber = 2 * 8 * 1024;

/// Large array initialized by Paren/InitListExpr.
template <typename T, unsigned long S>
struct array1 {
using AT = T[S];
AT Data{};
constexpr array1() : Data(T()) {} // expected-note {{cannot allocate array}}
};

/// And initialized by a CXXConstructExpr.
template <typename T, unsigned long S>
struct array2 {
using AT = T[S];
AT Data;
constexpr array2() {} // expected-note {{cannot allocate array}}
};

template <typename T>
class A{};
int main() {
array1<A<short*>, kThreadsNumber * kNumberOfIterations> futures1{};
array2<A<short*>, kThreadsNumber * kNumberOfIterations> futures2{};
}

constexpr int CE1() {
array1<A<short*>, kThreadsNumber * kNumberOfIterations> futures1{}; // expected-note {{in call to}}
return 1;
}
static_assert(CE1() == 1); // expected-error {{not an integral constant expression}} \
// expected-note {{in call to}}

constexpr int CE2() {
array2<A<short*>, kThreadsNumber * kNumberOfIterations> futures2{}; // expected-note {{in call to}}
return 1;
}
static_assert(CE2() == 1); // expected-error {{not an integral constant expression}} \
// expected-note {{in call to}}
}