Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions cmake/macro-conf/support/platform/linux/base.cmakedef
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
16 changes: 16 additions & 0 deletions src/Changes
Original file line number Diff line number Diff line change
@@ -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

Expand Down
3 changes: 0 additions & 3 deletions src/defines_linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand Down
12 changes: 12 additions & 0 deletions src/targ_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions tests/expectations/edg_x86_32/changes.log
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions tests/expectations/edg_x86_32_cp/changes.log
Original file line number Diff line number Diff line change
Expand Up @@ -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
30 changes: 30 additions & 0 deletions tests/tests/changes/.GH38.rto/default.1.1.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
fe_only -DTEST_NUMBER=1 --gnu_version 150200 Test_name.c
"Test_name.c", line 23: error: expression must have a constant value
static_assert(max + 1 != 0, ""); // Error: overflow
^
"Test_name.c", line 23: note: value exceeds range of "__int128"
static_assert(max + 1 != 0, ""); // Error: overflow
^

"Test_name.c", line 24: error: expression must have a constant value
static_assert(min / -1 != 0, ""); // Error: overflow
^
"Test_name.c", line 24: note: integer operation result is out of range
static_assert(min / -1 != 0, ""); // Error: overflow
^

"Test_name.c", line 25: error: expression must have a constant value
static_assert(max * 2 != 0, ""); // Error: overflow
^
"Test_name.c", line 25: note: value exceeds range of "__int128"
static_assert(max * 2 != 0, ""); // Error: overflow
^

"Test_name.c", line 26: error: expression must have a constant value
static_assert(min * 2 != 0, ""); // Error: overflow
^
"Test_name.c", line 26: note: value exceeds range of "__int128"
static_assert(min * 2 != 0, ""); // Error: overflow
^

4 errors detected in the compilation of "Test_name.c".
26 changes: 26 additions & 0 deletions tests/tests/changes/GH38.sft.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//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]
//
// 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
Loading