ValueType: Support unary arithmetical/bit operators
This commit is contained in:
parent
cae19cadd3
commit
a9f52aec04
|
@ -3734,13 +3734,13 @@ static void setValueType(Token *tok, const ValueType &valuetype, bool cpp, Value
|
||||||
if (parent->astOperand2() && !vt2)
|
if (parent->astOperand2() && !vt2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (parent->isArithmeticalOp() && vt2) {
|
if (parent->isArithmeticalOp()) {
|
||||||
if (vt1->pointer != 0U && vt2->pointer == 0U) {
|
if (vt1->pointer != 0U && vt2 && vt2->pointer == 0U) {
|
||||||
setValueType(parent, *vt1, cpp, defaultSignedness);
|
setValueType(parent, *vt1, cpp, defaultSignedness);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vt1->pointer == 0U && vt2->pointer != 0U) {
|
if (vt1->pointer == 0U && vt2 && vt2->pointer != 0U) {
|
||||||
setValueType(parent, *vt2, cpp, defaultSignedness);
|
setValueType(parent, *vt2, cpp, defaultSignedness);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3750,27 +3750,30 @@ static void setValueType(Token *tok, const ValueType &valuetype, bool cpp, Value
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vt1->type == ValueType::Type::LONGDOUBLE || vt2->type == ValueType::Type::LONGDOUBLE) {
|
if (vt1->type == ValueType::Type::LONGDOUBLE || (vt2 && vt2->type == ValueType::Type::LONGDOUBLE)) {
|
||||||
setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::LONGDOUBLE, 0U), cpp, defaultSignedness);
|
setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::LONGDOUBLE, 0U), cpp, defaultSignedness);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (vt1->type == ValueType::Type::DOUBLE || vt2->type == ValueType::Type::DOUBLE) {
|
if (vt1->type == ValueType::Type::DOUBLE || (vt2 && vt2->type == ValueType::Type::DOUBLE)) {
|
||||||
setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::DOUBLE, 0U), cpp, defaultSignedness);
|
setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::DOUBLE, 0U), cpp, defaultSignedness);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (vt1->type == ValueType::Type::FLOAT || vt2->type == ValueType::Type::FLOAT) {
|
if (vt1->type == ValueType::Type::FLOAT || (vt2 && vt2->type == ValueType::Type::FLOAT)) {
|
||||||
setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::FLOAT, 0U), cpp, defaultSignedness);
|
setValueType(parent, ValueType(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::FLOAT, 0U), cpp, defaultSignedness);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vt2 &&
|
if (vt1->isIntegral() && vt1->pointer == 0U &&
|
||||||
vt1->isIntegral() && vt1->pointer == 0U &&
|
(!vt2 || (vt2->isIntegral() && vt2->pointer == 0U)) &&
|
||||||
vt2->isIntegral() && vt2->pointer == 0U &&
|
|
||||||
(parent->isArithmeticalOp() || parent->tokType() == Token::eBitOp || parent->isAssignmentOp())) {
|
(parent->isArithmeticalOp() || parent->tokType() == Token::eBitOp || parent->isAssignmentOp())) {
|
||||||
|
|
||||||
ValueType vt;
|
ValueType vt;
|
||||||
if (vt1->type == vt2->type) {
|
if (!vt2 || vt1->type > vt2->type) {
|
||||||
|
vt.type = vt1->type;
|
||||||
|
vt.sign = vt1->sign;
|
||||||
|
vt.originalTypeName = vt1->originalTypeName;
|
||||||
|
} else if (vt1->type == vt2->type) {
|
||||||
vt.type = vt1->type;
|
vt.type = vt1->type;
|
||||||
if (vt1->sign == ValueType::Sign::UNSIGNED || vt2->sign == ValueType::Sign::UNSIGNED)
|
if (vt1->sign == ValueType::Sign::UNSIGNED || vt2->sign == ValueType::Sign::UNSIGNED)
|
||||||
vt.sign = ValueType::Sign::UNSIGNED;
|
vt.sign = ValueType::Sign::UNSIGNED;
|
||||||
|
@ -3779,10 +3782,6 @@ static void setValueType(Token *tok, const ValueType &valuetype, bool cpp, Value
|
||||||
else
|
else
|
||||||
vt.sign = ValueType::Sign::SIGNED;
|
vt.sign = ValueType::Sign::SIGNED;
|
||||||
vt.originalTypeName = (vt1->originalTypeName.empty() ? vt2 : vt1)->originalTypeName;
|
vt.originalTypeName = (vt1->originalTypeName.empty() ? vt2 : vt1)->originalTypeName;
|
||||||
} else if (vt1->type > vt2->type) {
|
|
||||||
vt.type = vt1->type;
|
|
||||||
vt.sign = vt1->sign;
|
|
||||||
vt.originalTypeName = vt1->originalTypeName;
|
|
||||||
} else {
|
} else {
|
||||||
vt.type = vt2->type;
|
vt.type = vt2->type;
|
||||||
vt.sign = vt2->sign;
|
vt.sign = vt2->sign;
|
||||||
|
|
|
@ -3190,6 +3190,11 @@ private:
|
||||||
ASSERT_EQUALS("long double *", typeOf("long double x; dostuff(&x,1);", "& x ,"));
|
ASSERT_EQUALS("long double *", typeOf("long double x; dostuff(&x,1);", "& x ,"));
|
||||||
ASSERT_EQUALS("signed int", typeOf("struct X {int i;}; void f(struct X x) { x.i }", "."));
|
ASSERT_EQUALS("signed int", typeOf("struct X {int i;}; void f(struct X x) { x.i }", "."));
|
||||||
|
|
||||||
|
// Unary arithmetic/bit operators
|
||||||
|
ASSERT_EQUALS("signed int", typeOf("int x; a = -x;", "-"));
|
||||||
|
ASSERT_EQUALS("signed int", typeOf("int x; a = ~x;", "~"));
|
||||||
|
ASSERT_EQUALS("double", typeOf("double x; a = -x;", "-"));
|
||||||
|
|
||||||
// shift => result has same type as lhs
|
// shift => result has same type as lhs
|
||||||
ASSERT_EQUALS("signed int", typeOf("int x; a = x << 1U;", "<<"));
|
ASSERT_EQUALS("signed int", typeOf("int x; a = x << 1U;", "<<"));
|
||||||
ASSERT_EQUALS("signed int", typeOf("int x; a = x >> 1U;", ">>"));
|
ASSERT_EQUALS("signed int", typeOf("int x; a = x >> 1U;", ">>"));
|
||||||
|
|
Loading…
Reference in New Issue