diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java index 8700aba8b21..fdd71ce558f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPTemplateResolutionTest.java @@ -2784,4 +2784,67 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa public void testRedeclarationWithUnnamedTemplateParameter_472199() throws Exception { checkBindings(); } + + // template struct _GcdX { + // static const long value = _GcdX<_Ax - 1>::value; + // }; + // + // template<> struct _GcdX<0> { + // static const long value = 0; + // }; + // + // template struct R { + // // static const long value = _Ax; + // }; + // + // template struct Operation { + // static const long _N1 = _R1::value; + // typedef R<_GcdX<_N1>::value> value; + // }; + // + // typedef Operation< R<1> >::value MYTYPE; + + // // empty file + public void testRecursiveTemplateInstantiation_479138a() throws Exception { + // This tests that a template metaprogram whose termination depends on + // its inputs being known, doesn't cause a stack overflow when its + // inputs are not known. + checkBindings(); + } + + // template struct _GcdX { + // static const long value = _GcdX<_Bx, _Ax % _Bx>::value; + // }; + // + // template struct _GcdX<_Ax, 0> { + // static const long value = _Ax; + // }; + // + // template struct _Gcd { + // static const long value = _GcdX<_Ax, _Bx>::value; + // }; + // + // template<> struct _Gcd<0, 0> { + // static const long value = 1; + // }; + // + // template struct R { + // // static const long value = _Ax; + // }; + // + // template struct Operation { + // static const long _N1 = _R1::value; + // typedef R<_Gcd<_N1, _N1>::value> value; + // }; + // + // + // typedef Operation< R<1> >::value MYTYPE; + + // // empty file + public void testRecursiveTemplateInstantiation_479138b() throws Exception { + // This is similar to 479138a, but the metaprogram additionally has + // exponential memory usage when the inputs are unknown and thus + // intermediate results cannot be collapsed into a single value. + checkBindings(); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java index 88217c5a00f..a58c9509a78 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateNonTypeArgument.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IValue; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; +import org.eclipse.cdt.internal.core.dom.parser.Value; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFixed; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalParameterPack; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalTypeId; @@ -36,8 +37,10 @@ public class CPPTemplateNonTypeArgument implements ICPPTemplateArgument { fEvaluation= evaluation; } else { IValue value = evaluation.getValue(point); - // Avoid nesting EvalFixed's as nesting causes the signature to be different. - if (value.getEvaluation() instanceof EvalFixed) { + if (value == Value.ERROR) { + fEvaluation = EvalFixed.INCOMPLETE; + } else if (value.getEvaluation() instanceof EvalFixed) { + // Avoid nesting EvalFixed's as nesting causes the signature to be different. fEvaluation = value.getEvaluation(); } else { fEvaluation= new EvalFixed(evaluation.getTypeOrFunctionSet(point),