mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-31 12:55:40 +02:00
Fix type conversion in unary and binary expression evaluations.
This commit is contained in:
parent
09ab420f17
commit
c0220469ad
4 changed files with 53 additions and 23 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009, 2015 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2009, 2015, 2023 Wind River Systems, Inc. and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
|
@ -77,6 +77,14 @@ public abstract class ArithmeticConversion {
|
|||
case IASTBinaryExpression.op_max:
|
||||
case IASTBinaryExpression.op_min:
|
||||
return convert(op1, op2);
|
||||
// Relational operators
|
||||
case IASTBinaryExpression.op_lessEqual:
|
||||
case IASTBinaryExpression.op_lessThan:
|
||||
case IASTBinaryExpression.op_greaterEqual:
|
||||
case IASTBinaryExpression.op_greaterThan:
|
||||
case IASTBinaryExpression.op_equals:
|
||||
case IASTBinaryExpression.op_notequals:
|
||||
return convert(op1, op2);
|
||||
|
||||
case IASTBinaryExpression.op_shiftLeft:
|
||||
case IASTBinaryExpression.op_shiftRight:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008, 2014 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2008, 2014, 2023 Wind River Systems, Inc. and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
|
@ -11,6 +11,7 @@
|
|||
* Contributors:
|
||||
* Markus Schorn - initial API and implementation
|
||||
* Sergey Prigogin (Google)
|
||||
* Igor V. Kovalenko
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.parser;
|
||||
|
||||
|
@ -41,6 +42,7 @@ 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 java.util.Arrays;
|
||||
import java.util.function.LongBinaryOperator;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||
|
@ -52,6 +54,7 @@ import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.ICompositeType;
|
||||
import org.eclipse.cdt.core.dom.ast.IEnumeration;
|
||||
|
@ -92,8 +95,8 @@ public class ValueFactory {
|
|||
return val;
|
||||
}
|
||||
|
||||
if (expr instanceof ICPPASTInitializerClause) {
|
||||
ICPPEvaluation evaluation = ((ICPPASTInitializerClause) expr).getEvaluation();
|
||||
if (expr instanceof ICPPASTInitializerClause clause) {
|
||||
ICPPEvaluation evaluation = clause.getEvaluation();
|
||||
return evaluation.getValue();
|
||||
}
|
||||
return IntegralValue.UNKNOWN;
|
||||
|
@ -102,14 +105,14 @@ public class ValueFactory {
|
|||
}
|
||||
}
|
||||
|
||||
public static IValue evaluateUnaryExpression(final int unaryOp, final IValue value) {
|
||||
IValue val = applyUnaryOperator(unaryOp, value);
|
||||
public static IValue evaluateUnaryExpression(final int unaryOp, final IValue value, final IType type) {
|
||||
IValue val = applyUnaryOperator(unaryOp, value, type);
|
||||
if (isInvalidValue(val))
|
||||
return IntegralValue.UNKNOWN;
|
||||
return val;
|
||||
}
|
||||
|
||||
public static IValue evaluateBinaryExpression(final int op, final IValue v1, final IValue v2) {
|
||||
public static IValue evaluateBinaryExpression(final int op, final IValue v1, final IValue v2, final IType type) {
|
||||
if (v1 instanceof FloatingPointValue && v2 instanceof FloatingPointValue) {
|
||||
FloatingPointValue fv1 = (FloatingPointValue) v1;
|
||||
FloatingPointValue fv2 = (FloatingPointValue) v2;
|
||||
|
@ -125,7 +128,7 @@ public class ValueFactory {
|
|||
} else if (v1 instanceof IntegralValue && v2 instanceof IntegralValue) {
|
||||
IntegralValue iv1 = (IntegralValue) v1;
|
||||
IntegralValue iv2 = (IntegralValue) v2;
|
||||
return applyBinaryOperator(op, iv1.numberValue().longValue(), iv2.numberValue().longValue());
|
||||
return applyBinaryOperator(op, iv1.numberValue().longValue(), iv2.numberValue().longValue(), type);
|
||||
}
|
||||
return IntegralValue.UNKNOWN;
|
||||
}
|
||||
|
@ -184,7 +187,16 @@ public class ValueFactory {
|
|||
}
|
||||
}
|
||||
|
||||
private static IntegralValue applyBinaryOperator(final int op, final long v1, final long v2) {
|
||||
private static IntegralValue applyBinaryOperator(final int op, final long v1, final long v2, final IType type) {
|
||||
if ((v1 < 0 || v2 < 0) && type instanceof IBasicType basicType && basicType.isUnsigned()) {
|
||||
return applyBinaryOperator(op, v1, v2, (x, y) -> Long.compareUnsigned(x, y));
|
||||
} else {
|
||||
return applyBinaryOperator(op, v1, v2, (x, y) -> Long.compare(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
private static IntegralValue applyBinaryOperator(final int op, final long v1, final long v2,
|
||||
LongBinaryOperator comparator) {
|
||||
Long value = null;
|
||||
switch (op) {
|
||||
case IASTBinaryExpression.op_multiply:
|
||||
|
@ -213,20 +225,20 @@ public class ValueFactory {
|
|||
value = v1 >> v2;
|
||||
break;
|
||||
case IASTBinaryExpression.op_lessThan:
|
||||
value = v1 < v2 ? 1l : 0l;
|
||||
value = comparator.applyAsLong(v1, v2) < 0 ? 1l : 0l;
|
||||
break;
|
||||
case IASTBinaryExpression.op_greaterThan:
|
||||
value = v1 > v2 ? 1l : 0l;
|
||||
value = comparator.applyAsLong(v1, v2) > 0 ? 1l : 0l;
|
||||
break;
|
||||
case IASTBinaryExpression.op_lessEqual:
|
||||
value = v1 <= v2 ? 1l : 0l;
|
||||
value = comparator.applyAsLong(v1, v2) <= 0 ? 1l : 0l;
|
||||
break;
|
||||
case IASTBinaryExpression.op_greaterEqual:
|
||||
value = v1 >= v2 ? 1l : 0l;
|
||||
value = comparator.applyAsLong(v1, v2) >= 0 ? 1l : 0l;
|
||||
break;
|
||||
case IASTBinaryExpression.op_threewaycomparison:
|
||||
// TODO: implement for <=>
|
||||
value = v1 < v2 ? -1l : (v1 > v2 ? 1l : 0);
|
||||
value = comparator.applyAsLong(v1, v2);
|
||||
break;
|
||||
case IASTBinaryExpression.op_binaryAnd:
|
||||
value = v1 & v2;
|
||||
|
@ -250,10 +262,10 @@ public class ValueFactory {
|
|||
value = v1 != v2 ? 1l : 0l;
|
||||
break;
|
||||
case IASTBinaryExpression.op_max:
|
||||
value = Math.max(v1, v2);
|
||||
value = comparator.applyAsLong(v1, v2) >= 0 ? v1 : v2;
|
||||
break;
|
||||
case IASTBinaryExpression.op_min:
|
||||
value = Math.min(v1, v2);
|
||||
value = comparator.applyAsLong(v1, v2) <= 0 ? v1 : v2;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -514,10 +526,10 @@ public class ValueFactory {
|
|||
return value;
|
||||
if (isDeferredValue(value))
|
||||
return null; // the value will be computed using the evaluation
|
||||
return applyUnaryOperator(unaryOp, value);
|
||||
return applyUnaryOperator(unaryOp, value, exp.getExpressionType());
|
||||
}
|
||||
|
||||
private static IValue applyUnaryOperator(final int unaryOp, final IValue value) {
|
||||
private static IValue applyUnaryOperator(final int unaryOp, final IValue value, final IType type) {
|
||||
if (isInvalidValue(value) || value.numberValue() == null) {
|
||||
return IntegralValue.UNKNOWN;
|
||||
}
|
||||
|
@ -548,6 +560,15 @@ public class ValueFactory {
|
|||
}
|
||||
case IASTUnaryExpression.op_minus:
|
||||
if (value instanceof IntegralValue) {
|
||||
if (type instanceof IBasicType basicType && basicType.isUnsigned()) {
|
||||
SizeAndAlignment sizeAndAlignment = SizeofCalculator.getSizeAndAlignment(basicType);
|
||||
if (sizeAndAlignment != null && sizeAndAlignment.size < 8) {
|
||||
long range = (1L << (sizeAndAlignment.size * 8));
|
||||
return IntegralValue.create(range - value.numberValue().longValue());
|
||||
}
|
||||
|
||||
return IntegralValue.create(-value.numberValue().longValue());
|
||||
}
|
||||
return IntegralValue.create(-value.numberValue().longValue());
|
||||
} else {
|
||||
FloatingPointValue fpv = (FloatingPointValue) value;
|
||||
|
@ -593,7 +614,8 @@ public class ValueFactory {
|
|||
return o2;
|
||||
if (isDeferredValue(o1) || isDeferredValue(o2))
|
||||
return null; // the value will be computed using the evaluation
|
||||
return evaluateBinaryExpression(op, o1, o2);
|
||||
IType exprType = exp.getExpressionType();
|
||||
return evaluateBinaryExpression(op, o1, o2, exprType);
|
||||
}
|
||||
|
||||
private static IValue applyBinaryTypeIdOperator(IASTBinaryTypeIdExpression.Operator operator, IType type1,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012, 2017 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2012, 2017, 2023 Wind River Systems, Inc. and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
|
@ -240,7 +240,7 @@ public class EvalBinary extends CPPDependentEvaluation {
|
|||
|
||||
Number num2 = v2.numberValue();
|
||||
if (num2 != null) {
|
||||
return ValueFactory.evaluateBinaryExpression(fOperator, v1, v2);
|
||||
return ValueFactory.evaluateBinaryExpression(fOperator, v1, v2, getType());
|
||||
}
|
||||
}
|
||||
return DependentValue.create(this);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2012, 2014 Wind River Systems, Inc. and others.
|
||||
* Copyright (c) 2012, 2014, 2023 Wind River Systems, Inc. and others.
|
||||
*
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License 2.0
|
||||
|
@ -357,7 +357,7 @@ public class EvalUnary extends CPPDependentEvaluation {
|
|||
if (val == null)
|
||||
return IntegralValue.UNKNOWN;
|
||||
|
||||
return ValueFactory.evaluateUnaryExpression(fOperator, val);
|
||||
return ValueFactory.evaluateUnaryExpression(fOperator, val, getType());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Add table
Reference in a new issue