[COMMITTED] algol68: fix BIN of negative values in strict algol 68 programs

Jose E. Marchesi jemarch@gnu.org
Fri Mar 14 11:00:21 GMT 2025


The BIN standard operator returns an undefined value for negative
integral values.  However, as a GNU extension (enabled by -std=gnu68)
it returns the bit representation of the negative value encoded in
two's complement.
---
 gcc/algol68/a68-low-bits.cc |  9 +++++++--
 gcc/algol68/ga68.texi       | 30 ++++++++++++++++++++++++++++++
 2 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/gcc/algol68/a68-low-bits.cc b/gcc/algol68/a68-low-bits.cc
index f101eef1221..37a9e7b80af 100644
--- a/gcc/algol68/a68-low-bits.cc
+++ b/gcc/algol68/a68-low-bits.cc
@@ -66,8 +66,13 @@ a68_bits_maxbits (tree type)
 tree
 a68_bits_bin (tree type, tree val)
 {
-  /* XXX if no extensions allowed, check and error on negative numbers.  */
-  return fold_convert (type, val);
+  if (OPTION_STRICT (&A68_JOB))
+    /* BIN of a negative value is INT (SKIP).  */
+    return a68_get_skip_tree (a68_type_moid (type));
+  else
+    /* BIN of a negative value is the constituent bits of the two's complement
+       of the value.  */
+    return fold_convert (type, val);
 }
 
 /* Given a SIZETY BITS value BITS, compute and return the corresponding SIZETY
diff --git a/gcc/algol68/ga68.texi b/gcc/algol68/ga68.texi
index 8655ae678aa..3c417e0c522 100644
--- a/gcc/algol68/ga68.texi
+++ b/gcc/algol68/ga68.texi
@@ -1966,6 +1966,36 @@ enabled by default.  To disable them the user can select the strict
 Algol 68 standard by passing the option @option{-std=algol68} when
 invoking the compiler.
 
+@node @code{@B{bin}} of negative integral values
+@section @code{@B{bin}} of negative integral values
+
+The @code{@B{bin}} operator gets an integral value and yields a
+@code{@B{bits}} value that reflects the internal bits of the integral
+value.  The semantics of this operator, as defined in the Algol 68
+standard prelude, are:
+
+@example
+@B{op} @B{bin} = (L @B{int} a) L @B{bits}:
+  @B{if} a >= L 0
+  @B{then} L @B{int} b := a; L @B{bits};
+       @B{for} i @B{from} L bits width @B{by} -1 @B{to} 1
+       @B{do} (L F @B{of} c)[i] := @B{odd} b; b := b % L 2 @B{od};
+       c
+  @B{fi};
+@end example
+
+@noindent
+Note how the @code{@B{bin}} of a negative integral value is not
+defined: the implicit else-part of the conditional yields
+@code{@B{skip}}, which is defined as any integral value.  The GNU
+Algol 68 compiler always yields zero for an integral @code{@B{skip}},
+but strict Algol 68 programs must not rely on this.
+
+When GNU extensions are enabled the @code{@B{bin}} of a negative value
+yields the two's complement bit pattern of the value rather than zero.
+Therefore, @code{@B{bin} - @B{short} @B{short} 2} yields
+@code{2r11111110}.
+
 @include gpl_v3.texi
 @include fdl.texi
 
-- 
2.30.2



More information about the Algol68 mailing list