Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Ridge2015-02-04 07:55:55 +0000
committerSergey Prigogin2015-02-04 16:55:51 +0000
commit8eb15f3fcab1209acd989c968ae29e0be1e38f48 (patch)
treed49d4b335a117af44e3ed6f51c3a8cc49ba1a4fe
parent279821d96176781e7b0adb22b69612d0162993b0 (diff)
downloadorg.eclipse.cdt-8eb15f3fcab1209acd989c968ae29e0be1e38f48.tar.gz
org.eclipse.cdt-8eb15f3fcab1209acd989c968ae29e0be1e38f48.tar.xz
org.eclipse.cdt-8eb15f3fcab1209acd989c968ae29e0be1e38f48.zip
Bug 458679 - Ranking list-initialization sequences with user-defined
conversions Change-Id: Ia976acf656f3431f96880b32fedc575a56c4e86b Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java24
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java8
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java10
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Conversions.java5
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/Cost.java59
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;
}

Back to the top