mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-05 08:46:02 +02:00
Bug 458679 - Ranking list-initialization sequences with user-defined
conversions Change-Id: Ia976acf656f3431f96880b32fedc575a56c4e86b Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
This commit is contained in:
parent
3cf7241ccb
commit
9ca379e67f
5 changed files with 69 additions and 37 deletions
|
@ -8778,6 +8778,30 @@ public class AST2CPPTests extends AST2TestBase {
|
|||
helper.assertProblem("waldo({1, 2, 3, 4})", "waldo", IProblemBinding.SEMANTIC_NAME_NOT_FOUND);
|
||||
}
|
||||
|
||||
// namespace std {
|
||||
// template<class E>
|
||||
// class initializer_list {
|
||||
// const E* _array;
|
||||
// long unsigned int _len;
|
||||
//
|
||||
// initializer_list(const E* array, int len) {}
|
||||
// };
|
||||
// }
|
||||
//
|
||||
// template<typename T>
|
||||
// struct A {
|
||||
// A(std::initializer_list<T> list) {}
|
||||
// };
|
||||
//
|
||||
// struct B {
|
||||
// int b;
|
||||
// };
|
||||
//
|
||||
// A<B> waldo({{0}, {0}});
|
||||
public void testListInitialization_458679() throws Exception {
|
||||
parseAndCheckImplicitNameBindings();
|
||||
}
|
||||
|
||||
// namespace std {
|
||||
// template<typename T> class initializer_list;
|
||||
// }
|
||||
|
|
|
@ -128,14 +128,6 @@ public class AST2TemplateTests extends AST2TestBase {
|
|||
return parseAndCheckBindings(code, CPP);
|
||||
}
|
||||
|
||||
protected IASTTranslationUnit parseAndCheckImplicitNameBindings() throws Exception {
|
||||
IASTTranslationUnit tu = parse(getAboveComment(), CPP, false, true);
|
||||
NameCollector col = new NameCollector(true /* Visit implicit names */);
|
||||
tu.accept(col);
|
||||
assertNoProblemBindings(col);
|
||||
return tu;
|
||||
}
|
||||
|
||||
protected BindingAssertionHelper getAssertionHelper() throws ParserException, IOException {
|
||||
String code= getAboveComment();
|
||||
return new BindingAssertionHelper(code, true);
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.tests.ast2;
|
||||
|
||||
import static org.eclipse.cdt.core.parser.ParserLanguage.CPP;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
|
@ -775,6 +777,14 @@ public class AST2TestBase extends BaseTestCase {
|
|||
assertNoProblemBindings(col);
|
||||
return tu;
|
||||
}
|
||||
|
||||
final protected IASTTranslationUnit parseAndCheckImplicitNameBindings() throws Exception {
|
||||
IASTTranslationUnit tu = parse(getAboveComment(), CPP, false, true);
|
||||
NameCollector col = new NameCollector(true /* Visit implicit names */);
|
||||
tu.accept(col);
|
||||
assertNoProblemBindings(col);
|
||||
return tu;
|
||||
}
|
||||
|
||||
final protected void assertNoProblemBindings(NameCollector col) {
|
||||
for (IASTName n : col.nameList) {
|
||||
|
|
|
@ -601,6 +601,11 @@ public class Conversions {
|
|||
bestCost.setRank(Rank.NO_MATCH);
|
||||
}
|
||||
}
|
||||
// This cost came from listInitializationSequence() with an std::initializer_list
|
||||
// type as the list initialization target. From the point of view of the caller,
|
||||
// however, the target is the class type, not std::initializer_list, so update it
|
||||
// accordingly.
|
||||
bestCost.setListInitializationTarget(t);
|
||||
return bestCost;
|
||||
}
|
||||
|
||||
|
|
|
@ -200,6 +200,35 @@ public class Cost {
|
|||
if (cmp != 0)
|
||||
return cmp;
|
||||
|
||||
// [over.ics.rank] p3.3:
|
||||
// List-initialization sequence L1 is a better conversion sequence than
|
||||
// list-initialization sequence L2 if
|
||||
if (fListInitializationTarget != null && other.fListInitializationTarget != null) {
|
||||
// - L1 converts to std::initializer_list<X> for some X and L2 does not,
|
||||
// or if not that,
|
||||
IType initListType = Conversions.getInitListType(fListInitializationTarget);
|
||||
IType otherInitListType = Conversions.getInitListType(other.fListInitializationTarget);
|
||||
if (initListType != null && otherInitListType == null) {
|
||||
return -1;
|
||||
} else if (initListType == null && otherInitListType != null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// - L1 converts to type "array of N1 T", L2 converts to type "array of
|
||||
// N2 T", and N1 is smaller than N2
|
||||
if (fListInitializationTarget instanceof IArrayType && other.fListInitializationTarget instanceof IArrayType) {
|
||||
IArrayType arrayType = (IArrayType) fListInitializationTarget;
|
||||
IArrayType otherArrayType = (IArrayType) other.fListInitializationTarget;
|
||||
if (arrayType.getType().isSameType(otherArrayType.getType())) {
|
||||
Long size = arrayType.getSize().numericalValue();
|
||||
Long otherSize = otherArrayType.getSize().numericalValue();
|
||||
if (size != null && otherSize != null) {
|
||||
return size.compareTo(otherSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// rank is equal
|
||||
if (rank == Rank.USER_DEFINED_CONVERSION) {
|
||||
// 13.3.3.1.10
|
||||
|
@ -241,35 +270,7 @@ public class Cost {
|
|||
if ((other.fQualificationAdjustments & qdiff) == 0)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// [over.ics.rank] p3:
|
||||
// List-initialization sequence L1 is a better conversion sequence than
|
||||
// list-initialization sequence L2 if
|
||||
if (fListInitializationTarget != null && other.fListInitializationTarget != null) {
|
||||
// - L1 converts to std::initializer_list<X> for some X and L2 does not,
|
||||
// or if not that,
|
||||
IType initListType = Conversions.getInitListType(fListInitializationTarget);
|
||||
IType otherInitListType = Conversions.getInitListType(other.fListInitializationTarget);
|
||||
if (initListType != null && otherInitListType == null) {
|
||||
return -1;
|
||||
} else if (initListType == null && otherInitListType != null) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// - L1 converts to type "array of N1 T", L2 converts to type "array of
|
||||
// N2 T", and N1 is smaller than N2
|
||||
if (fListInitializationTarget instanceof IArrayType && other.fListInitializationTarget instanceof IArrayType) {
|
||||
IArrayType arrayType = (IArrayType) fListInitializationTarget;
|
||||
IArrayType otherArrayType = (IArrayType) other.fListInitializationTarget;
|
||||
if (arrayType.getType().isSameType(otherArrayType.getType())) {
|
||||
Long size = arrayType.getSize().numericalValue();
|
||||
Long otherSize = otherArrayType.getSize().numericalValue();
|
||||
if (size != null && otherSize != null) {
|
||||
return size.compareTo(otherSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue