Skip to content

Commit a8bb9ce

Browse files
mohitmishra786daveedvdv-nvidia
authored andcommitted
Default the integer value limits to 128 bits when __int128 extensions are allowed. [GH edgcpp#38]
1 parent 7915434 commit a8bb9ce

8 files changed

Lines changed: 86 additions & 6 deletions

File tree

‎cmake/macro-conf/support/platform/linux/base.cmakedef‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@ LONG_LONG_ALLOWED=1
4242
INTEGER_VALUE_REPR_IS_A_HOST_INTEGER=0
4343
TYPE_FOR_AN_INTEGER_VALUE=unsigned long long
4444
TYPE_FOR_A_SIGNED_INTEGER_VALUE=long long
45-
MAX_INTEGER_VALUE=9223372036854775807LL
46-
MIN_INTEGER_VALUE=(-MAX_INTEGER_VALUE-1)
47-
MAX_UNSIGNED_INTEGER_VALUE=18446744073709551615ULL
4845
FP_LONG_DOUBLE_IS_80BIT_EXTENDED=1
4946
LINKER_CAN_DISCARD_DUPLICATE_DEFINITIONS=1
5047

‎src/Changes‎

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,22 @@ ref-qualifiers. They now leave such types unchanged. For example, with
1212
using F = __add_pointer(F); // Previously a spurious error, now okay.
1313

1414

15+
10/20/26 [GH #38]
16+
Integer value limits for a 128-bit host integer representation
17+
18+
When INTEGER_VALUE_REPR_IS_A_HOST_INTEGER is TRUE and __int128 extensions are
19+
allowed, the integer value types default to the 128-bit types, but
20+
MAX_INTEGER_VALUE, MIN_INTEGER_VALUE, and MAX_UNSIGNED_INTEGER_VALUE still
21+
defaulted to 64-bit limits. As a result, constant arithmetic on __int128
22+
values that did not fit in 64 bits could be wrongly diagnosed as overflowing.
23+
For example, with --gnu_version 150200:
24+
25+
constexpr __int128 s = (__int128)1 << 100;
26+
static_assert(s * 4 == ((__int128)1 << 102), ""); // Previously an error.
27+
28+
This is now fixed.
29+
30+
1531
10/20/26 [GH #173]
1632
CTAD through a template template parameter of an alias template
1733

‎src/defines_linux.h‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -282,9 +282,6 @@ Linux.
282282
#ifndef TYPE_FOR_A_SIGNED_INTEGER_VALUE
283283
#define TYPE_FOR_A_SIGNED_INTEGER_VALUE long long
284284
#endif /* TYPE_FOR_A_SIGNED_INTEGER_VALUE */
285-
#define MAX_INTEGER_VALUE 9223372036854775807LL
286-
#define MIN_INTEGER_VALUE (-MAX_INTEGER_VALUE-1)
287-
#define MAX_UNSIGNED_INTEGER_VALUE 18446744073709551615ULL
288285

289286
#if defined(__aarch64__) || defined(__riscv)
290287
/* 64-bit ARM and RISC-V use a 128-bit long double representation. */

‎src/targ_def.h‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,6 +1536,9 @@ typedef TYPE_FOR_A_SIGNED_INTEGER_VALUE a_signed_integer_value;
15361536

15371537
/* Minimum and maximum values that can be represented in an_integer_value. */
15381538
#ifndef MAX_INTEGER_VALUE
1539+
#if INT128_EXTENSIONS_ALLOWED
1540+
#define MAX_INTEGER_VALUE ((__int128_t)(~(__uint128_t)0 >> 1))
1541+
#else /* !INT128_EXTENSIONS_ALLOWED */
15391542
#if LONG_LONG_ALLOWED
15401543
#ifdef LLONG_MAX
15411544
#define MAX_INTEGER_VALUE LLONG_MAX
@@ -1545,8 +1548,12 @@ typedef TYPE_FOR_A_SIGNED_INTEGER_VALUE a_signed_integer_value;
15451548
#else /* !LONG_LONG_ALLOWED */
15461549
#define MAX_INTEGER_VALUE LONG_MAX
15471550
#endif /* LONG_LONG_ALLOWED */
1551+
#endif /* INT128_EXTENSIONS_ALLOWED */
15481552
#endif /* ifndef MAX_INTEGER_VALUE */
15491553
#ifndef MIN_INTEGER_VALUE
1554+
#if INT128_EXTENSIONS_ALLOWED
1555+
#define MIN_INTEGER_VALUE (-MAX_INTEGER_VALUE-1)
1556+
#else /* !INT128_EXTENSIONS_ALLOWED */
15501557
#if LONG_LONG_ALLOWED
15511558
#if defined(LLONG_MIN) && LLONG_MIN < LLONG_MAX /*lint !e30*/
15521559
/* The preceding condition detects an incorrect definition of LLONG_MIN
@@ -1558,8 +1565,12 @@ typedef TYPE_FOR_A_SIGNED_INTEGER_VALUE a_signed_integer_value;
15581565
#else /* !LONG_LONG_ALLOWED */
15591566
#define MIN_INTEGER_VALUE LONG_MIN
15601567
#endif /* LONG_LONG_ALLOWED */
1568+
#endif /* INT128_EXTENSIONS_ALLOWED */
15611569
#endif /* ifndef MIN_INTEGER_VALUE */
15621570
#ifndef MAX_UNSIGNED_INTEGER_VALUE
1571+
#if INT128_EXTENSIONS_ALLOWED
1572+
#define MAX_UNSIGNED_INTEGER_VALUE (~(__uint128_t)0)
1573+
#else /* !INT128_EXTENSIONS_ALLOWED */
15631574
#if LONG_LONG_ALLOWED
15641575
#ifdef ULLONG_MAX
15651576
#define MAX_UNSIGNED_INTEGER_VALUE ULLONG_MAX
@@ -1569,6 +1580,7 @@ typedef TYPE_FOR_A_SIGNED_INTEGER_VALUE a_signed_integer_value;
15691580
#else /* !LONG_LONG_ALLOWED */
15701581
#define MAX_UNSIGNED_INTEGER_VALUE ULONG_MAX
15711582
#endif /* LONG_LONG_ALLOWED */
1583+
#endif /* INT128_EXTENSIONS_ALLOWED */
15721584
#endif /* ifndef MAX_UNSIGNED_INTEGER_VALUE */
15731585
#ifndef BITS_IN_AN_INTEGER_VALUE
15741586
#define BITS_IN_AN_INTEGER_VALUE (sizeof(an_integer_value) * CHAR_BIT)

‎tests/expectations/edg_x86_32/changes.log‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ EDGcpfe28436.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:[6.8] GNU/clang compatibility: larg
77
EDGcpfe28794.sft.cpp:fp:-DTEST_NUMBER=1:REQUIREMENTS NOT MET:Abort on __builtin_bit_cast in dependent context
88
EDGcpfe8330.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:[4.1] Microsoft compatibility: Calling conventions and pointer-to-member-function
99
EDGcpfe9522.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:[4.1] Microsoft compatibility: __ptr64 on 64-bit targets
10+
GH38.sft.cpp:fn:-DTEST_NUMBER=1 --gnu_version 150200:REQUIREMENTS NOT MET:[GH #38] Integer value limits for a 128-bit host integer representation

‎tests/expectations/edg_x86_32_cp/changes.log‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ EDGcpfe28436.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:[6.8] GNU/clang compatibility: larg
1313
EDGcpfe28794.sft.cpp:fp:-DTEST_NUMBER=1:REQUIREMENTS NOT MET:Abort on __builtin_bit_cast in dependent context
1414
EDGcpfe8330.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:[4.1] Microsoft compatibility: Calling conventions and pointer-to-member-function
1515
EDGcpfe9522.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:[4.1] Microsoft compatibility: __ptr64 on 64-bit targets
16+
GH38.sft.cpp:fn:-DTEST_NUMBER=1 --gnu_version 150200:REQUIREMENTS NOT MET:[GH #38] Integer value limits for a 128-bit host integer representation
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
fe_only -DTEST_NUMBER=1 --gnu_version 150200 Test_name.c
2+
"Test_name.c", line 23: error: expression must have a constant value
3+
static_assert(max + 1 != 0, ""); // Error: overflow
4+
^
5+
"Test_name.c", line 23: note: value exceeds range of "__int128"
6+
static_assert(max + 1 != 0, ""); // Error: overflow
7+
^
8+
9+
"Test_name.c", line 24: error: expression must have a constant value
10+
static_assert(min / -1 != 0, ""); // Error: overflow
11+
^
12+
"Test_name.c", line 24: note: integer operation result is out of range
13+
static_assert(min / -1 != 0, ""); // Error: overflow
14+
^
15+
16+
"Test_name.c", line 25: error: expression must have a constant value
17+
static_assert(max * 2 != 0, ""); // Error: overflow
18+
^
19+
"Test_name.c", line 25: note: value exceeds range of "__int128"
20+
static_assert(max * 2 != 0, ""); // Error: overflow
21+
^
22+
23+
"Test_name.c", line 26: error: expression must have a constant value
24+
static_assert(min * 2 != 0, ""); // Error: overflow
25+
^
26+
"Test_name.c", line 26: note: value exceeds range of "__int128"
27+
static_assert(min * 2 != 0, ""); // Error: overflow
28+
^
29+
30+
4 errors detected in the compilation of "Test_name.c".

‎tests/tests/changes/GH38.sft.cpp‎

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//type:fn
2+
//options:--gnu_version 150200
3+
//require:INT128_EXTENSIONS_ALLOWED 1
4+
//remark:[GH #38] Integer value limits for a 128-bit host integer representation
5+
// 10/20/26 [GH #38]
6+
//
7+
// Constant arithmetic on __int128 values that do not fit in 64 bits is
8+
// accepted, and overflow of the 128-bit range is still diagnosed.
9+
10+
constexpr __int128 s = (__int128)1 << 100;
11+
static_assert(s * 4 == ((__int128)1 << 102), "");
12+
static_assert(-s * 4 == -((__int128)1 << 102), "");
13+
14+
constexpr unsigned __int128 u = (unsigned __int128)1 << 100;
15+
static_assert(u * 4 == ((unsigned __int128)1 << 102), "");
16+
static_assert(u + u == ((unsigned __int128)1 << 101), "");
17+
18+
constexpr __int128 max = (__int128)(~(unsigned __int128)0 >> 1);
19+
constexpr __int128 min = -max - 1;
20+
static_assert(max / 3 * 3 + 1 == max, "");
21+
static_assert(min + 1 == -max, "");
22+
23+
static_assert(max + 1 != 0, ""); // Error: overflow
24+
static_assert(min / -1 != 0, ""); // Error: overflow
25+
static_assert(max * 2 != 0, ""); // Error: overflow
26+
static_assert(min * 2 != 0, ""); // Error: overflow

0 commit comments

Comments
 (0)