diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index e68a78797..14af8bf75 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -873,29 +873,10 @@ static int append_esc_string_token(char *restrict dest, const char *restrict src { int scanned; uint64_t unicode_char; - switch (src[0]) + signed char scanned_char = is_valid_escape(src[0]); + if (scanned_char < 0) return -1; + switch (scanned_char) { - case 'a': - dest[(*pos)++] = '\a'; - return 1; - case 'b': - dest[(*pos)++] = '\b'; - return 1; - case 'e': - dest[(*pos)++] = 0x1b; - return 1; - case 'f': - dest[(*pos)++] = '\f'; - return 1; - case 'n': - dest[(*pos)++] = '\n'; - return 1; - case 'r': - dest[(*pos)++] = '\r'; - return 1; - case 't': - dest[(*pos)++] = '\t'; - return 1; case 'x': { int h = char_to_nibble(src[1]); @@ -933,7 +914,7 @@ static int append_esc_string_token(char *restrict dest, const char *restrict src break; } default: - dest[(*pos)++] = src[0]; + dest[(*pos)++] = scanned_char; return 1; } if (unicode_char < 0x80U) diff --git a/src/utils/lib.h b/src/utils/lib.h index da0c39113..892fb47ff 100644 --- a/src/utils/lib.h +++ b/src/utils/lib.h @@ -176,7 +176,7 @@ static inline bool is_hex_or_(char c) } } -static inline char is_valid_escape(char c) +static inline signed char is_valid_escape(char c) { switch (c) { diff --git a/test/test_suite/strings/string_escape.c3t b/test/test_suite/strings/string_escape.c3t new file mode 100644 index 000000000..e3456960d --- /dev/null +++ b/test/test_suite/strings/string_escape.c3t @@ -0,0 +1,14 @@ +func void main() +{ + char *s = "Hello\0 world!"; +} + +// #expect: string_escape.ll + +@.str = private constant [14 x i8] c"Hello\00 world!\00", align 1 + +define void @main() +entry: + %s = alloca i8*, align 8 + store i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str, i32 0, i32 0), i8** %s, align 8 + ret void