1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-03 23:25:26 +02:00

Bug 531322 - Overloading between initializer-list and non-initializer-list constructors during list-initializations

Change-Id: I6884ce16bc0f14893f074eef27015b3654aedba5
This commit is contained in:
Nathan Ridge 2018-02-20 01:10:13 -05:00
parent 37dfcc486e
commit cf308662d2
2 changed files with 46 additions and 9 deletions

View file

@ -10651,4 +10651,35 @@ public class AST2TemplateTests extends AST2CPPTestBase {
public void testLongDependentFunctionCallChain_530692() throws Exception {
parseAndCheckBindings();
}
// namespace std {
// template <class E>
// struct initializer_list {
// E* array;
// unsigned long len;
// };
// }
//
// template <typename T>
// struct vector {
// vector(std::initializer_list<T>);
//
// template <typename InputIterator>
// vector(InputIterator, InputIterator);
// };
//
// struct mystring {
// mystring(const char*);
// };
//
// void foo(vector<mystring>);
//
// int main() {
// char** begin;
// char** end;
// foo({begin, end});
// }
public void testOverloadResolutionWithInitializerList_531322() throws Exception {
parseAndCheckBindings();
}
}

View file

@ -631,7 +631,7 @@ public class Conversions {
return cost;
}
// 13.3.1.7 Initialization by list-initialization
// [over.match.list] Initialization by list-initialization
static Cost listInitializationOfClass(EvalInitList arg, ICPPClassType t, boolean isDirect, boolean deferUDC) throws DOMException {
if (deferUDC) {
Cost c= new Cost(arg.getType(), t, Rank.USER_DEFINED_CONVERSION);
@ -639,10 +639,15 @@ public class Conversions {
return c;
}
// If T has an initializer-list constructor
// p1: When objects of non-aggregate class type are list-initialized,
// [...] overload resoution selects the constructor in two phases:
// - Initially, the candidate functions are the initializer-
// list constructors of the class T and the argument list
// consists of the initializer list as a single argument.
ICPPConstructor usedCtor= null;
Cost bestCost= null;
boolean hasInitListConstructor= false;
final ICPPConstructor[] constructors = t.getConstructors();
ICPPConstructor[] ctors= constructors;
for (ICPPConstructor ctor : ctors) {
@ -658,7 +663,6 @@ public class Conversions {
if (parTypes.length > 0) {
final IType target = parTypes[0];
if (getInitListType(target) != null) {
hasInitListConstructor= true;
Cost cost= listInitializationSequence(arg, target, UDCMode.FORBIDDEN, isDirect);
if (cost.converts()) {
int cmp= cost.compareTo(bestCost);
@ -674,10 +678,7 @@ public class Conversions {
}
}
}
if (hasInitListConstructor) {
if (bestCost == null)
return Cost.NO_CONVERSION;
if (bestCost != null) {
if (!bestCost.isAmbiguousUDC() && !isDirect) {
if (usedCtor != null && usedCtor.isExplicit()) {
bestCost.setRank(Rank.NO_MATCH);
@ -691,7 +692,12 @@ public class Conversions {
return bestCost;
}
// No initializer-list constructor
// - If no viable initializer-list constructor is found,
// overload resolution is performed again, where the
// candidate functions are all the constructors of the
// class T and the argument list consists of the elements
// of the initializer list.
LookupData data= new LookupData(t.getNameCharArray(), null, CPPSemantics.getCurrentLookupPoint());
final ICPPEvaluation[] expandedArgs = arg.getClauses();
data.setFunctionArguments(false, expandedArgs);