Skip to content

Commit 49d0609

Browse files
committed
added CMake option USE_INT128 and support built-in __int128 / some compilation fixes
1 parent 4d04f41 commit 49d0609

File tree

10 files changed

+88
-30
lines changed

10 files changed

+88
-30
lines changed

cmake/compilerDefinitions.cmake

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,13 @@ if(HAVE_RULES)
3737
add_definitions(-DHAVE_RULES)
3838
endif()
3939

40+
if(USE_INT128)
41+
add_definitions(-DHAVE_INT128)
42+
endif()
43+
4044
if(Boost_FOUND)
4145
add_definitions(-DHAVE_BOOST)
42-
if(USE_BOOST_INT128)
46+
if(USE_INT128 AND USE_BOOST_INT128)
4347
add_definitions(-DHAVE_BOOST_INT128)
4448
endif()
4549
endif()

cmake/options.cmake

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,16 @@ option(DISALLOW_THREAD_EXECUTOR "Disallow usage of ThreadExecutor for -j"
9292
if(DISALLOW_THREAD_EXECUTOR AND WIN32)
9393
message(FATAL_ERROR "Cannot disable usage of ThreadExecutor on Windows as no other executor implementation is currently available")
9494
endif()
95+
set(USE_INT128 "Off" CACHE STRING "Usage of 128-bit integer type") # TODO: default to Auto when working
96+
set_property(CACHE USE_INT128 PROPERTY STRINGS Auto Off On)
9597
set(USE_BOOST "Auto" CACHE STRING "Usage of Boost")
9698
set_property(CACHE USE_BOOST PROPERTY STRINGS Auto Off On)
97-
option(USE_BOOST_INT128 "Usage of Boost.Multiprecision 128-bit integer for Mathlib" OFF)
98-
if (NOT USE_BOOST AND USE_BOOST_INT128)
99-
message(FATAL_ERROR "USE_BOOST_INT128 requires USE_BOOST to be enabled")
99+
set(USE_BOOST_INT128 "Off" CACHE STRING "Usage of Boost.Multiprecision 128-bit integer for Mathlib") # TODO: default to Auto when working
100+
set_property(CACHE USE_BOOST_INT128 PROPERTY STRINGS Auto Off On)
101+
if (USE_INT128)
102+
if (NOT USE_BOOST AND USE_BOOST_INT128)
103+
message(FATAL_ERROR "USE_BOOST_INT128 requires USE_BOOST to be enabled")
104+
endif()
100105
endif()
101106
option(USE_LIBCXX "Use libc++ instead of libstdc++" OFF)
102107

cmake/printInfo.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ if(NOT USE_BUNDLED_TINYXML2)
8686
message(STATUS "tinyxml2_INCLUDE_DIRS = ${tinyxml2_INCLUDE_DIRS}")
8787
endif()
8888
message(STATUS)
89+
message(STATUS "USE_INT128 = ${USE_INT128}")
90+
message(STATUS)
8991
message(STATUS "USE_BOOST = ${USE_BOOST}")
9092
if(USE_BOOST)
9193
message(STATUS "Boost_FOUND = ${Boost_FOUND}")

lib/mathlib.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ MathLib::value MathLib::value::calc(char op, const MathLib::value &v1, const Mat
163163
case '/':
164164
if (v2.mIntValue == 0)
165165
throw InternalError(nullptr, "Internal Error: Division by zero");
166-
if (v1.mIntValue == std::numeric_limits<bigint>::min() && std::abs(v2.mIntValue)<=1)
166+
if (v1.mIntValue == std::numeric_limits<bigint>::min() && MathLib::abs(v2.mIntValue)<=1)
167167
throw InternalError(nullptr, "Internal Error: Division overflow");
168168
temp.mIntValue /= static_cast<unsigned long long>(v2.mIntValue);
169169
break;
@@ -198,7 +198,7 @@ MathLib::value MathLib::value::calc(char op, const MathLib::value &v1, const Mat
198198
case '/':
199199
if (v2.mIntValue == 0)
200200
throw InternalError(nullptr, "Internal Error: Division by zero");
201-
if (v1.mIntValue == std::numeric_limits<bigint>::min() && std::abs(v2.mIntValue)<=1)
201+
if (v1.mIntValue == std::numeric_limits<bigint>::min() && MathLib::abs(v2.mIntValue)<=1)
202202
throw InternalError(nullptr, "Internal Error: Division overflow");
203203
temp.mIntValue /= v2.mIntValue;
204204
break;
@@ -537,21 +537,33 @@ double MathLib::toDoubleNumber(const std::string &str, const Token * const tok)
537537

538538
template<> std::string MathLib::toString<MathLib::bigint>(MathLib::bigint value)
539539
{
540-
#if defined(HAVE_BOOST) && defined(HAVE_BOOST_INT128)
540+
#if defined(HAVE_INT128)
541+
# if defined(HAVE_BOOST) && defined(HAVE_BOOST_INT128)
541542
std::ostringstream result;
542543
result << value;
543544
return result.str();
545+
# else
546+
// TODO: handle actual 128-bit values
547+
assert(value >= std::numeric_limits<long long>::min() && value <= std::numeric_limits<long long>::max());
548+
return std::to_string(static_cast<long long>(value));
549+
# endif
544550
#else
545551
return std::to_string(value);
546552
#endif
547553
}
548554

549555
template<> std::string MathLib::toString<MathLib::biguint>(MathLib::biguint value)
550556
{
551-
#if defined(HAVE_BOOST) && defined(HAVE_BOOST_INT128)
557+
#if defined(HAVE_INT128)
558+
# if defined(HAVE_BOOST) && defined(HAVE_BOOST_INT128)
552559
std::ostringstream result;
553560
result << value;
554561
return result.str();
562+
# else
563+
// TODO: handle actual 128-bit values
564+
assert(value <= std::numeric_limits<unsigned long long>::max());
565+
return std::to_string(static_cast<unsigned long long>(value));
566+
# endif
555567
#else
556568
return std::to_string(value);
557569
#endif
@@ -1148,7 +1160,7 @@ std::string MathLib::divide(const std::string &first, const std::string &second)
11481160
const bigint b = toBigNumber(second);
11491161
if (b == 0)
11501162
throw InternalError(nullptr, "Internal Error: Division by zero");
1151-
if (a == std::numeric_limits<bigint>::min() && std::abs(b)<=1)
1163+
if (a == std::numeric_limits<bigint>::min() && MathLib::abs(b)<=1)
11521164
throw InternalError(nullptr, "Internal Error: Division overflow");
11531165
return MathLib::toString(toBigNumber(first) / b) + intsuffix(first, second);
11541166
}

lib/mathlib.h

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
#include <cstdint>
2727
#include <string>
2828

29-
#if defined(HAVE_BOOST) && defined(HAVE_BOOST_INT128)
30-
#include <boost/multiprecision/cpp_int.hpp>
29+
#if defined(HAVE_INT128)
30+
# if defined(HAVE_BOOST) && defined(HAVE_BOOST_INT128)
31+
# include <boost/multiprecision/cpp_int.hpp>
32+
# endif
3133
#endif
3234

3335
class Token;
@@ -41,9 +43,18 @@ class CPPCHECKLIB MathLib {
4143
friend class TestMathLib;
4244

4345
public:
44-
#if defined(HAVE_BOOST) && defined(HAVE_BOOST_INT128)
46+
#if defined(HAVE_INT128)
47+
# if defined(HAVE_BOOST) && defined(HAVE_BOOST_INT128)
4548
using bigint = boost::multiprecision::int128_t;
4649
using biguint = boost::multiprecision::uint128_t;
50+
# elif defined(__GNUC__)
51+
SUPPRESS_WARNING_GCC_PUSH("-Wpedantic")
52+
using bigint = __int128;
53+
using biguint = unsigned __int128;
54+
SUPPRESS_WARNING_GCC_POP
55+
# else
56+
#error "no 128-bit type"
57+
# endif
4758
#else
4859
using bigint = long long;
4960
using biguint = unsigned long long;
@@ -144,6 +155,12 @@ class CPPCHECKLIB MathLib {
144155
static bool isOctalDigit(char c);
145156

146157
static unsigned int encodeMultiChar(const std::string& str);
158+
159+
static bigint abs(bigint i) {
160+
if (i < 0)
161+
return -i;
162+
return i;
163+
}
147164
};
148165

149166
MathLib::value operator+(const MathLib::value &v1, const MathLib::value &v2);
@@ -161,6 +178,20 @@ template<> CPPCHECKLIB std::string MathLib::toString<MathLib::bigint>(MathLib::b
161178
template<> CPPCHECKLIB std::string MathLib::toString<MathLib::biguint>(MathLib::biguint value);
162179
template<> CPPCHECKLIB std::string MathLib::toString<double>(double value);
163180

181+
// Boost provides stream insertion operators
182+
#if defined(HAVE_INT128) && !defined(HAVE_BOOST_INT128)
183+
inline std::ostream& operator<<(std::ostream& os, MathLib::bigint i)
184+
{
185+
os << MathLib::toString(i);
186+
return os;
187+
}
188+
inline std::ostream& operator<<(std::ostream& os, MathLib::biguint u)
189+
{
190+
os << MathLib::toString(u);
191+
return os;
192+
}
193+
#endif
194+
164195
/// @}
165196
//---------------------------------------------------------------------------
166197
#endif // mathlibH

lib/token.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2027,7 +2027,7 @@ static bool isAdjacent(const ValueFlow::Value& x, const ValueFlow::Value& y)
20272027
return true;
20282028
if (x.valueType == ValueFlow::Value::ValueType::FLOAT)
20292029
return false;
2030-
return std::abs(x.intvalue - y.intvalue) == 1;
2030+
return MathLib::abs(x.intvalue - y.intvalue) == 1;
20312031
}
20322032

20332033
static bool removePointValue(std::list<ValueFlow::Value>& values, std::list<ValueFlow::Value>::iterator& x)

lib/valueflow.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4515,7 +4515,7 @@ struct ConditionHandler {
45154515

45164516
MathLib::bigint getPath() const
45174517
{
4518-
assert(std::abs(findPath(true_values) - findPath(false_values)) == 0);
4518+
assert(MathLib::abs(findPath(true_values) - findPath(false_values)) == 0);
45194519
return findPath(true_values) | findPath(false_values);
45204520
}
45214521

lib/vfvalue.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ namespace ValueFlow
168168
return !(*this == rhs);
169169
}
170170

171+
// TODO: allow __int128
171172
template<class T, REQUIRES("T must be an arithmetic type", std::is_arithmetic<T> )>
172173
bool equalTo(const T& x) const {
173174
bool result = false;
@@ -316,6 +317,9 @@ namespace ValueFlow
316317

317318
std::int8_t indirect{}; // TODO: can we reduce the size?
318319

320+
#if defined(HAVE_INT128)
321+
long long : 64;
322+
#endif
319323
/** int value (or sometimes bool value?) */
320324
MathLib::bigint intvalue{};
321325

test/testmathlib.cpp

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -358,12 +358,12 @@ class TestMathLib : public TestFixture {
358358
// min/max and out-of-bounds - hex
359359
{
360360
constexpr MathLib::bigint i = 0xFFFFFFFFFFFFFFFF;
361-
ASSERT_EQUALS(i, MathLib::toBigNumber(std::to_string(i)));
361+
ASSERT_EQUALS(i, MathLib::toBigNumber(MathLib::toString(i)));
362362
ASSERT_EQUALS(i, MathLib::toBigNumber("0xFFFFFFFFFFFFFFFF"));
363363
}
364364
{
365365
constexpr MathLib::bigint i = -0xFFFFFFFFFFFFFFFF;
366-
ASSERT_EQUALS(i, MathLib::toBigNumber(std::to_string(i)));
366+
ASSERT_EQUALS(i, MathLib::toBigNumber(MathLib::toString(i)));
367367
ASSERT_EQUALS(i, MathLib::toBigNumber("-0xFFFFFFFFFFFFFFFF"));
368368
}
369369

@@ -373,12 +373,12 @@ class TestMathLib : public TestFixture {
373373
// min/max and out-of-bounds - octal
374374
{
375375
constexpr MathLib::bigint i = 01777777777777777777777;
376-
ASSERT_EQUALS(i, MathLib::toBigNumber(std::to_string(i)));
376+
ASSERT_EQUALS(i, MathLib::toBigNumber(MathLib::toString(i)));
377377
ASSERT_EQUALS(i, MathLib::toBigNumber("01777777777777777777777"));
378378
}
379379
{
380380
constexpr MathLib::bigint i = -01777777777777777777777;
381-
ASSERT_EQUALS(i, MathLib::toBigNumber(std::to_string(i)));
381+
ASSERT_EQUALS(i, MathLib::toBigNumber(MathLib::toString(i)));
382382
ASSERT_EQUALS(i, MathLib::toBigNumber("-01777777777777777777777"));
383383
}
384384

@@ -388,12 +388,12 @@ class TestMathLib : public TestFixture {
388388
// min/max and out-of-range - decimal
389389
{
390390
constexpr MathLib::bigint i = 18446744073709551615ULL;
391-
ASSERT_EQUALS(i, MathLib::toBigNumber(std::to_string(i)));
391+
ASSERT_EQUALS(i, MathLib::toBigNumber(MathLib::toString(i)));
392392
ASSERT_EQUALS(i, MathLib::toBigNumber("18446744073709551615"));
393393
}
394394
{
395395
constexpr MathLib::bigint i = -18446744073709551615ULL;
396-
ASSERT_EQUALS(i, MathLib::toBigNumber(std::to_string(i)));
396+
ASSERT_EQUALS(i, MathLib::toBigNumber(MathLib::toString(i)));
397397
ASSERT_EQUALS(i, MathLib::toBigNumber("-18446744073709551615"));
398398
}
399399

@@ -530,12 +530,12 @@ class TestMathLib : public TestFixture {
530530
// min/max and out-of-bounds - hex
531531
{
532532
constexpr MathLib::biguint u = 0xFFFFFFFFFFFFFFFF;
533-
ASSERT_EQUALS(u, MathLib::toBigUNumber(std::to_string(u)));
533+
ASSERT_EQUALS(u, MathLib::toBigUNumber(MathLib::toString(u)));
534534
ASSERT_EQUALS(u, MathLib::toBigUNumber("0xFFFFFFFFFFFFFFFF"));
535535
}
536536
{
537537
constexpr MathLib::biguint u = -0xFFFFFFFFFFFFFFFF;
538-
ASSERT_EQUALS(u, MathLib::toBigUNumber(std::to_string(u)));
538+
ASSERT_EQUALS(u, MathLib::toBigUNumber(MathLib::toString(u)));
539539
ASSERT_EQUALS(u, MathLib::toBigUNumber("-0xFFFFFFFFFFFFFFFF"));
540540
}
541541

@@ -545,12 +545,12 @@ class TestMathLib : public TestFixture {
545545
// min/max and out-of-bounds - octal
546546
{
547547
constexpr MathLib::biguint u = 01777777777777777777777;
548-
ASSERT_EQUALS(u, MathLib::toBigUNumber(std::to_string(u)));
548+
ASSERT_EQUALS(u, MathLib::toBigUNumber(MathLib::toString(u)));
549549
ASSERT_EQUALS(u, MathLib::toBigUNumber("01777777777777777777777"));
550550
}
551551
{
552552
constexpr MathLib::biguint u = -01777777777777777777777;
553-
ASSERT_EQUALS(u, MathLib::toBigUNumber(std::to_string(u)));
553+
ASSERT_EQUALS(u, MathLib::toBigUNumber(MathLib::toString(u)));
554554
ASSERT_EQUALS(u, MathLib::toBigUNumber("-01777777777777777777777"));
555555
}
556556

@@ -560,12 +560,12 @@ class TestMathLib : public TestFixture {
560560
// min/max and out-of-range - decimal
561561
{
562562
constexpr MathLib::biguint u = 18446744073709551615ULL;
563-
ASSERT_EQUALS(u, MathLib::toBigUNumber(std::to_string(u)));
563+
ASSERT_EQUALS(u, MathLib::toBigUNumber(MathLib::toString(u)));
564564
ASSERT_EQUALS(u, MathLib::toBigUNumber("18446744073709551615"));
565565
}
566566
{
567567
constexpr MathLib::biguint u = -18446744073709551615ULL;
568-
ASSERT_EQUALS(u, MathLib::toBigUNumber(std::to_string(u)));
568+
ASSERT_EQUALS(u, MathLib::toBigUNumber(MathLib::toString(u)));
569569
ASSERT_EQUALS(u, MathLib::toBigUNumber("-18446744073709551615"));
570570
}
571571

test/testvalueflow.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6452,7 +6452,7 @@ class TestValueFlow : public TestFixture {
64526452
if (!values.front().isPossible())
64536453
return "Possible";
64546454
if (values.front().intvalue != i)
6455-
return "intvalue:" + std::to_string(values.front().intvalue);
6455+
return "intvalue:" + MathLib::toString(values.front().intvalue);
64566456
return "";
64576457
}
64586458

@@ -6470,7 +6470,7 @@ class TestValueFlow : public TestFixture {
64706470
if (!values.front().isImpossible())
64716471
return "Impossible";
64726472
if (values.front().intvalue != i)
6473-
return "intvalue:" + std::to_string(values.front().intvalue);
6473+
return "intvalue:" + MathLib::toString(values.front().intvalue);
64746474
return "";
64756475
}
64766476

@@ -6488,7 +6488,7 @@ class TestValueFlow : public TestFixture {
64886488
if (!values.front().isInconclusive())
64896489
return "Inconclusive";
64906490
if (values.front().intvalue != i)
6491-
return "intvalue:" + std::to_string(values.front().intvalue);
6491+
return "intvalue:" + MathLib::toString(values.front().intvalue);
64926492
return "";
64936493
}
64946494

@@ -6504,7 +6504,7 @@ class TestValueFlow : public TestFixture {
65046504
if (!values.front().isKnown())
65056505
return "Known";
65066506
if (values.front().intvalue != i)
6507-
return "intvalue:" + std::to_string(values.front().intvalue);
6507+
return "intvalue:" + MathLib::toString(values.front().intvalue);
65086508
return "";
65096509
}
65106510

0 commit comments

Comments
 (0)