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

Bug 497875 - Indexer runs out of memory with recursive template

functions

Change-Id: I1b92d57fc13f61933082185b397e63cf7d9b69a6
This commit is contained in:
Sergey Prigogin 2016-07-13 20:47:54 -07:00
parent b7ecc46eca
commit b47514f94a
3 changed files with 71 additions and 6 deletions

View file

@ -2375,9 +2375,9 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
// B<bool>::type x;
// B<int*>::type y;
public void testConstexprFunction_395238_2() throws Exception {
ITypedef td = getBindingFromASTName("type x", 4, ITypedef.class);
ITypedef td = getBindingFromFirstIdentifier("type x", ITypedef.class);
assertEquals("bool", ASTTypeUtil.getType(td.getType()));
getProblemFromASTName("type y", 4);
getProblemFromFirstIdentifier("type y");
}
// template <class RandomAccessRange, class BinaryPredicate>
@ -2536,6 +2536,51 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
checkBindings();
}
// // Empty header.
// template <typename T, T v>
// constexpr T a() { return v; }
//
// template <typename T>
// constexpr T A(T n, int i, T j = 1) {
// return (i < 1) ? j : (i == 1) ? n * j : A<T>(n * n, i / 2, (i % 2) ? j * n : j);
// }
//
// template <int I, int J, int K, typename T>
// struct B {
// static constexpr int b(T n);
// };
//
// template <int I, int J, typename T>
// struct B<I, J, J, T> {
// static constexpr int b(T n) {
// return J;
// }
// };
//
// template <int I, int J, int K, typename T>
// constexpr int B<I, J, K, T>::b(T n) {
// return (n < a<T, A<T>(I, (J + K) / 2)>()) ?
// B<I, J, (J + K) / 2, T>::b(n) :
// B<I, (J + K) / 2 + 1, K, T>::b(n);
// }
//
// template <int I, typename T>
// constexpr int C(T v = 2000000000) {
// return v < I ? 1 : 1 + C<I, T>(v / I);
// }
//
// template <int I, typename T>
// constexpr int D(T n) {
// return B<I, 1, C<I, T>(), T>::b(n);
// }
//
// static_assert(D<10>(1000000000) == 10, "");
public void testOOM_497875() throws Exception {
// TODO(sprigogin): Uncomment after http://bugs.eclipse.org/497931 is fixed.
// checkBindings();
}
// template <typename>
// struct basic_A {
// bool eof() const;
@ -2664,7 +2709,7 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
// constexpr int waldo = foo<int>();
public void testInstantiationOfReturnExpression_484959() throws Exception {
ICPPVariable waldo = getBindingFromASTName("waldo", 5);
ICPPVariable waldo = getBindingFromFirstIdentifier("waldo");
assertVariableValue(waldo, 42);
}

View file

@ -30,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.IValue;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
@ -242,9 +243,24 @@ public class EvalFunctionCall extends CPPDependentEvaluation {
}
if (function == null)
return this;
ICPPEvaluation eval = CPPFunction.getReturnExpression(function, context.getPoint());
if (eval == null)
return EvalFixed.INCOMPLETE;
if (eval == null) {
if (!(function instanceof ICPPTemplateInstance)
|| ((ICPPTemplateInstance) function).isExplicitSpecialization()) {
return EvalFixed.INCOMPLETE;
}
ICPPTemplateInstance functionInstance = (ICPPTemplateInstance) function;
IBinding specialized = functionInstance.getSpecializedBinding();
if (!(specialized instanceof ICPPFunction))
return this;
eval = CPPFunction.getReturnExpression((ICPPFunction) specialized, context.getPoint());
if (eval == null)
return EvalFixed.INCOMPLETE;
InstantiationContext instantiationContext =
new InstantiationContext(functionInstance.getTemplateParameterMap(), context.getPoint());
return eval.instantiate(instantiationContext, Value.MAX_RECURSION_DEPTH);
}
CPPFunctionParameterMap parameterMap = buildParameterMap(function, context.getPoint());
return eval.computeForFunctionCall(parameterMap, context.recordStep());
}

View file

@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.internal.core.dom.parser.ProblemFunctionType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPComputableFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
@ -130,7 +131,10 @@ class PDOMCPPFunctionSpecialization extends PDOMCPPSpecialization
typelist = PDOMCPPTypeList.putTypes(this, astFunction.getExceptionSpecification());
}
db.putRecPtr(record + EXCEPTION_SPEC, typelist);
linkage.new ConfigureFunctionSpecialization(astFunction, this, point);
if (!(astFunction instanceof ICPPTemplateInstance)
|| ((ICPPTemplateInstance) astFunction).isExplicitSpecialization()) {
linkage.new ConfigureFunctionSpecialization(astFunction, this, point);
}
}
private short getAnnotation(ICPPFunction astFunction) {