From c66fc61a5d68411725026f847c76988b67e7cb78 Mon Sep 17 00:00:00 2001 From: Mohit Mishra Date: Sun, 11 Oct 2026 00:32:29 +0530 Subject: [PATCH 1/3] Default the integer value limits to 128 bits when __int128 extensions are allowed. [GH #38] --- .../support/platform/linux/base.cmakedef | 3 --- src/Changes | 16 ++++++++++++++++ src/defines_linux.h | 3 --- src/targ_def.h | 12 ++++++++++++ 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/cmake/macro-conf/support/platform/linux/base.cmakedef b/cmake/macro-conf/support/platform/linux/base.cmakedef index 152f7629fe..162a67c545 100644 --- a/cmake/macro-conf/support/platform/linux/base.cmakedef +++ b/cmake/macro-conf/support/platform/linux/base.cmakedef @@ -42,9 +42,6 @@ LONG_LONG_ALLOWED=1 INTEGER_VALUE_REPR_IS_A_HOST_INTEGER=0 TYPE_FOR_AN_INTEGER_VALUE=unsigned long long TYPE_FOR_A_SIGNED_INTEGER_VALUE=long long -MAX_INTEGER_VALUE=9223372036854775807LL -MIN_INTEGER_VALUE=(-MAX_INTEGER_VALUE-1) -MAX_UNSIGNED_INTEGER_VALUE=18446744073709551615ULL FP_LONG_DOUBLE_IS_80BIT_EXTENDED=1 LINKER_CAN_DISCARD_DUPLICATE_DEFINITIONS=1 diff --git a/src/Changes b/src/Changes index 0b18da167f..0927359082 100644 --- a/src/Changes +++ b/src/Changes @@ -1,5 +1,21 @@ Version 7.1 +10/20/26 [GH #38] +Integer value limits for a 128-bit host integer representation + +When INTEGER_VALUE_REPR_IS_A_HOST_INTEGER is TRUE and __int128 extensions are +allowed, the integer value types default to the 128-bit types, but +MAX_INTEGER_VALUE, MIN_INTEGER_VALUE, and MAX_UNSIGNED_INTEGER_VALUE still +defaulted to 64-bit limits. As a result, constant arithmetic on __int128 +values that did not fit in 64 bits could be wrongly diagnosed as overflowing. +For example, with --gnu_version 150200: + + constexpr __int128 s = (__int128)1 << 100; + static_assert(s * 4 == ((__int128)1 << 102), ""); // Previously an error. + +This is now fixed. + + 10/15/26 [GH #309] Position of (lowered) cleanups at the end of a function body diff --git a/src/defines_linux.h b/src/defines_linux.h index 47fa8d5264..0e6b9ca149 100644 --- a/src/defines_linux.h +++ b/src/defines_linux.h @@ -282,9 +282,6 @@ Linux. #ifndef TYPE_FOR_A_SIGNED_INTEGER_VALUE #define TYPE_FOR_A_SIGNED_INTEGER_VALUE long long #endif /* TYPE_FOR_A_SIGNED_INTEGER_VALUE */ -#define MAX_INTEGER_VALUE 9223372036854775807LL -#define MIN_INTEGER_VALUE (-MAX_INTEGER_VALUE-1) -#define MAX_UNSIGNED_INTEGER_VALUE 18446744073709551615ULL #if defined(__aarch64__) || defined(__riscv) /* 64-bit ARM and RISC-V use a 128-bit long double representation. */ diff --git a/src/targ_def.h b/src/targ_def.h index 50edb81f9e..49d7b7132f 100644 --- a/src/targ_def.h +++ b/src/targ_def.h @@ -1536,6 +1536,9 @@ typedef TYPE_FOR_A_SIGNED_INTEGER_VALUE a_signed_integer_value; /* Minimum and maximum values that can be represented in an_integer_value. */ #ifndef MAX_INTEGER_VALUE +#if INT128_EXTENSIONS_ALLOWED +#define MAX_INTEGER_VALUE ((__int128_t)(~(__uint128_t)0 >> 1)) +#else /* !INT128_EXTENSIONS_ALLOWED */ #if LONG_LONG_ALLOWED #ifdef LLONG_MAX #define MAX_INTEGER_VALUE LLONG_MAX @@ -1545,8 +1548,12 @@ typedef TYPE_FOR_A_SIGNED_INTEGER_VALUE a_signed_integer_value; #else /* !LONG_LONG_ALLOWED */ #define MAX_INTEGER_VALUE LONG_MAX #endif /* LONG_LONG_ALLOWED */ +#endif /* INT128_EXTENSIONS_ALLOWED */ #endif /* ifndef MAX_INTEGER_VALUE */ #ifndef MIN_INTEGER_VALUE +#if INT128_EXTENSIONS_ALLOWED +#define MIN_INTEGER_VALUE (-MAX_INTEGER_VALUE-1) +#else /* !INT128_EXTENSIONS_ALLOWED */ #if LONG_LONG_ALLOWED #if defined(LLONG_MIN) && LLONG_MIN < LLONG_MAX /*lint !e30*/ /* 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; #else /* !LONG_LONG_ALLOWED */ #define MIN_INTEGER_VALUE LONG_MIN #endif /* LONG_LONG_ALLOWED */ +#endif /* INT128_EXTENSIONS_ALLOWED */ #endif /* ifndef MIN_INTEGER_VALUE */ #ifndef MAX_UNSIGNED_INTEGER_VALUE +#if INT128_EXTENSIONS_ALLOWED +#define MAX_UNSIGNED_INTEGER_VALUE (~(__uint128_t)0) +#else /* !INT128_EXTENSIONS_ALLOWED */ #if LONG_LONG_ALLOWED #ifdef ULLONG_MAX #define MAX_UNSIGNED_INTEGER_VALUE ULLONG_MAX @@ -1569,6 +1580,7 @@ typedef TYPE_FOR_A_SIGNED_INTEGER_VALUE a_signed_integer_value; #else /* !LONG_LONG_ALLOWED */ #define MAX_UNSIGNED_INTEGER_VALUE ULONG_MAX #endif /* LONG_LONG_ALLOWED */ +#endif /* INT128_EXTENSIONS_ALLOWED */ #endif /* ifndef MAX_UNSIGNED_INTEGER_VALUE */ #ifndef BITS_IN_AN_INTEGER_VALUE #define BITS_IN_AN_INTEGER_VALUE (sizeof(an_integer_value) * CHAR_BIT) From 2075e41d81e7646e2482cb604365f6415a7fb2b8 Mon Sep 17 00:00:00 2001 From: Mohit Mishra Date: Tue, 20 Oct 2026 01:47:30 +0530 Subject: [PATCH 2/3] Add a test for 128-bit integer value limits. [GH #38] --- tests/tests/changes/.GH38.rto/default.1.1.txt | 30 +++++++++++++++++++ tests/tests/changes/GH38.sft.cpp | 25 ++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 tests/tests/changes/.GH38.rto/default.1.1.txt create mode 100644 tests/tests/changes/GH38.sft.cpp diff --git a/tests/tests/changes/.GH38.rto/default.1.1.txt b/tests/tests/changes/.GH38.rto/default.1.1.txt new file mode 100644 index 0000000000..63ab4be7be --- /dev/null +++ b/tests/tests/changes/.GH38.rto/default.1.1.txt @@ -0,0 +1,30 @@ +fe_only -DTEST_NUMBER=1 --gnu_version 150200 Test_name.c +"Test_name.c", line 22: error: expression must have a constant value + static_assert(max + 1 != 0, ""); // Error: overflow + ^ +"Test_name.c", line 22: note: value exceeds range of "__int128" + static_assert(max + 1 != 0, ""); // Error: overflow + ^ + +"Test_name.c", line 23: error: expression must have a constant value + static_assert(min / -1 != 0, ""); // Error: overflow + ^ +"Test_name.c", line 23: note: integer operation result is out of range + static_assert(min / -1 != 0, ""); // Error: overflow + ^ + +"Test_name.c", line 24: error: expression must have a constant value + static_assert(max * 2 != 0, ""); // Error: overflow + ^ +"Test_name.c", line 24: note: value exceeds range of "__int128" + static_assert(max * 2 != 0, ""); // Error: overflow + ^ + +"Test_name.c", line 25: error: expression must have a constant value + static_assert(min * 2 != 0, ""); // Error: overflow + ^ +"Test_name.c", line 25: note: value exceeds range of "__int128" + static_assert(min * 2 != 0, ""); // Error: overflow + ^ + +4 errors detected in the compilation of "Test_name.c". diff --git a/tests/tests/changes/GH38.sft.cpp b/tests/tests/changes/GH38.sft.cpp new file mode 100644 index 0000000000..2cac03be85 --- /dev/null +++ b/tests/tests/changes/GH38.sft.cpp @@ -0,0 +1,25 @@ +//type:fn +//options:--gnu_version 150200 +//remark:[GH #38] Integer value limits for a 128-bit host integer representation +// 10/20/26 [GH #38] +// +// Constant arithmetic on __int128 values that do not fit in 64 bits is +// accepted, and overflow of the 128-bit range is still diagnosed. + +constexpr __int128 s = (__int128)1 << 100; +static_assert(s * 4 == ((__int128)1 << 102), ""); +static_assert(-s * 4 == -((__int128)1 << 102), ""); + +constexpr unsigned __int128 u = (unsigned __int128)1 << 100; +static_assert(u * 4 == ((unsigned __int128)1 << 102), ""); +static_assert(u + u == ((unsigned __int128)1 << 101), ""); + +constexpr __int128 max = (__int128)(~(unsigned __int128)0 >> 1); +constexpr __int128 min = -max - 1; +static_assert(max / 3 * 3 + 1 == max, ""); +static_assert(min + 1 == -max, ""); + +static_assert(max + 1 != 0, ""); // Error: overflow +static_assert(min / -1 != 0, ""); // Error: overflow +static_assert(max * 2 != 0, ""); // Error: overflow +static_assert(min * 2 != 0, ""); // Error: overflow From 00886bf34e2e48d77d67cb67cf00a2cba7914dad Mon Sep 17 00:00:00 2001 From: Mohit Mishra Date: Tue, 20 Oct 2026 03:13:36 +0530 Subject: [PATCH 3/3] Require __int128 extensions for the GH38 test. [GH #38] --- tests/expectations/edg_x86_32/changes.log | 1 + tests/expectations/edg_x86_32_cp/changes.log | 1 + tests/tests/changes/.GH38.rto/default.1.1.txt | 16 ++++++++-------- tests/tests/changes/GH38.sft.cpp | 1 + 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/tests/expectations/edg_x86_32/changes.log b/tests/expectations/edg_x86_32/changes.log index 9b9b36c1f5..654399e798 100644 --- a/tests/expectations/edg_x86_32/changes.log +++ b/tests/expectations/edg_x86_32/changes.log @@ -7,3 +7,4 @@ EDGcpfe28436.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:[6.8] GNU/clang compatibility: larg EDGcpfe28794.sft.cpp:fp:-DTEST_NUMBER=1:REQUIREMENTS NOT MET:Abort on __builtin_bit_cast in dependent context EDGcpfe8330.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:[4.1] Microsoft compatibility: Calling conventions and pointer-to-member-function EDGcpfe9522.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:[4.1] Microsoft compatibility: __ptr64 on 64-bit targets +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 diff --git a/tests/expectations/edg_x86_32_cp/changes.log b/tests/expectations/edg_x86_32_cp/changes.log index cd68db0c8f..8e5aac7971 100644 --- a/tests/expectations/edg_x86_32_cp/changes.log +++ b/tests/expectations/edg_x86_32_cp/changes.log @@ -13,3 +13,4 @@ EDGcpfe28436.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:[6.8] GNU/clang compatibility: larg EDGcpfe28794.sft.cpp:fp:-DTEST_NUMBER=1:REQUIREMENTS NOT MET:Abort on __builtin_bit_cast in dependent context EDGcpfe8330.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:[4.1] Microsoft compatibility: Calling conventions and pointer-to-member-function EDGcpfe9522.sft.cpp:fp:-DTEST_NUMBER=1:FAIL:[4.1] Microsoft compatibility: __ptr64 on 64-bit targets +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 diff --git a/tests/tests/changes/.GH38.rto/default.1.1.txt b/tests/tests/changes/.GH38.rto/default.1.1.txt index 63ab4be7be..d9ee2a46a1 100644 --- a/tests/tests/changes/.GH38.rto/default.1.1.txt +++ b/tests/tests/changes/.GH38.rto/default.1.1.txt @@ -1,29 +1,29 @@ fe_only -DTEST_NUMBER=1 --gnu_version 150200 Test_name.c -"Test_name.c", line 22: error: expression must have a constant value +"Test_name.c", line 23: error: expression must have a constant value static_assert(max + 1 != 0, ""); // Error: overflow ^ -"Test_name.c", line 22: note: value exceeds range of "__int128" +"Test_name.c", line 23: note: value exceeds range of "__int128" static_assert(max + 1 != 0, ""); // Error: overflow ^ -"Test_name.c", line 23: error: expression must have a constant value +"Test_name.c", line 24: error: expression must have a constant value static_assert(min / -1 != 0, ""); // Error: overflow ^ -"Test_name.c", line 23: note: integer operation result is out of range +"Test_name.c", line 24: note: integer operation result is out of range static_assert(min / -1 != 0, ""); // Error: overflow ^ -"Test_name.c", line 24: error: expression must have a constant value +"Test_name.c", line 25: error: expression must have a constant value static_assert(max * 2 != 0, ""); // Error: overflow ^ -"Test_name.c", line 24: note: value exceeds range of "__int128" +"Test_name.c", line 25: note: value exceeds range of "__int128" static_assert(max * 2 != 0, ""); // Error: overflow ^ -"Test_name.c", line 25: error: expression must have a constant value +"Test_name.c", line 26: error: expression must have a constant value static_assert(min * 2 != 0, ""); // Error: overflow ^ -"Test_name.c", line 25: note: value exceeds range of "__int128" +"Test_name.c", line 26: note: value exceeds range of "__int128" static_assert(min * 2 != 0, ""); // Error: overflow ^ diff --git a/tests/tests/changes/GH38.sft.cpp b/tests/tests/changes/GH38.sft.cpp index 2cac03be85..b4783bf723 100644 --- a/tests/tests/changes/GH38.sft.cpp +++ b/tests/tests/changes/GH38.sft.cpp @@ -1,5 +1,6 @@ //type:fn //options:--gnu_version 150200 +//require:INT128_EXTENSIONS_ALLOWED 1 //remark:[GH #38] Integer value limits for a 128-bit host integer representation // 10/20/26 [GH #38] //