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 2e0ba985b97..94f8aa1a713 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 @@ -8477,4 +8477,17 @@ public class AST2TemplateTests extends AST2TestBase { public void testConstexprFunctionCallWithNonConstexprArguments_429891() throws Exception { parseAndCheckBindings(); } + + // constexpr int naive_fibonacci(int x) { + // return x == 0 ? 0 + // : x == 1 ? 1 + // : naive_fibonacci(x - 2) + naive_fibonacci(x - 1); + // } + // + // constexpr int waldo = naive_fibonacci(5); + public void testConditionalExpressionFolding_429891() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + IVariable waldo = helper.assertNonProblem("waldo"); + assertEquals(5, waldo.getInitialValue().numericalValue().longValue()); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java index 9216b7ef7fd..822ea150963 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConditional.java @@ -356,6 +356,18 @@ public class EvalConditional extends CPPDependentEvaluation { public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap, int maxdepth, IASTNode point) { ICPPEvaluation condition = fCondition.computeForFunctionCall(parameterMap, maxdepth, point); + // If the condition can be evaluated, fold the conditional into + // just the branch that is taken. This avoids infinite recursion + // when computing a recursive constexpr function where the base + // case of the recursion is one of the branches of the conditional. + Long conditionValue = condition.getValue(point).numericalValue(); + if (conditionValue != null) { + if (conditionValue.longValue() != 0) { + return fPositive == null ? null : fPositive.computeForFunctionCall(parameterMap, maxdepth, point); + } else { + return fNegative.computeForFunctionCall(parameterMap, maxdepth, point); + } + } ICPPEvaluation positive = fPositive == null ? null : fPositive.computeForFunctionCall(parameterMap, maxdepth, point); ICPPEvaluation negative = fNegative.computeForFunctionCall(parameterMap, maxdepth, point);