diff options
5 files changed, 69 insertions, 37 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index cc0da496320..48245376d38 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -8779,6 +8779,30 @@ public class AST2CPPTests extends AST2TestBase { } // 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; // } // struct A {}; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index 381ccac2afb..8ce664366d0 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -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); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java index 883355c4071..13fdbffc576 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java @@ -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) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java index 6a8cf9a3e23..70624d86462 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java @@ -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; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java index 8c6c7fbc595..cade32fee93 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java @@ -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; } |