From a20a82c41732ecbdd9fe9f4359844bfea4698bf6 Mon Sep 17 00:00:00 2001 From: Graeme Geldenhuys Date: Fri, 26 Jun 2026 18:30:53 +0100 Subject: [PATCH] fix(asm): brace-comment strip must skip quoted strings The asm brace-comment strip (added with the threads leaf to remove {...} comments the lexer leaves inside asm blocks) ran over the WHOLE line, including inside .ascii string literals. The native backend emits string-const data as .ascii directives, and the compiler's own codegen contains template strings with literal braces (e.g. codegen.qbe.pas's 'data $__s%d = { w -1, w %d, w %d, b "%s", b 0 }'). When the compiler was assembled by the internal assembler, the strip ate the '{ ... }' span out of those .ascii literals, corrupting the template strings. The damage only showed when the compiler ran --emit-ir / GenerateIR: the corrupted template produced garbage data lines (data $__s0 = ), so the ~1240 IR-assertion tests failed (TestHelloWorld_HasStrLitData etc.). Compiled user programs were unaffected (their own Format/strings come from freshly built RTL), and the QBE-built compiler was unaffected (gcc assembles its .ascii), which is why local QBE fixpoints stayed green while the CI native-internal TestRunner went red. Fix: skip over quoted strings in the brace strip, exactly as the adjacent '#'-comment strip already does, so a brace inside a .ascii literal is left intact. Root-caused from the CI failure on ci/linux-direct-syscalls; the corruption is visible as -clean but -garbled string data from a native-internal-assembled compiler. --- .../main/pascal/blaise.assembler.x86_64.pas | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/compiler/src/main/pascal/blaise.assembler.x86_64.pas b/compiler/src/main/pascal/blaise.assembler.x86_64.pas index 93edb81..35f5872 100644 --- a/compiler/src/main/pascal/blaise.assembler.x86_64.pas +++ b/compiler/src/main/pascal/blaise.assembler.x86_64.pas @@ -670,11 +670,30 @@ begin { Strip a brace comment (open/close = ASCII 123/125) that survived the lexer: a whole-line or trailing comment inside an asm block. Single line only; remove the span from the open brace to the matching close brace, or to end - of line when unterminated. } + of line when unterminated. Skip over quoted strings so that a brace INSIDE + a .ascii string literal (the string-const data the native backend emits) is + left intact rather than mistaken for a comment. } P := 0; while P < Length(S) do begin - if S[P] = 123 then + if S[P] = Ord('"') then + begin + { Skip the whole quoted string, honouring \" escapes. } + P := P + 1; + while P < Length(S) do + begin + if S[P] = Ord('\') then + P := P + 2 + else if S[P] = Ord('"') then + begin + P := P + 1; + Break; + end + else + P := P + 1; + end; + end + else if S[P] = 123 then begin Q := P + 1; while (Q < Length(S)) and (S[Q] <> 125) do