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 cf6a682bc55..381e0de232e 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 @@ -7130,4 +7130,33 @@ public class AST2CPPTests extends AST2BaseTest { IScope scope= t.getScope(); assertEquals(EScopeKind.eGlobal, scope.getKind()); } + + // class C {}; + // class D : public C {}; + // class E { + // public: E(D) {} + // }; + // void test(C c) {} + // void test(E e) {} + // + // void xx() { + // D d1; + // const D d2= D(); + // test(d1); // problem binding here although test(C c) has to be selected + // test(d2); // problem binding here although test(C c) has to be selected + // } + public void testDerivedToBaseConversion_269318() throws Exception { + final String code = getAboveComment(); + BindingAssertionHelper ba= new BindingAssertionHelper(code, true); + ICPPFunction t= ba.assertNonProblem("test(d1);", 4, ICPPFunction.class); + ICPPClassType ct= (ICPPClassType) t.getParameters()[0].getType(); + assertEquals("C", ct.getName()); + + t= ba.assertNonProblem("test(d2);", 4, ICPPFunction.class); + ct= (ICPPClassType) t.getParameters()[0].getType(); + assertEquals("C", ct.getName()); + + parseAndCheckBindings(code, ParserLanguage.CPP); + } + } 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 b0dce3442bf..c6cdc8ad0b9 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 @@ -162,6 +162,22 @@ public class Conversions { } // Non-reference binding + // [13.3.3.1-6] Subsume cv-qualifications + source= getNestedType(source, TDEF | REF | CVQ | PTR_CVQ); + target= getNestedType(target, TDEF | REF | CVQ | PTR_CVQ); + + // [13.3.3.1-6] Derived to base conversion + if (source instanceof ICPPClassType && target instanceof ICPPClassType) { + int depth= calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, source, target); + if (depth > -1) { + if (depth == 0) { + return new Cost(source, target, Rank.IDENTITY); + } + Cost cost= new Cost(source, target, Rank.CONVERSION); + cost.setInheritanceDistance(depth); + return cost; + } + } return nonReferenceConversion(source, target, udc, isImpliedObject); } @@ -799,23 +815,4 @@ public class Conversions { return true; } - -// mstodo must be part of implicit conversion -// /** -// * [13.3.3.1-6] Derived to base conversion -// * @param cost -// * @throws DOMException -// */ -// private static final void derivedToBaseConversion(Cost cost) throws DOMException { -// IType s = getUltimateType(cost.source, true); -// IType t = getUltimateType(cost.target, true); -// -// if (s instanceof ICPPClassType && t instanceof ICPPClassType) { -// int depth= calculateInheritanceDepth(CPPSemantics.MAX_INHERITANCE_DEPTH, s, t); -// if (depth > -1) { -// cost.rank = Cost.DERIVED_TO_BASE_CONVERSION; -// cost.conversion = depth; -// } -// } -// } }