Before this commit, on code like:
struct S { ... }; S arr[10000000];
while checking if arr is constexpr, clang would reserve memory for
arr before running constructor for S. If S turned out to not have a
valid constexpr c-tor, clang would still try to initialize each element
(and, in case the c-tor was trivial, even skipping the constexpr step
limit), only to discard that whole APValue later, since the first
element generated a diagnostic.
With this change, we start by allocating just 1 element in the array to
try out the c-tor and take an early exit if any diagnostics are
generated, avoiding possibly large memory allocation and a lot of work
initializing to-be-discarded APValues.
Fixes 51712 and 51843.
In the future we may want to be smarter about large possibly-constexrp
arrays and maybe make the allocation lazy.
maybe unroll the loop with a helper like checkConstantInitialization and just call it for a single element first and perform copy & call again for the whole thing ?
that way we can migrate performance issues later on (e.g. put a threshold on FinalSize, don't perform the small step check if it's less than 100, since copying might introduce a significant extra latency in such cases).
WDYT?