The overload resolution for initializer lists was incomplete. It did not
properly take the number of elements in the target array into account. The
size comparison already allows for an array of unknown boud, per P0338 'Permit
conversions to arrays of unknown bound'. However currently this is dead code.
This fixes the overload resolution for cases like:
void f(int(&&)[2]); void g() { f({1}); f({1, 2}); f({1, 2, 3}); }
The patch adds extra members to ImplicitConversionSequence, making it larger
for members only used for an initializer list. The largest member of the class'
union is UserDefinedConversion. An initializer list can be used with a user
defined conversion sequence, so it's not possible to use unused space in the
union. I'm open to suggestions how to avoid the enlargement of the class.
Storing the IntListExpr here doesn't seem like it captures the necessary information. Consider:
Here, the InitListExpr in both cases has two elements. We don't store the converted InitListExpr, because we don't -- and aren't allowed to -- build the converted InitListExpr until we've chosen the right overload. But I think what we're supposed to do in this case is to notice that calling #1 would initialize only one element of the array (one pair), whereas calling #2 would initialize two elements of the array, so we should call #2 here.
In effect, what you need to do is to compute the effective array bound for the case where we're initializing an array of unknown bound, and prefer the conversion sequence with the lower effective array bound. InitListChecker already works this out internally, see here, but currently only does that when actually doing the conversion (when not in VerifyOnly mode); you'd need to adjust that.
Given that the code that needs this (the P0388 part) is dead code for now, perhaps the best thing would be to do only the array bound comparison in this patch, and we can compute the proper array bound for said comparison in a future patch.