1: Sample code that reproduces the problem.
char object = '\x100';
2: Exact command used to run SDCC on this sample code.
sdcc -mz80 --std=c2y --nostdinc -S bug.c -o bug.asm
3: SDCC version tested.
SDCC 4.6.4 #17064 (Linux), tested 21 October 2026.
4: Observed and expected behaviour.
SDCC exits successfully and emits no diagnostic. A diagnostic is required by
WG14 N3886,
6.4.5.5 paragraph 9, also applied to string elements by 6.4.6 paragraph 4.
For an unprefixed character literal, the value of a hexadecimal or octal escape must be representable as unsigned char. SDCC has 8-bit char, so 256 is outside that range. SDCC accepts both \x100 and \400 in character and string literals. Character \xFF and string \177 are valid cases.
5: Additional checks.
The sample is silently accepted on Z80, MCS51 default, STM8 default, PDK14 and MOS65C02 in C2Y mode. These are translation and diagnostic checks; no runtime result is claimed.
Compiler Explorer: SDCC 4.6.0, SDCC trunk and GCC 16.2. All three panes use the sample above. The saved source, compiler selections and options were round-trip verified on 21 October 2026. Both SDCC panes use -mz80 --std=c2y; GCC uses -std=c2y -pedantic-errors -fsyntax-only. The public trunk build is r17013, distinct from the local r17064 retest.
| CE compiler | Observed result |
|---|---|
| SDCC 4.6.0 | Accepted silently |
| SDCC trunk r17013 | Accepted silently |
| GCC 16.2 | Rejected with diagnostics |
| Case | Expected | Current SDCC results |
|---|---|---|
escape-char-control.c |
Valid | Accepted silently on all five targets |
escape-char-hex.c |
Diagnostic required | Accepted silently on all five targets |
escape-char-octal.c |
Diagnostic required | Accepted silently on all five targets |
escape-string-control.c |
Valid | Accepted silently on all five targets |
escape-string-hex.c |
Diagnostic required | Accepted silently on all five targets |
escape-string-octal.c |
Diagnostic required | Accepted silently on all five targets |
Please consider the attached candidate patch, created with Codex. I didn't like the first patch it created (which I briefly attached here) because it added a separate scan that duplicated existing escape sequence parsing and could have diverged in future. This patch might be slightly bigger but it instead consolidates parsing of escape sequences by introducing a pair of new helper functions: parseEscape and escapeValueInRange.
The existing diagnostic W_ESC_SEQ_OOR_FOR_CHAR (warning 137) is reused, but its text is changed from “escape sequence out of range for char.” to “numeric escape sequence out of range" because the check also covers wide and UTF-prefixed character and string literals. The permitted range depends on the literal’s prefix.
The pre-processor logic in the tests was unreasonably complex. This version is simplified.
Looks ok to me (assuming regression tests pass), though I did only read it, not test it.
Thanks for the review. Retested and merged as [r17124].
Related
Commit: [r17124]