mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 17:26:01 +02:00
Bug 521274 - Defer execution of constexpr function body until function is fully instantiated
Change-Id: I35a63d15e7bfa7d3db98235eaa9dfe23e28950ac
This commit is contained in:
parent
398ca82b48
commit
e75a209b9f
3 changed files with 59 additions and 3 deletions
|
@ -10329,6 +10329,44 @@ public class AST2TemplateTests extends AST2CPPTestBase {
|
||||||
helper.assertVariableValue("waldo", 42);
|
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>
|
// template <class>
|
||||||
// struct A {
|
// struct A {
|
||||||
// template <class>
|
// template <class>
|
||||||
|
|
|
@ -3260,4 +3260,21 @@ public class CPPTemplates {
|
||||||
}
|
}
|
||||||
return name;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,9 +108,10 @@ public final class EvalFunctionCall extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isValueDependent() {
|
public boolean isValueDependent() {
|
||||||
return containsDependentValue(fArguments);
|
return containsDependentValue(fArguments) ||
|
||||||
|
!CPPTemplates.isFullyInstantiated(resolveFunctionBinding(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isConstantExpression(IASTNode point) {
|
public boolean isConstantExpression(IASTNode point) {
|
||||||
if (!fCheckedIsConstantExpression) {
|
if (!fCheckedIsConstantExpression) {
|
||||||
|
@ -301,7 +302,7 @@ public final class EvalFunctionCall extends CPPDependentEvaluation {
|
||||||
ICPPFunction function = resolveFunctionBinding(context.getPoint());
|
ICPPFunction function = resolveFunctionBinding(context.getPoint());
|
||||||
if (function == null)
|
if (function == null)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
if (!function.isConstexpr())
|
if (!function.isConstexpr())
|
||||||
return EvalFixed.INCOMPLETE;
|
return EvalFixed.INCOMPLETE;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue