From 2d02ddf8ca966becf685959fbc32afab5140b318 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Mon, 10 Oct 2016 18:46:14 -0700 Subject: [PATCH] Bug 505606 - OutOfMemoryError in indexer Change-Id: Ibcff4aa82cf46f0ec01705715b98f881cb39dca5 --- .../ast2/constexprevaluation/FunctionTests.java | 16 ++++++++++++++++ .../core/dom/parser/cpp/CPPVariable.java | 3 +++ .../parser/cpp/semantics/EvalConstructor.java | 10 ++++++---- .../parser/cpp/semantics/EvalFunctionCall.java | 14 ++++++++------ .../dom/parser/cpp/semantics/EvalReference.java | 3 ++- 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/constexprevaluation/FunctionTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/constexprevaluation/FunctionTests.java index e76e9c8697b..f4f9b13facb 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/constexprevaluation/FunctionTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/constexprevaluation/FunctionTests.java @@ -245,4 +245,20 @@ public class FunctionTests extends TestBase { ICPPExecution bodyExec = CPPFunction.getFunctionBodyExecution(function, clause); assertNull(bodyExec); } + + // // Empty header file + + // struct A { + // A() {} + // A& m(int p) { + // return *this; + // } + // }; + // + // A a = A() + // .m(1).m(2).m(3).m(4).m(5).m(6).m(7).m(8).m(9).m(10) + // .m(11).m(12).m(13).m(14).m(15).m(16).m(17).m(18).m(19).m(20) + // .m(21).m(22).m(23).m(24).m(25).m(26).m(27).m(28).m(29).m(30); + public void testLongCallChain_505606() throws Exception { + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java index 707d3d9bb04..623ae3f724d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVariable.java @@ -243,6 +243,9 @@ public class CPPVariable extends PlatformObject implements ICPPInternalVariable if (initEval == null) { return null; } + if (!initEval.isValueDependent() ) { + return initEval.getValue(fDefinition); + } return IntegralValue.create(initEval); } return initialValue; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConstructor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConstructor.java index d7c655e9881..553fe9ef0dd 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConstructor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalConstructor.java @@ -119,10 +119,12 @@ public final class EvalConstructor extends CPPDependentEvaluation { @Override public IValue getValue(IASTNode point) { - // An EvalConstructor is never used to directly represent the evaluation of an expression. - // It only comes up while evaluating other evaluations. As such, its getValue() doesn't - // do anything; computeForFunctionCall() must be called on it to obtain a useful result. - return IntegralValue.ERROR; + ICPPEvaluation computed = + computeForFunctionCall(new ActivationRecord(), new ConstexprEvaluationContext(point)); + if (computed == this) + return IntegralValue.ERROR; + + return computed.getValue(point); } @Override 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 df3cf4620e8..f95477dd920 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 @@ -230,7 +230,7 @@ public final class EvalFunctionCall extends CPPDependentEvaluation { ICPPParameter[] parameters = functionBinding.getParameters(); for (int i = 0; i < fArguments.length; i++) { ICPPEvaluation arg = fArguments[i].computeForFunctionCall(record, context.recordStep()); - if (i != 0 && isReference(parameters[i-1]) && fArguments[i] instanceof EvalBinding) { + if (0 < i && i <= parameters.length && isReference(parameters[i - 1]) && fArguments[i] instanceof EvalBinding) { final EvalBinding evalBinding = (EvalBinding) fArguments[i]; IBinding binding = evalBinding.getBinding(); // If the binding being referenced isn't present in the activation record, @@ -239,7 +239,7 @@ public final class EvalFunctionCall extends CPPDependentEvaluation { return EvalFixed.INCOMPLETE; } arg = new EvalReference(record, binding, evalBinding.getTemplateDefinition()); - } else if (i != 0 && !isReference(parameters[i-1])) { + } else if (0 < i && i <= parameters.length && !isReference(parameters[i - 1])) { IValue copiedValue = arg.getValue(context.getPoint()).clone(); arg = new EvalFixed(arg.getType(context.getPoint()), arg.getValueCategory(context.getPoint()), copiedValue); } @@ -272,13 +272,15 @@ public final class EvalFunctionCall extends CPPDependentEvaluation { // If the arguments are not all constant expressions, there is // no point trying to substitute them into the return expression. - if (!areAllConstantExpressions(fArguments, 1, fArguments.length, context.getPoint())) { + if (!areAllConstantExpressions(fArguments, 1, fArguments.length, context.getPoint())) return EvalFixed.INCOMPLETE; - } + ICPPFunction function = resolveFunctionBinding(context.getPoint()); - if (function == null) { + if (function == null) return this; - } + + if (!function.isConstexpr()) + return EvalFixed.INCOMPLETE; ActivationRecord record = createActivationRecord(function.getParameters(), fArguments, fImplicitThis, context.getPoint()); ICPPExecution bodyExec = CPPFunction.getFunctionBodyExecution(function, context.getPoint()); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalReference.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalReference.java index 74c685a4d3f..d7797b2cd8d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalReference.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalReference.java @@ -88,7 +88,8 @@ public class EvalReference extends CPPDependentEvaluation { if (referredSubValue != null) { return referredSubValue; } - return owningRecord.getVariable(referredBinding); + ICPPEvaluation targetValue = owningRecord.getVariable(referredBinding); + return targetValue == null ? EvalFixed.INCOMPLETE : targetValue; } public void update(ICPPEvaluation eval) {