1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-04 07:35:24 +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 { public void testLongDependentFunctionCallChain_530692() throws Exception {
parseAndCheckBindings(); 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; 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 { static Cost listInitializationOfClass(EvalInitList arg, ICPPClassType t, boolean isDirect, boolean deferUDC) throws DOMException {
if (deferUDC) { if (deferUDC) {
Cost c= new Cost(arg.getType(), t, Rank.USER_DEFINED_CONVERSION); Cost c= new Cost(arg.getType(), t, Rank.USER_DEFINED_CONVERSION);
@ -639,10 +639,15 @@ public class Conversions {
return c; 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; ICPPConstructor usedCtor= null;
Cost bestCost= null; Cost bestCost= null;
boolean hasInitListConstructor= false;
final ICPPConstructor[] constructors = t.getConstructors(); final ICPPConstructor[] constructors = t.getConstructors();
ICPPConstructor[] ctors= constructors; ICPPConstructor[] ctors= constructors;
for (ICPPConstructor ctor : ctors) { for (ICPPConstructor ctor : ctors) {
@ -658,7 +663,6 @@ public class Conversions {
if (parTypes.length > 0) { if (parTypes.length > 0) {
final IType target = parTypes[0]; final IType target = parTypes[0];
if (getInitListType(target) != null) { if (getInitListType(target) != null) {
hasInitListConstructor= true;
Cost cost= listInitializationSequence(arg, target, UDCMode.FORBIDDEN, isDirect); Cost cost= listInitializationSequence(arg, target, UDCMode.FORBIDDEN, isDirect);
if (cost.converts()) { if (cost.converts()) {
int cmp= cost.compareTo(bestCost); int cmp= cost.compareTo(bestCost);
@ -674,10 +678,7 @@ public class Conversions {
} }
} }
} }
if (hasInitListConstructor) { if (bestCost != null) {
if (bestCost == null)
return Cost.NO_CONVERSION;
if (!bestCost.isAmbiguousUDC() && !isDirect) { if (!bestCost.isAmbiguousUDC() && !isDirect) {
if (usedCtor != null && usedCtor.isExplicit()) { if (usedCtor != null && usedCtor.isExplicit()) {
bestCost.setRank(Rank.NO_MATCH); bestCost.setRank(Rank.NO_MATCH);
@ -691,7 +692,12 @@ public class Conversions {
return bestCost; 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()); LookupData data= new LookupData(t.getNameCharArray(), null, CPPSemantics.getCurrentLookupPoint());
final ICPPEvaluation[] expandedArgs = arg.getClauses(); final ICPPEvaluation[] expandedArgs = arg.getClauses();
data.setFunctionArguments(false, expandedArgs); data.setFunctionArguments(false, expandedArgs);