diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java index a381a7dc621..16401af5f38 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java @@ -2452,6 +2452,26 @@ public class IndexCPPBindingResolutionTest extends IndexBindingResolutionTestBas public void testDelegatingConstructorCallInConstexprConstructor_509871() throws Exception { checkBindings(); } + + // // empty file + + // template + // struct base { + // constexpr base() : p(0) {} + // int p; + // }; + // + // template + // struct derived : public base { + // constexpr derived() : base() {} + // constexpr derived(int) : derived() {} + // }; + // + // class C {}; + // derived waldo = 0; + public void testDelegatingConstructorCallInConstexprConstructor_514595() throws Exception { + checkBindings(); + } // enum class NoneType { None }; // const NoneType None = None; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConstructor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConstructor.java index bd38fcc0e16..42263616c8a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConstructor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConstructor.java @@ -331,16 +331,18 @@ public final class EvalConstructor extends CPPDependentEvaluation { @Override public ICPPEvaluation instantiate(InstantiationContext context, int maxDepth) { - IType newType = CPPTemplates.instantiateType(fType, context); - ICPPEvaluation[] newArguments = new ICPPEvaluation[fArguments.length]; for (int i = 0; i < fArguments.length; i++) { newArguments[i] = fArguments[i].instantiate(context, maxDepth); } + IType newType = null; ICPPConstructor newConstructor; try { newConstructor = (ICPPConstructor) CPPTemplates.instantiateBinding(fConstructor, context, maxDepth); + if (newConstructor != null) { + newType = newConstructor.getClassOwner(); + } if (newConstructor instanceof CPPDeferredFunction) { ICPPFunction[] candidates = ((CPPDeferredFunction) newConstructor).getCandidates(); if (candidates != null) { @@ -352,6 +354,9 @@ public final class EvalConstructor extends CPPDependentEvaluation { if (resolved instanceof EvalBinding) { EvalBinding evalBinding = (EvalBinding) resolved; newConstructor = (ICPPConstructor) evalBinding.getBinding(); + if (newConstructor != null) { + newType = newConstructor.getClassOwner(); + } } } } @@ -359,6 +364,15 @@ public final class EvalConstructor extends CPPDependentEvaluation { newConstructor = fConstructor; } + // Only instantiate fType separately if we couldn't get the instantiated type + // via newConstructor.getClassOwner() for some reason. This is not just for + // efficiency; instantiating fType directly will not work if fType is a + // CPPClassTemplate because CPPTemplates.instantiateType() does not instantiate + // CPPClassTemplates, only CPPDeferredClassInstances (TODO: why?). + if (newType == null) { + newType = CPPTemplates.instantiateType(fType, context); + } + return new EvalConstructor(newType, newConstructor, newArguments, getTemplateDefinition()); } }