unsigned int object[] = u"\x100";
sdcc --c1mode -mz80 --std=c2y -o bug.asm < bug.c
The source is supplied directly as preprocessed input. No preprocessor is run.
SDCC 4.6.4 #17081 (Linux)
The compiler exits successfully without diagnostics. Its Z80 assembly contains:
__xinit__object:
.byte 0,0
.byte 0,0
The first UTF-16 code unit should have value 256, followed by the zero terminator.
The expected little-endian bytes are 0,1,0,0. The escape is representable as
char16_t; this is valid source, not a required-diagnostic case.
This is separate from the missing range diagnostic in [bugs:#4179]; this sample is within range and must preserve its value.
Using u"\u0100" emits 0,1,0,0 as expected. Using u"A" emits 65,0,0,0.
All three variants were compared on unmodified r17081 and a standalone candidate bugfix for [bugs:#4179]. The numeric-escape defect remains on both. Sources, commands, return codes, logs and generated assembly are in evidence/direct/wide-numeric-escape.json and adjacent files. This observation is based on emitted data; no runtime execution is claimed for this reproducer.
Implementation observation: the existing string decoding path appears to narrow numeric escapes before constructing the wide elements.
Please consider the attached candidate patch to fix this bug. The patch looks large, but that is mostly because an existing function,
utf_32_from_utf_8was moved from src/SDCCval.c to src/SDCCutil.c.An existing comment already said:
Regression tests passed on ucz80. valdiag tests passed on all targets.
The candidate shares escape parsing between byte and wide strings. The wide path produces 32-bit elements directly, preserving numeric code units without a UTF-8 round trip. Numeric UTF-16 escapes retain one 16-bit code unit, including a surrogate value; UTF-32 and SDCC's wchar_t literals retain all 32 bits. Ordinary/u8 strings and inline assembly keep the existing byte path.
The patch includes ChangeLog and a six-case regression test. It changes no diagnostic messages or valdiag expectations and needs no part of the fix for [bugs:#4179]. Both candidates touch string decoding, so the pending [bugs:#4179] patch will need reconciliation if this one is merged first.
Related
Bugs:
#4179How about moving the function to SDCCutil in a first step (along with
utf_16_from_utf_32), then look at the smaller patch for the bugfix?Good idea. The split patches are attached.
The first moves
utf_32_from_utf_8andutf_16_from_utf_32to SDCCutil.c. Function bodies are unchanged; only static linkage and the obsolete TODO comments are removed. Both declarations are added to SDCCutil.h.The second uses
parseEscapeandescapeValueInRangefrom the patch for [bugs:#4179] before storing wide numeric code units. Ordinary/u8 strings keepcopyStrWithEscapeLimit; inline assembly keeps unrestrictedcopyStr. A shared internal decoder supports byte and wide output. Wide numeric escapes no longer pass through a byte buffer or get interpreted as UTF-8. All 16-bit numeric units, including surrogate values, are preserved. Existing Unicode-range warnings for universal escapes are also retained. Numeric UTF-32 values above the Unicode range remain permitted; universal escapes and numeric escapes have different rules.Related
Bugs:
#4179Last edit: Christopher Bazley 1 day ago
First patch is ok; I'll look at the second later this week.
Thanks for the review. The first patch is now committed as [r17136].
Related
Commit: [r17136]