[COMMITTED] a68: error rather than ICE on invalid Unicode points in string breaks
Jose E. Marchesi
jemarch@gnu.org
Fri Oct 31 12:17:09 GMT 2025
The string break '(...) is used to specify a list of characters having
some given unicode points, in the form of uXXXX or UXXXXXXXX.
However, not every four digits nor eight digits hexadecimal numbers
are actual valid Unicode codepoints.
The compiler checks for the validity of the specific codepoints, but
it was emitting an ICE in case these would not be valid ones. This
patch changes this so now we emit a proper error like:
/home/jemarch/foo.a68:2:25: error: invalid Unicode codepoint in string literal
2 | fputs (f, " '(Uf09f94a5)");
---
gcc/algol68/a68-low-strings.cc | 19 ++++++++++++++-----
gcc/algol68/a68-low-units.cc | 4 ++--
gcc/algol68/a68.h | 2 +-
.../algol68/compile/error-string-break-8.a68 | 4 ++++
4 files changed, 21 insertions(+), 8 deletions(-)
create mode 100644 gcc/testsuite/algol68/compile/error-string-break-8.a68
diff --git a/gcc/algol68/a68-low-strings.cc b/gcc/algol68/a68-low-strings.cc
index f9fdd56febd..f5822037e33 100644
--- a/gcc/algol68/a68-low-strings.cc
+++ b/gcc/algol68/a68-low-strings.cc
@@ -102,7 +102,7 @@ copy_string (tree elements, tree to_index, tree str)
/* from_index = from_index + 1 */
a68_add_stmt (fold_build2 (POSTINCREMENT_EXPR, sizetype, from_index, size_one_node));
- }
+ }
/* End of loop body. */
tree loop_body = a68_pop_range ();
@@ -133,7 +133,7 @@ a68_string_concat (tree str1, tree str2)
tree s1 = a68_low_func_param (string_concat_fndecl, "s1", TREE_TYPE (str1));
tree s2 = a68_low_func_param (string_concat_fndecl, "s2", TREE_TYPE (str2));
DECL_ARGUMENTS (string_concat_fndecl) = chainon (s1, s2);
-
+
a68_push_function_range (string_concat_fndecl, char_pointer_type,
true /* top_level */);
@@ -271,10 +271,12 @@ a68_string_cmp (tree s1, tree s2)
/* Return a newly allocated UTF-8 string resulting from processing the string
breaks in STR. This function assumes the passed string is well-formed (the
- scanner is in charge of seeing that is true) and just ICEs if it is not. */
+ scanner is in charge of seeing that is true) and just ICEs if it is not.
+ NODE is used as the location for diagnostics in case the string breaks
+ contain some invalid data. */
char *
-a68_string_process_breaks (const char *str)
+a68_string_process_breaks (NODE_T *node, const char *str)
{
size_t len = 0;
char *res = NULL;
@@ -362,6 +364,7 @@ a68_string_process_breaks (const char *str)
gcc_assert (p[0] == 'u' || p[0] == 'U');
p++;
+ const char *begin = p;
char *end;
int64_t codepoint = strtol (p, &end, 16);
gcc_assert (end > p);
@@ -369,7 +372,13 @@ a68_string_process_breaks (const char *str)
/* Append the UTF-8 encoding of the obtained codepoint to
the `res' string. */
int n = a68_u8_uctomb ((uint8_t *) res + offset, codepoint, 6);
- gcc_assert (n > 0);
+ if (n < 0)
+ {
+ char *start = CHAR_IN_LINE (INFO (node)) + (begin - str);
+ a68_scan_error (LINE (INFO (node)), start,
+ "invalid Unicode codepoint in string literal");
+ }
+
offset += n;
}
break;
diff --git a/gcc/algol68/a68-low-units.cc b/gcc/algol68/a68-low-units.cc
index 85a94a8b0ac..66eba1f57d4 100644
--- a/gcc/algol68/a68-low-units.cc
+++ b/gcc/algol68/a68-low-units.cc
@@ -122,7 +122,7 @@ tree
a68_lower_string_denotation (NODE_T *p, LOW_CTX_T ctx ATTRIBUTE_UNUSED)
{
/* First process string breaks. */
- char *str = a68_string_process_breaks (NSYMBOL (p));
+ char *str = a68_string_process_breaks (p, NSYMBOL (p));
/* Build a multiple of UCS-4 CHARs from the resulting UTF-8 string. */
size_t ucslen;
@@ -173,7 +173,7 @@ a68_lower_denotation (NODE_T *p, LOW_CTX_T ctx)
return (NSYMBOL (p)[0] == 'T') ? boolean_true_node : boolean_false_node;
else if (moid == M_CHAR)
{
- char *s = a68_string_process_breaks (NSYMBOL (p));
+ char *s = a68_string_process_breaks (p, NSYMBOL (p));
uint32_t ucs;
int length = a68_u8_mbtouc (&ucs, (const uint8_t *) s, 1);
gcc_assert (length == 1);
diff --git a/gcc/algol68/a68.h b/gcc/algol68/a68.h
index ad0fdba9c50..b6ab4ab67fa 100644
--- a/gcc/algol68/a68.h
+++ b/gcc/algol68/a68.h
@@ -611,7 +611,7 @@ tree a68_string_concat (tree str1, tree str2);
tree a68_string_mult (tree str1, tree str2);
tree a68_string_from_char (tree c);
tree a68_string_cmp (tree s1, tree s2);
-char *a68_string_process_breaks (const char *str);
+char *a68_string_process_breaks (NODE_T *p, const char *str);
/* a68-low-chars.cc */
diff --git a/gcc/testsuite/algol68/compile/error-string-break-8.a68 b/gcc/testsuite/algol68/compile/error-string-break-8.a68
new file mode 100644
index 00000000000..dbc96e4e57f
--- /dev/null
+++ b/gcc/testsuite/algol68/compile/error-string-break-8.a68
@@ -0,0 +1,4 @@
+begin string s =
+ "'(Uf09f94a5)"; { dg-error "Unicode" }
+ skip
+end
--
2.30.2
More information about the Algol68
mailing list