diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java index 7324703f8f0..6234e8a0539 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ArithmeticConversion.java @@ -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 final IType convertOperandTypes(int operator, IType op1, IType op2) { 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: diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java index 2b08f3223a0..b9585e5f510 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ValueFactory.java @@ -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.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.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 static IValue create(IASTExpression expr) { 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 static IValue create(IASTExpression expr) { } } - 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 static IValue evaluateBinaryExpression(final int op, final IValue v1, fin } 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 @@ private static IValue applyBinaryOperator(final int op, final double v1, final d } } - 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 @@ private static IntegralValue applyBinaryOperator(final int op, final long v1, fi 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 @@ private static IntegralValue applyBinaryOperator(final int op, final long v1, fi 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 @@ private static IValue evaluateUnaryExpression(IASTUnaryExpression exp) { 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 @@ private static IValue applyUnaryOperator(final int unaryOp, final IValue value) } 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 @@ private static IValue evaluateBinaryExpression(IASTBinaryExpression exp) { 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, diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java index e9408f89e1a..8efed7ea9e9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalBinary.java @@ -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 IValue getValue() { Number num2 = v2.numberValue(); if (num2 != null) { - return ValueFactory.evaluateBinaryExpression(fOperator, v1, v2); + return ValueFactory.evaluateBinaryExpression(fOperator, v1, v2, getType()); } } return DependentValue.create(this); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java index 79eb2395633..35d386adf7c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/EvalUnary.java @@ -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 IValue getValue() { if (val == null) return IntegralValue.UNKNOWN; - return ValueFactory.evaluateUnaryExpression(fOperator, val); + return ValueFactory.evaluateUnaryExpression(fOperator, val, getType()); } @Override