1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-21 16:05:25 +02:00

Added protection against NPE and invalid values.

Change-Id: I8b2b96acc9f7852a4857eabb81e4ff35f9e3a0a9
This commit is contained in:
Sergey Prigogin 2017-03-09 18:34:27 -08:00
parent 8bdda7bd02
commit 7501266165
7 changed files with 34 additions and 16 deletions

View file

@ -297,12 +297,14 @@ public class ValueFactory {
if (isInvalidValue(v))
return v;
if (isDeferredValue(v))
return null; // the value will be computed using the evaluation
if (v.numberValue().longValue() == 0) {
return null; // The value will be computed using the evaluation.
Number numericValue = v.numberValue();
if (numericValue == null)
return IntegralValue.UNKNOWN;
if (v instanceof IntegralValue ? numericValue.longValue() == 0 : numericValue.doubleValue() == 0)
return evaluate(cexpr.getNegativeResultExpression());
}
final IASTExpression pe = cexpr.getPositiveResultExpression();
if (pe == null) // gnu-extension allows to omit the positive expression.
if (pe == null) // A gnu-extension allows to omit the positive expression.
return v;
return evaluate(pe);
}

View file

@ -11,7 +11,7 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.*;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_assign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryAnd;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryAndAssign;
import static org.eclipse.cdt.core.dom.ast.IASTBinaryExpression.op_binaryOr;
@ -461,6 +461,8 @@ public class EvalBinary extends CPPDependentEvaluation {
return EvalFixed.INCOMPLETE;
}
} else {
if (updateable1 == EvalFixed.INCOMPLETE)
return EvalFixed.INCOMPLETE;
int binaryOperator = getBinaryOperatorWithoutAssignment(fOperator);
EvalBinary binaryOpEval = new EvalBinary(binaryOperator, fixed1, fixed2, getTemplateDefinition());
EvalBinary assignmentEval = new EvalBinary(op_assign, updateable1, binaryOpEval, getTemplateDefinition());
@ -486,7 +488,10 @@ public class EvalBinary extends CPPDependentEvaluation {
}
return updateable1;
} else if (fOperator == op_arrayAccess) {
return new EvalCompositeAccess(fixed1, fixed2.getValue(context.getPoint()).numberValue().intValue());
Number numericValue = fixed2.getValue(context.getPoint()).numberValue();
if (numericValue == null)
return EvalFixed.INCOMPLETE;
return new EvalCompositeAccess(fixed1, numericValue.intValue());
} else if ((isArray(fixed1, context) || isArray(fixed2, context)) && (hasIntType(fixed1, context) || hasIntType(fixed2, context))) {
int offset = hasIntType(fixed1, context) ? fixed1.getValue(context.getPoint()).numberValue().intValue() : fixed2.getValue(context.getPoint()).numberValue().intValue();
EvalCompositeAccess evalCompositeAccess = new EvalCompositeAccess(isArray(fixed1, context) ? fixed1 : fixed2, offset);

View file

@ -29,6 +29,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.EvalFunctionCall.ParameterPackType;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
/**
@ -40,6 +41,7 @@ public final class EvalCompositeAccess implements ICPPEvaluation {
private final int elementId; // The index of the sub-value being accessed
public EvalCompositeAccess(ICPPEvaluation parent, int elementId) {
Assert.isNotNull(parent);
this.parent = parent;
this.elementId = elementId;
}

View file

@ -45,6 +45,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPExecution;
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics.LookupMode;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
public final class EvalFunctionCall extends CPPDependentEvaluation {
@ -58,6 +59,9 @@ public final class EvalFunctionCall extends CPPDependentEvaluation {
public EvalFunctionCall(ICPPEvaluation[] args, ICPPEvaluation owner, IBinding templateDefinition) {
super(templateDefinition);
for (int i = 0; i < args.length; i++) {
Assert.isNotNull(args[i]);
}
fArguments = args;
fImplicitThis = getImplicitThis() == owner ? null : owner;
}
@ -247,14 +251,15 @@ public final class EvalFunctionCall extends CPPDependentEvaluation {
IBinding binding = evalBinding.getBinding();
// If the binding being referenced isn't present in the activation record,
// we won't be able to evaluate the function call.
if (record.getVariable(binding) == null) {
if (record.getVariable(binding) == null)
return EvalFixed.INCOMPLETE;
}
arg = new EvalReference(record, binding, evalBinding.getTemplateDefinition());
} 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);
}
if (arg == EvalFixed.INCOMPLETE)
return EvalFixed.INCOMPLETE;
args[i] = arg;
}

View file

@ -23,6 +23,8 @@ import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUti
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers;
import java.util.Collection;
import org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
@ -56,8 +58,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics.LookupMode;
import org.eclipse.core.runtime.CoreException;
import java.util.Collection;
public class EvalMemberAccess extends CPPDependentEvaluation {
private final IType fOwnerType;
private final IBinding fMember;
@ -430,7 +430,7 @@ public class EvalMemberAccess extends CPPDependentEvaluation {
EvalBinding evalBinding = new EvalBinding(fMember, fType, getTemplateDefinition());
return evalBinding;
}
if (ownerEval == null) {
if (ownerEval == null || ownerEval == this) {
return this;
}

View file

@ -428,8 +428,10 @@ public class EvalUnary extends CPPDependentEvaluation {
} else if (updateable instanceof EvalBinding && isStarOperatorOnArrayName(context)) {
EvalBinding evalBinding = (EvalBinding) updateable;
IBinding binding = evalBinding.getBinding();
ICPPEvaluation value = record.getVariable(binding);
EvalCompositeAccess compositeAccess = new EvalCompositeAccess(value, 0);
ICPPEvaluation eval = record.getVariable(binding);
if (eval == null)
return EvalFixed.INCOMPLETE;
EvalCompositeAccess compositeAccess = new EvalCompositeAccess(eval, 0);
return new EvalReference(record, compositeAccess, getTemplateDefinition());
}
return evalUnary;

View file

@ -124,7 +124,9 @@ public class EvalUtil {
updateable = eval;
}
ICPPEvaluation fixed = eval.computeForFunctionCall(record, context.recordStep());
if (isUpdateable(fixed)) {
if (fixed == EvalFixed.INCOMPLETE) {
updateable = fixed;
} else if (isUpdateable(fixed)) {
updateable = fixed;
if (!(fixed instanceof EvalCompositeAccess)) {
fixed = fixed.computeForFunctionCall(record, context);
@ -169,7 +171,7 @@ public class EvalUtil {
IType nestedType = SemanticUtil.getNestedType(type, TDEF | REF | CVTYPE);
IValue initialValue = variable.getInitialValue();
ICPPEvaluation valueEval = null;
if ((initialValue != null && initialValue.getEvaluation() != null) ||
(initialValue == null && nestedType instanceof ICPPClassType)) {
final ICPPEvaluation initializerEval = initialValue == null ? null : initialValue.getEvaluation();
@ -185,7 +187,7 @@ public class EvalUtil {
} else if (initialValue != null) {
valueEval = new EvalFixed(type, ValueCategory.LVALUE, initialValue);
}
if (valueEval != null && (valueEval == EvalFixed.INCOMPLETE ||
valueEval.getValue(point) == IntegralValue.UNKNOWN)) {
return null;