1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 14:42:11 +02:00

Bug 521274 - Defer execution of constexpr function body until function is fully instantiated

Change-Id: I35a63d15e7bfa7d3db98235eaa9dfe23e28950ac
This commit is contained in:
Nathan Ridge 2017-08-24 00:35:24 -04:00
parent 398ca82b48
commit e75a209b9f
3 changed files with 59 additions and 3 deletions

View file

@ -10329,6 +10329,44 @@ public class AST2TemplateTests extends AST2CPPTestBase {
helper.assertVariableValue("waldo", 42);
}
// template <int N>
// 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 <int N>
// struct constant {
// static constexpr int value = N;
// };
// template <int N>
// struct Model {
// static constexpr int getFamily() {
// if (N < 1350)
// return 1300;
// else
// return 1400;
// }
// using family_t = constant<getFamily()>;
// };
//
// constexpr int waldo = Model<1302>::family_t::value;
public void testStaticConstexprFunctionWithDependentBody_521274b() throws Exception {
BindingAssertionHelper helper = getAssertionHelper();
helper.assertVariableValue("waldo", 1300);
}
// template <class>
// struct A {
// template <class>

View file

@ -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;
}
}

View file

@ -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;