mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-20 23:45:23 +02:00
Added protection against NPE and invalid values.
Change-Id: I8b2b96acc9f7852a4857eabb81e4ff35f9e3a0a9
This commit is contained in:
parent
8bdda7bd02
commit
7501266165
7 changed files with 34 additions and 16 deletions
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue