Skip to content

Commit 8ffb76d

Browse files
Fix #15032 FP knownConditionTrueFalse for bitwise negation of char (#8941)
1 parent f73fc08 commit 8ffb76d

6 files changed

Lines changed: 14 additions & 7 deletions

File tree

‎lib/valueflow.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4131,7 +4131,7 @@ static std::list<ValueFlow::Value> truncateValues(std::list<ValueFlow::Value> va
41314131
}
41324132

41334133
if (value.isIntValue() && sz > 0 && sz < sizeof(MathLib::biguint))
4134-
value.intvalue = ValueFlow::truncateIntValue(value.intvalue, sz, dst->sign);
4134+
value.intvalue = ValueFlow::truncateIntValue(value.intvalue, sz, dst, settings.platform);
41354135
}
41364136
return values;
41374137
}

‎lib/vf_analyzers.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ struct ValueFlowAnalyzer : Analyzer {
357357
if (dst) {
358358
const size_t sz = dst->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer);
359359
if (sz > 0 && sz < sizeof(MathLib::biguint)) {
360-
MathLib::bigint newvalue = ValueFlow::truncateIntValue(value->intvalue, sz, dst->sign);
360+
MathLib::bigint newvalue = ValueFlow::truncateIntValue(value->intvalue, sz, dst, settings.platform);
361361

362362
/* Handle overflow/underflow for value bounds */
363363
if (value->bound != ValueFlow::Value::Bound::Point) {

‎lib/vf_common.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,15 +96,15 @@ namespace ValueFlow
9696
return true;
9797
}
9898

99-
MathLib::bigint truncateIntValue(MathLib::bigint value, size_t value_size, const ValueType::Sign dst_sign)
99+
MathLib::bigint truncateIntValue(MathLib::bigint value, size_t value_size, const ValueType* dst, const Platform& platform)
100100
{
101101
if (value_size == 0)
102102
return value;
103103

104104
const MathLib::biguint unsignedMaxValue = std::numeric_limits<MathLib::biguint>::max() >> ((sizeof(unsignedMaxValue) - value_size) * 8);
105105
const MathLib::biguint signBit = 1ULL << ((value_size * 8) - 1);
106106
value &= unsignedMaxValue;
107-
if (dst_sign == ValueType::Sign::SIGNED && (value & signBit))
107+
if ((dst->sign == ValueType::Sign::SIGNED || (dst->sign == ValueType::Sign::UNKNOWN_SIGN && dst->type == ValueType::Type::CHAR && platform.defaultSign == 's')) && (value & signBit))
108108
value |= ~unsignedMaxValue;
109109

110110
return value;

‎lib/vf_common.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ namespace ValueFlow
4141
{
4242
bool getMinMaxValues(const ValueType* vt, const Platform& platform, MathLib::bigint& minValue, MathLib::bigint& maxValue);
4343

44-
MathLib::bigint truncateIntValue(MathLib::bigint value, size_t value_size, ValueType::Sign dst_sign);
44+
MathLib::bigint truncateIntValue(MathLib::bigint value, size_t value_size, const ValueType* dst, const Platform& platform);
4545

4646
Token * valueFlowSetConstantValue(Token *tok, const Settings &settings);
4747

‎lib/vf_settokenvalue.cpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,7 @@ namespace ValueFlow
665665
const ValueType *dst = tok->valueType();
666666
if (dst) {
667667
const size_t sz = dst->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer);
668-
MathLib::bigint newvalue = ValueFlow::truncateIntValue(v.intvalue + 1, sz, dst->sign);
668+
MathLib::bigint newvalue = ValueFlow::truncateIntValue(v.intvalue + 1, sz, dst, settings.platform);
669669
if (v.bound != ValueFlow::Value::Bound::Point) {
670670
if (newvalue < v.intvalue) {
671671
v.invertBound();
@@ -695,7 +695,7 @@ namespace ValueFlow
695695
const ValueType *dst = tok->valueType();
696696
if (dst) {
697697
const size_t sz = dst->getSizeOf(settings, ValueType::Accuracy::ExactOrZero, ValueType::SizeOf::Pointer);
698-
MathLib::bigint newvalue = ValueFlow::truncateIntValue(v.intvalue - 1, sz, dst->sign);
698+
MathLib::bigint newvalue = ValueFlow::truncateIntValue(v.intvalue - 1, sz, dst, settings.platform);
699699
if (v.bound != ValueFlow::Value::Bound::Point) {
700700
if (newvalue > v.intvalue) {
701701
v.invertBound();

‎test/testvalueflow.cpp‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1389,6 +1389,13 @@ class TestValueFlow : public TestFixture {
13891389
ASSERT_EQUALS(22, values.back().intvalue);
13901390
}
13911391

1392+
code = "void f() {\n" // #15032
1393+
" char c = -1;\n"
1394+
" if (~c == -256) {}\n"
1395+
"}\n";
1396+
const int expected = std::numeric_limits<char>::is_signed ? 0 : -256;
1397+
ASSERT_EQUALS(true, testKnownValueOfTok(code, "~", expected));
1398+
13921399
// #10251 starship operator
13931400
code = "struct X {};\n"
13941401
"auto operator<=>(const X & a, const X & b) -> decltype(1 <=> 2) {\n"

0 commit comments

Comments
 (0)