Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathan Ridge2017-08-24 00:35:24 -0400
committerNathan Ridge2017-09-07 01:30:34 -0400
commite75a209b9f5543701b616d71680ce4932b91c8d3 (patch)
tree95b159bd1a8b60a3c9cf6d206989e7dad2c6bc7a
parent398ca82b481015e71b5928c2b83c484fbf1e9b4d (diff)
downloadorg.eclipse.cdt-e75a209b9f5543701b616d71680ce4932b91c8d3.tar.gz
org.eclipse.cdt-e75a209b9f5543701b616d71680ce4932b91c8d3.tar.xz
org.eclipse.cdt-e75a209b9f5543701b616d71680ce4932b91c8d3.zip
Bug 521274 - Defer execution of constexpr function body until function is fully instantiated
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java38
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java17
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalFunctionCall.java7
3 files changed, 59 insertions, 3 deletions
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 <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>
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;

Back to the top