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 d1ee11ec350..3134508e077 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 @@ -148,6 +148,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPConstructor; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethod; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; @@ -4225,13 +4226,15 @@ public class AST2CPPTests extends AST2CPPTestBase { } // class X { - // X(const X &); + // public: + // X(const X &); // }; // class Y { - // operator X (); + // public: + // operator X(); // }; // Y y; - // X x = new X(y); + // X* x = new X(y); public void testBug90654a() throws Exception { IASTTranslationUnit tu = parse(getAboveComment(), CPP); NameCollector col = new NameCollector(true); @@ -12777,4 +12780,58 @@ public class AST2CPPTests extends AST2CPPTestBase { public void testElabSpecInTrailingReturn_535777() throws Exception { parseAndCheckBindings(); } + + // struct type { + // type(int,int){}; + // }; + // + // int main() { + // type a0(1,2); + // type a1{1,2}; + // type a2 = {1,2}; + // type a3(1,2,3); + // type a4{1,2,3}; + // type a5 = {1,2,3}; + // } + public void testInitListConstructor_542448() throws Exception { + BindingAssertionHelper bh = getAssertionHelper(); + bh.assertImplicitName("a0", 2, CPPConstructor.class); + bh.assertImplicitName("a1", 2, CPPConstructor.class); + bh.assertImplicitName("a2", 2, CPPConstructor.class); + + bh.assertImplicitName("a3", 2, IProblemBinding.class); + bh.assertImplicitName("a4", 2, IProblemBinding.class); + bh.assertImplicitName("a5", 2, IProblemBinding.class); + } + + // struct type { + // explicit type(int,int){}; + // }; + // + // int main() { + // type a0(1,2); // ok + // type a1{1,2}; // ok + // type a2 = {1,2}; // error: using explict ctor + // } + public void testInitListConstructorWithExplicit_542448() throws Exception { + BindingAssertionHelper bh = getAssertionHelper(); + bh.assertImplicitName("a0", 2, CPPConstructor.class); + bh.assertImplicitName("a1", 2, CPPConstructor.class); + bh.assertImplicitName("a2", 2, IProblemBinding.class); + } + + // struct type { + // explicit type(int,int); + // type(float,float); + // }; + // int main() { + // type a0 = {1,2}; + // } + public void testInitListConstructorWithExplicit2_542448() throws Exception { + BindingAssertionHelper bh = getAssertionHelper(); + // ill-formed, because overload resolution + // prefers the (int,int) constructor + // which is explicit + bh.assertImplicitName("a0", 2, IProblemBinding.class); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java index 2299b6b5dc5..dfad90333ee 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java @@ -3738,6 +3738,9 @@ public class CPPSemantics { if (f instanceof ICPPConstructor) return f; // If a conversion is used, the constructor is elided. + } else { + return new ProblemBinding(null, typeId, ISemanticProblem.BINDING_NOT_FOUND, + type.getConstructors()); } } } else if (initializer instanceof ICPPASTInitializerList) { @@ -3749,6 +3752,9 @@ public class CPPSemantics { ICPPFunction f = c.getUserDefinedConversion(); if (f instanceof ICPPConstructor) return f; + } else { + return new ProblemBinding(null, typeId, ISemanticProblem.BINDING_NOT_FOUND, + type.getConstructors()); } } } else if (initializer instanceof ICPPASTConstructorInitializer) { 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 14470e681b2..189d802e8e2 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 @@ -728,11 +728,16 @@ public class Conversions { } } } + final IBinding result = CPPSemantics.resolveFunction(data, filteredConstructors, true, false); final Cost c; if (result instanceof ICPPMethod) { - c = new Cost(arg.getType(), t, Rank.IDENTITY); - c.setUserDefinedConversion((ICPPMethod) result); + if (!isDirect && ((ICPPMethod) result).isExplicit()) { + c = Cost.NO_CONVERSION; + } else { + c = new Cost(arg.getType(), t, Rank.IDENTITY); + c.setUserDefinedConversion((ICPPMethod) result); + } } else if (result instanceof IProblemBinding && ((IProblemBinding) result).getID() == IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP) { c = new Cost(arg.getType(), t, Rank.USER_DEFINED_CONVERSION);