Skip to content

Commit ac3c395

Browse files
authored
fix #12110: FP signConversion with integer overflow (danmar#7022)
1 parent ff8ea61 commit ac3c395

File tree

4 files changed

+20
-9
lines changed

4 files changed

+20
-9
lines changed

lib/platform.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -329,24 +329,24 @@ std::string Platform::getLimitsDefines(bool c99) const
329329
s += ";USHRT_MAX=";
330330
s += std::to_string(max_value(short_bit+1));
331331
s += ";INT_MIN=";
332-
s += std::to_string(min_value(int_bit));
332+
s += "(-" + std::to_string(max_value(int_bit)) + " - 1)";
333333
s += ";INT_MAX=";
334334
s += std::to_string(max_value(int_bit));
335335
s += ";UINT_MAX=";
336336
s += std::to_string(max_value(int_bit+1));
337337
s += ";LONG_MIN=";
338-
s += std::to_string(min_value(long_bit));
338+
s += "(-" + std::to_string(max_value(long_bit)) + "L - 1L)";
339339
s += ";LONG_MAX=";
340-
s += std::to_string(max_value(long_bit));
340+
s += std::to_string(max_value(long_bit)) + "L";
341341
s += ";ULONG_MAX=";
342-
s += std::to_string(max_value(long_bit+1));
342+
s += std::to_string(max_value_unsigned(long_bit)) + "UL";
343343
if (c99) {
344344
s += ";LLONG_MIN=";
345-
s += std::to_string(min_value(long_long_bit));
345+
s += "(-" + std::to_string(max_value(long_long_bit)) + "LL - 1LL)";
346346
s += ";LLONG_MAX=";
347-
s += std::to_string(max_value(long_long_bit));
347+
s += std::to_string(max_value(long_long_bit)) + "LL";
348348
s += ";ULLONG_MAX=";
349-
s += std::to_string(max_value(long_long_bit + 1));
349+
s += std::to_string(max_value_unsigned(long_long_bit)) + "ULL";
350350
}
351351

352352
// cstdint / stdint.h

lib/platform.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ class CPPCHECKLIB Platform {
5555
return (1LL << (bit-1)) - 1LL;
5656
}
5757

58+
static unsigned long long max_value_unsigned(int bit) {
59+
if (bit >= 64)
60+
return ~0ULL;
61+
return (1ULL << bit) - 1ULL;
62+
}
63+
5864
/** provides list of defines specified by the limit.h/climits includes */
5965
std::string getLimitsDefines(bool c99) const;
6066
public:

test/testplatform.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -403,8 +403,8 @@ class TestPlatform : public TestFixture {
403403
void limitsDefines() const {
404404
Platform platform;
405405
ASSERT_EQUALS(true, platform.set(Platform::Unix64));
406-
const std::string defs = "CHAR_BIT=8;SCHAR_MIN=-128;SCHAR_MAX=127;UCHAR_MAX=255;CHAR_MIN=0;CHAR_MAX=127;SHRT_MIN=-32768;SHRT_MAX=32767;USHRT_MAX=65535;INT_MIN=-2147483648;INT_MAX=2147483647;UINT_MAX=4294967295;LONG_MIN=-9223372036854775808;LONG_MAX=9223372036854775807;ULONG_MAX=9223372036854775807";
407-
const std::string defs_c99 = "CHAR_BIT=8;SCHAR_MIN=-128;SCHAR_MAX=127;UCHAR_MAX=255;CHAR_MIN=0;CHAR_MAX=127;SHRT_MIN=-32768;SHRT_MAX=32767;USHRT_MAX=65535;INT_MIN=-2147483648;INT_MAX=2147483647;UINT_MAX=4294967295;LONG_MIN=-9223372036854775808;LONG_MAX=9223372036854775807;ULONG_MAX=9223372036854775807;LLONG_MIN=-9223372036854775808;LLONG_MAX=9223372036854775807;ULLONG_MAX=9223372036854775807";
406+
const std::string defs = "CHAR_BIT=8;SCHAR_MIN=-128;SCHAR_MAX=127;UCHAR_MAX=255;CHAR_MIN=0;CHAR_MAX=127;SHRT_MIN=-32768;SHRT_MAX=32767;USHRT_MAX=65535;INT_MIN=(-2147483647 - 1);INT_MAX=2147483647;UINT_MAX=4294967295;LONG_MIN=(-9223372036854775807L - 1L);LONG_MAX=9223372036854775807L;ULONG_MAX=18446744073709551615UL";
407+
const std::string defs_c99 = "CHAR_BIT=8;SCHAR_MIN=-128;SCHAR_MAX=127;UCHAR_MAX=255;CHAR_MIN=0;CHAR_MAX=127;SHRT_MIN=-32768;SHRT_MAX=32767;USHRT_MAX=65535;INT_MIN=(-2147483647 - 1);INT_MAX=2147483647;UINT_MAX=4294967295;LONG_MIN=(-9223372036854775807L - 1L);LONG_MAX=9223372036854775807L;ULONG_MAX=18446744073709551615UL;LLONG_MIN=(-9223372036854775807LL - 1LL);LLONG_MAX=9223372036854775807LL;ULLONG_MAX=18446744073709551615ULL";
408408
ASSERT_EQUALS(defs, platform.getLimitsDefines(Standards::cstd_t::C89));
409409
ASSERT_EQUALS(defs_c99, platform.getLimitsDefines(Standards::cstd_t::C99));
410410
ASSERT_EQUALS(defs_c99, platform.getLimitsDefines(Standards::cstd_t::CLatest));

test/testtype.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,11 @@ class TestType : public TestFixture {
352352
" return -2 * x;\n"
353353
"}", settingsDefault);
354354
ASSERT_EQUALS("[test.cpp:2]: (warning) Expression '-2' has a negative value. That is converted to an unsigned value and used in an unsigned calculation.\n", errout_str());
355+
356+
checkP("void f() {\n" // #12110 FP signConversion with integer overflow
357+
" if (LLONG_MIN / (-1)) {}\n"
358+
"}\n", settingsDefault);
359+
ASSERT_EQUALS("", errout_str());
355360
}
356361

357362
void longCastAssign() {

0 commit comments

Comments
 (0)