From: Jose E. Marchesi Date: Sun, 5 Jul 2026 10:25:28 +0000 (+0200) Subject: a68: check for overflow in bits denotations X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=726353ff4e49a057376fb6b2e5b241aa1ba391b3;p=thirdparty%2Fgcc.git a68: check for overflow in bits denotations Signed-off-by: Jose E. Marchesi gcc/algol68/ChangeLog * a68-low-units.cc (a68_lower_denotation): Check for denotations too big for bits modes. gcc/testsuite/ChangeLog * algol68/compile/error-bits-denotation-1.a68: New test. * algol68/execute/and-bits-1.a68: Fix invalid bits denotations. * algol68/execute/bits-shift-2.a68: Likewise. * algol68/execute/bits-shift-3.a68: Likewise. * algol68/execute/not-bits-1.a68: Likewise. * algol68/execute/or-bits-1.a68: Likewise. --- diff --git a/gcc/algol68/a68-low-units.cc b/gcc/algol68/a68-low-units.cc index e3650aea952..ed92a1fd517 100644 --- a/gcc/algol68/a68-low-units.cc +++ b/gcc/algol68/a68-low-units.cc @@ -302,6 +302,14 @@ a68_lower_denotation (NODE_T *p, LOW_CTX_T ctx) uint64_t val = strtoull (end, &end, radix); #endif gcc_assert (errno == 0 && end[0] == '\0'); + + uint64_t max_positive = uint64_t (wi::max_value (type).to_uhwi ()); + if (errno == ERANGE || val > max_positive) + { + a68_moid_format_token m (moid); + a68_error (s, "denotation is too large for %e", &m); + } + return build_int_cst (type, val); } else if (moid == M_REAL diff --git a/gcc/testsuite/algol68/compile/error-bits-denotation-1.a68 b/gcc/testsuite/algol68/compile/error-bits-denotation-1.a68 new file mode 100644 index 00000000000..455007c2905 --- /dev/null +++ b/gcc/testsuite/algol68/compile/error-bits-denotation-1.a68 @@ -0,0 +1,6 @@ +begin short short bits a + = short short 10r256; { dg-error "denotation is too large for short short bits" } + short bits b + = short 16rffff1; { dg-error "denotation is too large for short bits" } + skip +end diff --git a/gcc/testsuite/algol68/execute/and-bits-1.a68 b/gcc/testsuite/algol68/execute/and-bits-1.a68 index e6530bcdfb0..ece00717c32 100644 --- a/gcc/testsuite/algol68/execute/and-bits-1.a68 +++ b/gcc/testsuite/algol68/execute/and-bits-1.a68 @@ -12,7 +12,7 @@ BEGIN BITS b = 16r0f0f0; SHORT BITS ss = SHORT 16r0f0f0; ASSERT ((ss AND SHORT 16r0f0f) = SHORT 16r0); ASSERT ((ss AND SHORT 16r00ff) = SHORT 16rf0); - SHORT SHORT BITS sss = SHORT SHORT 16r0f0f0; - ASSERT ((sss AND SHORT SHORT 16r0f0f) = SHORT SHORT 16r0); - ASSERT ((sss AND SHORT SHORT 16r00ff) = SHORT SHORT 16rf0) + SHORT SHORT BITS sss = SHORT SHORT 16rf0; + ASSERT ((sss AND SHORT SHORT 16r0f) = SHORT SHORT 16r0); + ASSERT ((sss AND SHORT SHORT 16rff) = SHORT SHORT 16rf0) END diff --git a/gcc/testsuite/algol68/execute/bits-shift-2.a68 b/gcc/testsuite/algol68/execute/bits-shift-2.a68 index e946b978728..d3a0d1f6281 100644 --- a/gcc/testsuite/algol68/execute/bits-shift-2.a68 +++ b/gcc/testsuite/algol68/execute/bits-shift-2.a68 @@ -1,24 +1,24 @@ { Shifting by L_bits_width results in all bits being zero. } -begin assert (short short 16rffff SHR short_short_bits_width = short short 16r0); +begin assert (short short 16rff SHR short_short_bits_width = short short 16r0); assert (short 16rffff SHR short_bits_width = short 16r0); assert (16rffff SHR bits_width = 16r0); assert (long 16rffff SHR long_bits_width = long 16r0); assert (long long 16rffff SHR long_long_bits_width = long long 16r0); - assert (short short 16rffff SHR -short_short_bits_width = short short 16r0); + assert (short short 16rff SHR -short_short_bits_width = short short 16r0); assert (short 16rffff SHR -short_bits_width = short 16r0); assert (16rffff SHR -bits_width = 16r0); assert (long 16rffff SHR -long_bits_width = long 16r0); assert (long long 16rffff SHR -long_long_bits_width = long long 16r0); - assert (short short 16rffff SHL short_short_bits_width = short short 16r0); + assert (short short 16rff SHL short_short_bits_width = short short 16r0); assert (short 16rffff SHL short_bits_width = short 16r0); assert (16rffff SHL bits_width = 16r0); assert (long 16rffff SHL long_bits_width = long 16r0); assert (long long 16rffff SHL long_long_bits_width = long long 16r0); - assert (short short 16rffff SHL -short_short_bits_width = short short 16r0); + assert (short short 16rff SHL -short_short_bits_width = short short 16r0); assert (short 16rffff SHL -short_bits_width = short 16r0); assert (16rffff SHL -bits_width = 16r0); assert (long 16rffff SHL -long_bits_width = long 16r0); diff --git a/gcc/testsuite/algol68/execute/bits-shift-3.a68 b/gcc/testsuite/algol68/execute/bits-shift-3.a68 index b4536dc4368..12dd342ae2d 100644 --- a/gcc/testsuite/algol68/execute/bits-shift-3.a68 +++ b/gcc/testsuite/algol68/execute/bits-shift-3.a68 @@ -1,24 +1,24 @@ { Shifting by > L_bits_width results in all bits being zero. } -begin assert (short short 16rffff SHR (short_short_bits_width + 1) = short short 16r0); +begin assert (short short 16rff SHR (short_short_bits_width + 1) = short short 16r0); assert (short 16rffff SHR (short_bits_width + 1) = short 16r0); assert (16rffff SHR (bits_width + 1) = 16r0); assert (long 16rffff SHR (long_bits_width + 1) = long 16r0); assert (long long 16rffff SHR (long_long_bits_width + 1) = long long 16r0); - assert (short short 16rffff SHR -(short_short_bits_width + 1) = short short 16r0); + assert (short short 16rff SHR -(short_short_bits_width + 1) = short short 16r0); assert (short 16rffff SHR -(short_bits_width + 1) = short 16r0); assert (16rffff SHR -(bits_width + 1) = 16r0); assert (long 16rffff SHR -(long_bits_width + 1) = long 16r0); assert (long long 16rffff SHR -(long_long_bits_width + 1) = long long 16r0); - assert (short short 16rffff SHL (short_short_bits_width + 1) = short short 16r0); + assert (short short 16rff SHL (short_short_bits_width + 1) = short short 16r0); assert (short 16rffff SHL (short_bits_width + 1) = short 16r0); assert (16rffff SHL (bits_width + 1) = 16r0); assert (long 16rffff SHL (long_bits_width + 1) = long 16r0); assert (long long 16rffff SHL (long_long_bits_width + 1) = long long 16r0); - assert (short short 16rffff SHL -(short_short_bits_width + 1) = short short 16r0); + assert (short short 16rff SHL -(short_short_bits_width + 1) = short short 16r0); assert (short 16rffff SHL -(short_bits_width + 1) = short 16r0); assert (16rffff SHL -(bits_width + 1) = 16r0); assert (long 16rffff SHL -(long_bits_width + 1) = long 16r0); diff --git a/gcc/testsuite/algol68/execute/not-bits-1.a68 b/gcc/testsuite/algol68/execute/not-bits-1.a68 index 8334f7f7a7f..ee461d919dc 100644 --- a/gcc/testsuite/algol68/execute/not-bits-1.a68 +++ b/gcc/testsuite/algol68/execute/not-bits-1.a68 @@ -8,6 +8,6 @@ BEGIN BITS b = 16rf0f0; ASSERT ((NOT bbb AND LONG LONG 16rffff) = LONG LONG 16r0f0f); SHORT BITS ss = SHORT 16rf0f0; ASSERT ((NOT ss AND SHORT 16rffff) = SHORT 16r0f0f); - SHORT SHORT BITS sss = SHORT SHORT 16rf0f0; - ASSERT ((NOT sss AND SHORT SHORT 16rffff) = SHORT SHORT 16r0f0f) + SHORT SHORT BITS sss = SHORT SHORT 16rf0; + ASSERT ((NOT sss AND SHORT SHORT 16rff) = SHORT SHORT 16r0f) END diff --git a/gcc/testsuite/algol68/execute/or-bits-1.a68 b/gcc/testsuite/algol68/execute/or-bits-1.a68 index 4fc1b06225d..945c22a4170 100644 --- a/gcc/testsuite/algol68/execute/or-bits-1.a68 +++ b/gcc/testsuite/algol68/execute/or-bits-1.a68 @@ -12,7 +12,7 @@ BEGIN BITS b = 16rf0f0; SHORT BITS ss = SHORT 16rf0f0; ASSERT ((ss OR SHORT 16r0f0f) = SHORT 16rffff); ASSERT ((ss OR SHORT 16r00ff) = SHORT 16rf0ff); - SHORT SHORT BITS sss = SHORT SHORT 16rf0f0; - ASSERT ((sss OR SHORT SHORT 16r0f0f) = SHORT SHORT 16rffff); - ASSERT ((sss OR SHORT SHORT 16r00ff) = SHORT SHORT 16rf0ff) + SHORT SHORT BITS sss = SHORT SHORT 16rf0; + ASSERT ((sss OR SHORT SHORT 16r0f) = SHORT SHORT 16rff); + ASSERT ((sss OR SHORT SHORT 16rff) = SHORT SHORT 16rff) END