in continuing on p0388 (unbounded array conversions), I discovered we don't deal with list initialization of bounded array parameters. Indeed there's a smoking gun:
// FIXME: We're missing a lot of these checks.
This patch implements those checks. I discovered that the existing implementation, when marking an implicit conversion sequence as being to std::initializer_list, is broken in that it'll think initializing 'std::initializer_list<T> parm[N]' is doing that. But it's not, it's initializing an array of std::initializer. There's a test for that, (clang/tests/CXX/drs/dr15xx.cpp, around line 490) but it's working due to the other missing checks! (It continues to work after this patch too.)
Anyway, rather than have a single bit flag 'StdInitializerListElement' we need to record the type being initialized by a list, so we can compare array bounds. Sadly this does grow ImplicitConversionSequence.
TryListConversion now checks the target array type has sufficient bounds, and if it has additional bounds, there is a default conversion from {} available. Note the FIXME there -- is there a better way to determine that?
CompareImplicitConversionSequence now also compares array size, for two conversions to array type.
The structure of the code changes in SemaOverload is ready for changes that p0388 introduces involving IncompleteArrayType -- the llvm_unreachables in CompareImplicitConversionSequence in particular.
... let's try adding some other reviewers who've had their fingers in SemaOverload ...
Can we store this directly as a QualType instead? (I think the only reason we store types as void*s in *ConversionSequence is a historical artifact from a time when union members couldn't have non-trivial default constructors.)
It's also not clear to me whether we need to store an additional type here, in addition to the types we're already tracking. I think I would expect the type we need to inspect is the overall destination type of the implicit conversion sequence (the "to type" for the final standard conversion sequence). Is this redundant, or are there cases where the type we want isn't already tracked? Is the problem case a conversion to T (&&)[], where we invent an array bound?