mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
Bug 429891 - Limit the total number of computation steps in a constexpr
evaluation Change-Id: I057d94a78e92d26c9ad824b2ea0c6a4ad896e948 Signed-off-by: Nathan Ridge <zeratul976@hotmail.com> Reviewed-on: https://git.eclipse.org/r/24925 Tested-by: Hudson CI Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com> Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
parent
ec10b77e67
commit
d66e5c04bf
18 changed files with 110 additions and 46 deletions
|
@ -8490,4 +8490,22 @@ public class AST2TemplateTests extends AST2TestBase {
|
||||||
IVariable waldo = helper.assertNonProblem("waldo");
|
IVariable waldo = helper.assertNonProblem("waldo");
|
||||||
assertEquals(5, waldo.getInitialValue().numericalValue().longValue());
|
assertEquals(5, waldo.getInitialValue().numericalValue().longValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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(50);
|
||||||
|
public void testConstexprEvaluationLimit_429891() throws Exception {
|
||||||
|
// Here we're just checking that the computation of the initial
|
||||||
|
// value finishes (with a null result) in a reasonable time.
|
||||||
|
// If we tried to run the computation of naive_fibonacci(50)
|
||||||
|
// to its end, the IDE would appear to hang.
|
||||||
|
BindingAssertionHelper helper = getAssertionHelper();
|
||||||
|
IVariable waldo = helper.assertNonProblem("waldo");
|
||||||
|
assertNull(waldo.getInitialValue().numericalValue());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,16 +85,62 @@ public interface ICPPEvaluation extends ISerializableEvaluation {
|
||||||
ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
|
ICPPEvaluation instantiate(ICPPTemplateParameterMap tpMap, int packOffset,
|
||||||
ICPPClassSpecialization within, int maxdepth, IASTNode point);
|
ICPPClassSpecialization within, int maxdepth, IASTNode point);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keeps track of state during a constexpr evaluation.
|
||||||
|
*/
|
||||||
|
class ConstexprEvaluationContext {
|
||||||
|
/**
|
||||||
|
* The maximum number of steps allowed in a single constexpr evaluation.
|
||||||
|
* This is used to prevent a buggy constexpr function from causing the
|
||||||
|
* IDE to hang.
|
||||||
|
*/
|
||||||
|
public static final int MAX_CONSTEXPR_EVALUATION_STEPS = 1024;
|
||||||
|
|
||||||
|
private int fStepsPerformed;
|
||||||
|
private IASTNode fPoint;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a ConstexprEvaluationContext for a new constexpr evaluation.
|
||||||
|
* @param point the point of instantiation, determines the scope for name lookups
|
||||||
|
*/
|
||||||
|
public ConstexprEvaluationContext(IASTNode point) {
|
||||||
|
fStepsPerformed = 0;
|
||||||
|
fPoint = point;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record a new step being performed in this constexpr evaluation.
|
||||||
|
* @return this constexpr evaluation
|
||||||
|
*/
|
||||||
|
public ConstexprEvaluationContext recordStep() {
|
||||||
|
++fStepsPerformed;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of steps performed so far in the constexpr evaluation.
|
||||||
|
*/
|
||||||
|
public int getStepsPerformed() {
|
||||||
|
return fStepsPerformed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the point of instantiation.
|
||||||
|
*/
|
||||||
|
public IASTNode getPoint() {
|
||||||
|
return fPoint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the evaluation produced by substituting function parameters by their values.
|
* Computes the evaluation produced by substituting function parameters by their values.
|
||||||
*
|
*
|
||||||
* @param parameterMap maps function parameters to their values
|
* @param parameterMap maps function parameters to their values
|
||||||
* @param maxdepth allowed recursion depth
|
* @param context the context for the current constexpr evaluation
|
||||||
* @param point the point of instantiation, determines the scope for name lookups
|
|
||||||
* @return the computed evaluation
|
* @return the computed evaluation
|
||||||
*/
|
*/
|
||||||
ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap, int maxdepth,
|
ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
IASTNode point);
|
ConstexprEvaluationContext context);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches the evaluation for a usage of a template parameter which is a parameter pack,
|
* Searches the evaluation for a usage of a template parameter which is a parameter pack,
|
||||||
|
|
|
@ -366,9 +366,9 @@ public class EvalBinary extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
int maxdepth, IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
ICPPEvaluation arg1 = fArg1.computeForFunctionCall(parameterMap, maxdepth, point);
|
ICPPEvaluation arg1 = fArg1.computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
ICPPEvaluation arg2 = fArg2.computeForFunctionCall(parameterMap, maxdepth, point);
|
ICPPEvaluation arg2 = fArg2.computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
if (arg1 == fArg1 && arg2 == fArg2)
|
if (arg1 == fArg1 && arg2 == fArg2)
|
||||||
return this;
|
return this;
|
||||||
return new EvalBinary(fOperator, arg1, arg2, getTemplateDefinition());
|
return new EvalBinary(fOperator, arg1, arg2, getTemplateDefinition());
|
||||||
|
|
|
@ -142,7 +142,7 @@ public class EvalBinaryTypeId extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
int maxdepth, IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -405,7 +405,7 @@ public class EvalBinding extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
int maxdepth, IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
int pos = getFunctionParameterPosition();
|
int pos = getFunctionParameterPosition();
|
||||||
if (pos >= 0) {
|
if (pos >= 0) {
|
||||||
ICPPEvaluation eval = parameterMap.getArgument(pos);
|
ICPPEvaluation eval = parameterMap.getArgument(pos);
|
||||||
|
|
|
@ -204,10 +204,10 @@ public class EvalComma extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
int maxdepth, IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
ICPPEvaluation[] args = fArguments;
|
ICPPEvaluation[] args = fArguments;
|
||||||
for (int i = 0; i < fArguments.length; i++) {
|
for (int i = 0; i < fArguments.length; i++) {
|
||||||
ICPPEvaluation arg = fArguments[i].computeForFunctionCall(parameterMap, maxdepth, point);
|
ICPPEvaluation arg = fArguments[i].computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
if (arg != fArguments[i]) {
|
if (arg != fArguments[i]) {
|
||||||
if (args == fArguments) {
|
if (args == fArguments) {
|
||||||
args = new ICPPEvaluation[fArguments.length];
|
args = new ICPPEvaluation[fArguments.length];
|
||||||
|
|
|
@ -109,8 +109,8 @@ public class EvalCompound extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
int maxdepth, IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
ICPPEvaluation delegate = fDelegate.computeForFunctionCall(parameterMap, maxdepth, point);
|
ICPPEvaluation delegate = fDelegate.computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
if (delegate == fDelegate)
|
if (delegate == fDelegate)
|
||||||
return this;
|
return this;
|
||||||
return new EvalCompound(delegate, getTemplateDefinition());
|
return new EvalCompound(delegate, getTemplateDefinition());
|
||||||
|
|
|
@ -354,23 +354,23 @@ public class EvalConditional extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
int maxdepth, IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
ICPPEvaluation condition = fCondition.computeForFunctionCall(parameterMap, maxdepth, point);
|
ICPPEvaluation condition = fCondition.computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
// If the condition can be evaluated, fold the conditional into
|
// If the condition can be evaluated, fold the conditional into
|
||||||
// just the branch that is taken. This avoids infinite recursion
|
// just the branch that is taken. This avoids infinite recursion
|
||||||
// when computing a recursive constexpr function where the base
|
// when computing a recursive constexpr function where the base
|
||||||
// case of the recursion is one of the branches of the conditional.
|
// case of the recursion is one of the branches of the conditional.
|
||||||
Long conditionValue = condition.getValue(point).numericalValue();
|
Long conditionValue = condition.getValue(context.getPoint()).numericalValue();
|
||||||
if (conditionValue != null) {
|
if (conditionValue != null) {
|
||||||
if (conditionValue.longValue() != 0) {
|
if (conditionValue.longValue() != 0) {
|
||||||
return fPositive == null ? null : fPositive.computeForFunctionCall(parameterMap, maxdepth, point);
|
return fPositive == null ? null : fPositive.computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
} else {
|
} else {
|
||||||
return fNegative.computeForFunctionCall(parameterMap, maxdepth, point);
|
return fNegative.computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ICPPEvaluation positive = fPositive == null ?
|
ICPPEvaluation positive = fPositive == null ?
|
||||||
null : fPositive.computeForFunctionCall(parameterMap, maxdepth, point);
|
null : fPositive.computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
ICPPEvaluation negative = fNegative.computeForFunctionCall(parameterMap, maxdepth, point);
|
ICPPEvaluation negative = fNegative.computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
if (condition == fCondition && positive == fPositive && negative == fNegative)
|
if (condition == fCondition && positive == fPositive && negative == fNegative)
|
||||||
return this;
|
return this;
|
||||||
return new EvalConditional(condition, positive, negative, fPositiveThrows, fNegativeThrows, getTemplateDefinition());
|
return new EvalConditional(condition, positive, negative, fPositiveThrows, fNegativeThrows, getTemplateDefinition());
|
||||||
|
|
|
@ -175,11 +175,11 @@ public class EvalFixed extends CPPEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
int maxdepth, IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
ICPPEvaluation eval = fValue.getEvaluation();
|
ICPPEvaluation eval = fValue.getEvaluation();
|
||||||
if (eval == null)
|
if (eval == null)
|
||||||
return this;
|
return this;
|
||||||
eval = eval.computeForFunctionCall(parameterMap, maxdepth, point);
|
eval = eval.computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
if (eval == fValue.getEvaluation())
|
if (eval == fValue.getEvaluation())
|
||||||
return this;
|
return this;
|
||||||
return new EvalFixed(fType, fValueCategory, Value.create(eval));
|
return new EvalFixed(fType, fValueCategory, Value.create(eval));
|
||||||
|
|
|
@ -145,7 +145,7 @@ public class EvalFunctionCall extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IValue getValue(IASTNode point) {
|
public IValue getValue(IASTNode point) {
|
||||||
ICPPEvaluation eval = computeForFunctionCall(Value.MAX_RECURSION_DEPTH, point);
|
ICPPEvaluation eval = computeForFunctionCall(new ConstexprEvaluationContext(point));
|
||||||
if (eval == this) {
|
if (eval == this) {
|
||||||
return Value.create(eval);
|
return Value.create(eval);
|
||||||
}
|
}
|
||||||
|
@ -205,13 +205,13 @@ public class EvalFunctionCall extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
int maxdepth, IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
if (maxdepth == 0)
|
if (context.getStepsPerformed() >= ConstexprEvaluationContext.MAX_CONSTEXPR_EVALUATION_STEPS)
|
||||||
return EvalFixed.INCOMPLETE;
|
return EvalFixed.INCOMPLETE;
|
||||||
|
|
||||||
ICPPEvaluation[] args = fArguments;
|
ICPPEvaluation[] args = fArguments;
|
||||||
for (int i = 0; i < fArguments.length; i++) {
|
for (int i = 0; i < fArguments.length; i++) {
|
||||||
ICPPEvaluation arg = fArguments[i].computeForFunctionCall(parameterMap, maxdepth, point);
|
ICPPEvaluation arg = fArguments[i].computeForFunctionCall(parameterMap, context);
|
||||||
if (arg != fArguments[i]) {
|
if (arg != fArguments[i]) {
|
||||||
if (args == fArguments) {
|
if (args == fArguments) {
|
||||||
args = new ICPPEvaluation[fArguments.length];
|
args = new ICPPEvaluation[fArguments.length];
|
||||||
|
@ -223,17 +223,17 @@ public class EvalFunctionCall extends CPPDependentEvaluation {
|
||||||
EvalFunctionCall eval = this;
|
EvalFunctionCall eval = this;
|
||||||
if (args != fArguments)
|
if (args != fArguments)
|
||||||
eval = new EvalFunctionCall(args, getTemplateDefinition());
|
eval = new EvalFunctionCall(args, getTemplateDefinition());
|
||||||
return eval.computeForFunctionCall(maxdepth - 1, point);
|
return eval.computeForFunctionCall(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ICPPEvaluation computeForFunctionCall(int maxdepth, IASTNode point) {
|
private ICPPEvaluation computeForFunctionCall(ConstexprEvaluationContext context) {
|
||||||
if (isValueDependent())
|
if (isValueDependent())
|
||||||
return this;
|
return this;
|
||||||
// If the arguments are not all constant expressions, there is
|
// If the arguments are not all constant expressions, there is
|
||||||
// no point trying to substitute them into the return expression.
|
// no point trying to substitute them into the return expression.
|
||||||
if (!areAllConstantExpressions(fArguments, point))
|
if (!areAllConstantExpressions(fArguments, context.getPoint()))
|
||||||
return this;
|
return this;
|
||||||
ICPPFunction function = getOverload(point);
|
ICPPFunction function = getOverload(context.getPoint());
|
||||||
if (function == null) {
|
if (function == null) {
|
||||||
if (fArguments[0] instanceof EvalBinding) {
|
if (fArguments[0] instanceof EvalBinding) {
|
||||||
IBinding binding = ((EvalBinding) fArguments[0]).getBinding();
|
IBinding binding = ((EvalBinding) fArguments[0]).getBinding();
|
||||||
|
@ -247,7 +247,7 @@ public class EvalFunctionCall extends CPPDependentEvaluation {
|
||||||
if (eval == null)
|
if (eval == null)
|
||||||
return EvalFixed.INCOMPLETE;
|
return EvalFixed.INCOMPLETE;
|
||||||
CPPFunctionParameterMap parameterMap = buildParameterMap(function);
|
CPPFunctionParameterMap parameterMap = buildParameterMap(function);
|
||||||
return eval.computeForFunctionCall(parameterMap, maxdepth, point);
|
return eval.computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
}
|
}
|
||||||
|
|
||||||
private CPPFunctionParameterMap buildParameterMap(ICPPFunction function) {
|
private CPPFunctionParameterMap buildParameterMap(ICPPFunction function) {
|
||||||
|
|
|
@ -266,7 +266,7 @@ public class EvalFunctionSet extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
int maxdepth, IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -362,10 +362,10 @@ public class EvalID extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
int maxdepth, IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
if (fFieldOwner == null)
|
if (fFieldOwner == null)
|
||||||
return this;
|
return this;
|
||||||
ICPPEvaluation fieldOwner = fFieldOwner.computeForFunctionCall(parameterMap, maxdepth, point);
|
ICPPEvaluation fieldOwner = fFieldOwner.computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
if (fieldOwner == fFieldOwner)
|
if (fieldOwner == fFieldOwner)
|
||||||
return this;
|
return this;
|
||||||
return new EvalID(fieldOwner, fNameOwner, fName, fAddressOf, fQualified, fTemplateArgs, getTemplateDefinition());
|
return new EvalID(fieldOwner, fNameOwner, fName, fAddressOf, fQualified, fTemplateArgs, getTemplateDefinition());
|
||||||
|
|
|
@ -119,10 +119,10 @@ public class EvalInitList extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
int maxdepth, IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
ICPPEvaluation[] clauses = fClauses;
|
ICPPEvaluation[] clauses = fClauses;
|
||||||
for (int i = 0; i < fClauses.length; i++) {
|
for (int i = 0; i < fClauses.length; i++) {
|
||||||
ICPPEvaluation clause = fClauses[i].computeForFunctionCall(parameterMap, maxdepth, point);
|
ICPPEvaluation clause = fClauses[i].computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
if (clause != fClauses[i]) {
|
if (clause != fClauses[i]) {
|
||||||
if (clauses == fClauses) {
|
if (clauses == fClauses) {
|
||||||
clauses = new ICPPEvaluation[fClauses.length];
|
clauses = new ICPPEvaluation[fClauses.length];
|
||||||
|
|
|
@ -355,7 +355,7 @@ public class EvalMemberAccess extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
int maxdepth, IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,8 +105,8 @@ public class EvalParameterPack extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
int maxdepth, IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
ICPPEvaluation expansionPattern = fExpansionPattern.computeForFunctionCall(parameterMap, maxdepth, point);
|
ICPPEvaluation expansionPattern = fExpansionPattern.computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
if (expansionPattern == fExpansionPattern)
|
if (expansionPattern == fExpansionPattern)
|
||||||
return this;
|
return this;
|
||||||
return new EvalParameterPack(expansionPattern, getTemplateDefinition());
|
return new EvalParameterPack(expansionPattern, getTemplateDefinition());
|
||||||
|
|
|
@ -239,11 +239,11 @@ public class EvalTypeId extends CPPDependentEvaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap, int maxdepth,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
ICPPEvaluation[] args = fArguments;
|
ICPPEvaluation[] args = fArguments;
|
||||||
for (int i = 0; i < fArguments.length; i++) {
|
for (int i = 0; i < fArguments.length; i++) {
|
||||||
ICPPEvaluation arg = fArguments[i].computeForFunctionCall(parameterMap, maxdepth, point);
|
ICPPEvaluation arg = fArguments[i].computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
if (arg != fArguments[i]) {
|
if (arg != fArguments[i]) {
|
||||||
if (args == fArguments) {
|
if (args == fArguments) {
|
||||||
args = new ICPPEvaluation[fArguments.length];
|
args = new ICPPEvaluation[fArguments.length];
|
||||||
|
|
|
@ -345,9 +345,9 @@ public class EvalUnary extends CPPDependentEvaluation {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap, int maxdepth,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
ICPPEvaluation argument = fArgument.computeForFunctionCall(parameterMap, maxdepth, point);
|
ICPPEvaluation argument = fArgument.computeForFunctionCall(parameterMap, context.recordStep());
|
||||||
if (argument == fArgument)
|
if (argument == fArgument)
|
||||||
return this;
|
return this;
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,7 @@ public class EvalUnaryTypeID extends CPPDependentEvaluation {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
public ICPPEvaluation computeForFunctionCall(CPPFunctionParameterMap parameterMap,
|
||||||
int maxdepth, IASTNode point) {
|
ConstexprEvaluationContext context) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue