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 48afbbfb40b..4afd79421b6 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 @@ -10329,6 +10329,44 @@ public class AST2TemplateTests extends AST2CPPTestBase { helper.assertVariableValue("waldo", 42); } + // template + // struct Model { + // static constexpr int getFamily() { + // if (N < 1350) + // return 1300; + // else + // return 1400; + // } + // static constexpr int res = getFamily(); + // }; + // + // constexpr int waldo = Model<1302>::res; + public void testStaticConstexprFunctionWithDependentBody_521274a() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + helper.assertVariableValue("waldo", 1300); + } + + // template + // struct constant { + // static constexpr int value = N; + // }; + // template + // struct Model { + // static constexpr int getFamily() { + // if (N < 1350) + // return 1300; + // else + // return 1400; + // } + // using family_t = constant; + // }; + // + // constexpr int waldo = Model<1302>::family_t::value; + public void testStaticConstexprFunctionWithDependentBody_521274b() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + helper.assertVariableValue("waldo", 1300); + } + // template // struct A { // template diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 8d2f4e0d638..683829e3170 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -3260,4 +3260,21 @@ public class CPPTemplates { } return name; } + + /** + * Checks whether a binding is fully instantiated, that is, it does not depend on template + * parameters that do not yet have values. + */ + public static boolean isFullyInstantiated(IBinding binding) { + while (binding != null) { + binding = binding.getOwner(); + if (binding instanceof ICPPTemplateDefinition) { + return false; + } + if (!(binding instanceof ICPPClassType)) { + break; + } + } + return true; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java index 73136a9b3c0..9a39c097122 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java @@ -108,9 +108,10 @@ public final class EvalFunctionCall extends CPPDependentEvaluation { @Override public boolean isValueDependent() { - return containsDependentValue(fArguments); + return containsDependentValue(fArguments) || + !CPPTemplates.isFullyInstantiated(resolveFunctionBinding(null)); } - + @Override public boolean isConstantExpression(IASTNode point) { if (!fCheckedIsConstantExpression) { @@ -301,7 +302,7 @@ public final class EvalFunctionCall extends CPPDependentEvaluation { ICPPFunction function = resolveFunctionBinding(context.getPoint()); if (function == null) return this; - + if (!function.isConstexpr()) return EvalFixed.INCOMPLETE;