a68: fix string and character multiplication

This patch fixes the string operator for string and character
multiplication, to adjust to the semantics specified by the RR.  In
particular, multiplying by a negative number or zero must result in
the empty string.

Signed-off-by: Jose E. Marchesi <jemarch@gnu.org>

gcc/algol68/ChangeLog

	* a68-low-strings.cc (a68_string_mult): Adjust to RR semantics for
	negative or zero factor argument.
	* ga68.texi (String operators): Adjust documentation accordingly.

gcc/testsuite/ChangeLog

	* algol68/execute/mult-char-1.a68: Multiplying a char or string by
	negative or zero factor results in the empty string.
	* algol68/execute/mult-string-3.a68: Likewise.
	* algol68/execute/mult-string-2.a68: Likewise.
	* algol68/execute/mult-string-1.a68: Likewise.
This commit is contained in:
Jose E. Marchesi
2026-03-14 16:57:08 +01:00
parent 1315e1877e
commit 83b35da8f5
6 changed files with 25 additions and 20 deletions

View File

@@ -191,16 +191,19 @@ a68_string_mult (tree str, tree factor)
str = save_expr (str);
tree ssize_one_node = ssize_int (1);
tree res = a68_lower_tmpvar ("res%", CTYPE (M_STRING), str);
tree res = a68_lower_tmpvar ("res%", CTYPE (M_STRING),
fold_build1 (INDIRECT_REF, CTYPE(M_STRING),
a68_low_gen (M_STRING, 0, NULL,
false /* use_heap */)));
tree index = a68_lower_tmpvar ("index%", ssizetype, ssize_one_node);
/* Begin of loop body. */
a68_push_range (NULL);
/* if (index == FACTOR) break; */
/* if (index > FACTOR) break; */
a68_add_stmt (fold_build1 (EXIT_EXPR,
void_type_node,
fold_build2 (GE_EXPR, ssizetype,
fold_build2 (GT_EXPR, ssizetype,
index,
fold_convert (ssizetype, factor))));

View File

@@ -2754,9 +2754,9 @@ Dyadic operator that yields the concatenation of the given string
@deftypefn Operator {} {*} (= (@B{int} a, @B{string} b) @B{string})
@deftypefnx Operator {} {*} (= (@B{string} b, @B{int} a) @B{string})
Dyadic operator that yields the string @code{a} concatenated @code{a}
times to itself. If @code{a} is less than zero then it is interpreted
to be zero.
Dyadic operator that yields the string composed of @code{a}
concatenated copies of @code{b}. If @code{a} is less than zero then
it is interpreted to be zero.
@end deftypefn
@subsection Composition combined with assignation

View File

@@ -1,8 +1,10 @@
# { dg-options "-fstropping=upper" } #
BEGIN ASSERT ("a" * 3 = "aaa");
ASSERT ("" * 1 = "");
ASSERT ("x" * 0 = "x");
ASSERT ("x" * -1= "");
ASSERT ("x" * 0 = "");
ASSERT (3 * "a" = "aaa");
ASSERT (1 * "" = "");
ASSERT (0 * "x" = "x")
ASSERT (0 * "x" = "");
ASSERT (-20 * "" = "")
END

View File

@@ -1,9 +1,9 @@
# { dg-options "-fstropping=upper" } #
BEGIN STRING foo = "foo";
ASSERT (foo * -10 = "foo");
ASSERT (-10 * foo = "foo");
ASSERT (foo * 0 = "foo");
ASSERT (0 * foo = "foo");
ASSERT (foo * -10 = "");
ASSERT (-10 * foo = "");
ASSERT (foo * 0 = "");
ASSERT (0 * foo = "");
ASSERT (foo * 1 = "foo");
ASSERT (1 * foo = "foo");
ASSERT (foo * 2 = "foofoo");

View File

@@ -1,9 +1,9 @@
# { dg-options "-fstropping=upper" } #
BEGIN []CHAR foo = ("f","o","o");
ASSERT (foo * -10 = "foo");
ASSERT (-10 * foo = "foo");
ASSERT (foo * 0 = "foo");
ASSERT (0 * foo = "foo");
ASSERT (foo * -10 = "");
ASSERT (-10 * foo = "");
ASSERT (foo * 0 = "");
ASSERT (0 * foo = "");
ASSERT (foo * 1 = "foo");
ASSERT (1 * foo = "foo");
ASSERT (foo * 2 = "foofoo");

View File

@@ -1,9 +1,9 @@
# { dg-options "-fstropping=upper" } #
BEGIN FLEX[3]CHAR foo := ("f","o","o");
ASSERT (foo * -10 = "foo");
ASSERT (-10 * foo = "foo");
ASSERT (foo * 0 = "foo");
ASSERT (0 * foo = "foo");
ASSERT (foo * -10 = "");
ASSERT (-10 * foo = "");
ASSERT (foo * 0 = "");
ASSERT (0 * foo = "");
ASSERT (foo * 1 = "foo");
ASSERT (1 * foo = "foo");
ASSERT (foo * 2 = "foofoo");