Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

astgen: forbid trailing whitespace in multiline strings #20575

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions lib/compiler/aro/aro/Compilation.zig
Original file line number Diff line number Diff line change
Expand Up @@ -534,8 +534,8 @@ pub fn generateBuiltinMacros(comp: *Compilation, system_defines_mode: SystemDefi

if (system_defines_mode == .include_system_defines) {
try buf.appendSlice(
\\#define __VERSION__ "Aro
++ @import("../backend.zig").version_str ++ "\"\n" ++
\\#define __VERSION__ "Aro
++ " " ++ @import("../backend.zig").version_str ++ "\"\n" ++
\\#define __Aro__
\\
);
Expand Down
4 changes: 2 additions & 2 deletions lib/compiler/aro/aro/Driver.zig
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ pub const usage =
\\ -fhosted Compilation in a hosted environment
\\ -fms-extensions Enable support for Microsoft extensions
\\ -fno-ms-extensions Disable support for Microsoft extensions
\\ -fdollars-in-identifiers
\\ -fdollars-in-identifiers
\\ Allow '$' in identifiers
\\ -fno-dollars-in-identifiers
\\ -fno-dollars-in-identifiers
\\ Disallow '$' in identifiers
\\ -fmacro-backtrace-limit=<limit>
\\ Set limit on how many macro expansion traces are shown in errors (default 6)
Expand Down
10 changes: 5 additions & 5 deletions lib/compiler/aro/aro/Tokenizer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1871,11 +1871,11 @@ test "operators" {
test "keywords" {
try expectTokens(
\\auto __auto_type break case char const continue default do
\\double else enum extern float for goto if int
\\long register return short signed sizeof static
\\struct switch typedef union unsigned void volatile
\\while _Bool _Complex _Imaginary inline restrict _Alignas
\\_Alignof _Atomic _Generic _Noreturn _Static_assert _Thread_local
\\double else enum extern float for goto if int
\\long register return short signed sizeof static
\\struct switch typedef union unsigned void volatile
\\while _Bool _Complex _Imaginary inline restrict _Alignas
\\_Alignof _Atomic _Generic _Noreturn _Static_assert _Thread_local
\\__attribute __attribute__
\\
, &.{
Expand Down
5 changes: 2 additions & 3 deletions lib/compiler/resinator/comments.zig
Original file line number Diff line number Diff line change
Expand Up @@ -322,11 +322,10 @@ test "multiline comment with newlines" {

test "comments appended to a line" {
try testRemoveComments(
\\blah
\\blah
,
"blah \nblah",
\\blah // line comment
\\blah
,
);
try testRemoveComments(
"blah \r\nblah",
Expand Down
24 changes: 11 additions & 13 deletions lib/std/compress/xz/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,17 @@ test "compressed data" {
"good-1-lzma2-3.xz",
"good-1-lzma2-4.xz",
}) |filename| {
try testReader(@embedFile("testdata/" ++ filename),
\\Lorem ipsum dolor sit amet, consectetur adipisicing
\\elit, sed do eiusmod tempor incididunt ut
\\labore et dolore magna aliqua. Ut enim
\\ad minim veniam, quis nostrud exercitation ullamco
\\laboris nisi ut aliquip ex ea commodo
\\consequat. Duis aute irure dolor in reprehenderit
\\in voluptate velit esse cillum dolore eu
\\fugiat nulla pariatur. Excepteur sint occaecat cupidatat
\\non proident, sunt in culpa qui officia
\\deserunt mollit anim id est laborum.
\\
);
try testReader(@embedFile("testdata/" ++ filename), "" ++
"Lorem ipsum dolor sit amet, consectetur adipisicing \n" ++
"elit, sed do eiusmod tempor incididunt ut \n" ++
"labore et dolore magna aliqua. Ut enim \n" ++
"ad minim veniam, quis nostrud exercitation ullamco \n" ++
"laboris nisi ut aliquip ex ea commodo \n" ++
"consequat. Duis aute irure dolor in reprehenderit \n" ++
"in voluptate velit esse cillum dolore eu \n" ++
"fugiat nulla pariatur. Excepteur sint occaecat cupidatat \n" ++
"non proident, sunt in culpa qui officia \n" ++
"deserunt mollit anim id est laborum. \n");
}

try testReader(@embedFile("testdata/good-1-lzma2-5.xz"), "");
Expand Down
16 changes: 16 additions & 0 deletions lib/std/zig/AstGen.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11679,6 +11679,7 @@ fn strLitNodeAsString(astgen: *AstGen, node: Ast.Node.Index) !IndexSlice {
const slice = tree.tokenSlice(tok_i);
const carriage_return_ending: usize = if (slice[slice.len - 2] == '\r') 2 else 1;
const line_bytes = slice[2 .. slice.len - carriage_return_ending];
try astgen.strLitNodeCheckTrailingWhitespace(tok_i, line_bytes);
try string_bytes.appendSlice(gpa, line_bytes);
tok_i += 1;
}
Expand All @@ -11687,6 +11688,7 @@ fn strLitNodeAsString(astgen: *AstGen, node: Ast.Node.Index) !IndexSlice {
const slice = tree.tokenSlice(tok_i);
const carriage_return_ending: usize = if (slice[slice.len - 2] == '\r') 2 else 1;
const line_bytes = slice[2 .. slice.len - carriage_return_ending];
try astgen.strLitNodeCheckTrailingWhitespace(tok_i, line_bytes);
try string_bytes.ensureUnusedCapacity(gpa, line_bytes.len + 1);
string_bytes.appendAssumeCapacity('\n');
string_bytes.appendSliceAssumeCapacity(line_bytes);
Expand All @@ -11699,6 +11701,20 @@ fn strLitNodeAsString(astgen: *AstGen, node: Ast.Node.Index) !IndexSlice {
};
}

fn strLitNodeCheckTrailingWhitespace(
astgen: *AstGen,
tok: Ast.TokenIndex,
line_bytes: []const u8,
) !void {
if (line_bytes.len == 0) return;
switch (line_bytes[line_bytes.len - 1]) {
'\t', ' ' => {},
'\r', '\n' => unreachable,
else => return,
}
return astgen.failTok(tok, "multiline string cannot contain trailing whitespace", .{});
}

fn testNameString(astgen: *AstGen, str_lit_token: Ast.TokenIndex) !Zir.NullTerminatedString {
const gpa = astgen.gpa;
const string_bytes = &astgen.string_bytes;
Expand Down
24 changes: 12 additions & 12 deletions lib/std/zig/parser_test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5002,8 +5002,8 @@ test "zig fmt: space after top level doc comment" {
}

test "zig fmt: remove trailing whitespace after container doc comment" {
try testTransform(
\\//! top level doc comment
try testTransform("" ++
"//! top level doc comment \n" ++
\\
,
\\//! top level doc comment
Expand All @@ -5012,8 +5012,8 @@ test "zig fmt: remove trailing whitespace after container doc comment" {
}

test "zig fmt: remove trailing whitespace after doc comment" {
try testTransform(
\\/// doc comment
try testTransform("" ++
"/// doc comment \n" ++
\\a = 0,
\\
,
Expand Down Expand Up @@ -6218,8 +6218,8 @@ test "recovery: eof in c pointer" {

test "matching whitespace on minus op" {
try testError(
\\ _ = 2 -1,
\\ _ = 2- 1,
\\ _ = 2 -1,
\\ _ = 2- 1,
\\ _ = 2-
\\ 2,
\\ _ = 2
Expand All @@ -6236,7 +6236,7 @@ test "matching whitespace on minus op" {
\\ _ = -1,
\\ _ = 2 - -1,
\\ _ = 2 - 1,
\\ _ = 2-1,
\\ _ = 2-1,
\\ _ = 2 -
\\1,
\\ _ = 2
Expand All @@ -6247,8 +6247,8 @@ test "matching whitespace on minus op" {
test "ampersand" {
try testError(
\\ _ = bar && foo,
\\ _ = bar&&foo,
\\ _ = bar& & foo,
\\ _ = bar&&foo,
\\ _ = bar& & foo,
\\ _ = bar& &foo,
, &.{
.invalid_ampersand_ampersand,
Expand All @@ -6258,9 +6258,9 @@ test "ampersand" {
});

try testError(
\\ _ = bar & &foo,
\\ _ = bar & &&foo,
\\ _ = &&foo,
\\ _ = bar & &foo,
\\ _ = bar & &&foo,
\\ _ = &&foo,
, &.{});
}

Expand Down
3 changes: 1 addition & 2 deletions src/link/tapi/Tokenizer.zig
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,7 @@ test "mappings" {

test "inline mapped sequence of values" {
try testExpected(
\\key : [ val1,
\\key : [ val1,
\\ val2 ]
, &[_]Token.Id{
.literal,
Expand All @@ -416,7 +416,6 @@ test "inline mapped sequence of values" {
.space,
.literal,
.comma,
.space,
.new_line,
.space,
.literal,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const S =
\\Hello, world
; // ^^^^^ trailing whitespace here
// error
// backend=stage2
// target=native
//
// :2:5: error: multiline string cannot contain trailing whitespace
2 changes: 1 addition & 1 deletion test/compare_output.zig
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void {
\\
\\pub const std_options = .{
\\ .log_level = .debug,
\\
\\
\\ .log_scope_levels = &.{
\\ .{ .scope = .a, .level = .warn },
\\ .{ .scope = .c, .level = .err },
Expand Down
6 changes: 3 additions & 3 deletions test/compile_errors.zig
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ pub fn addCases(ctx: *Cases, b: *std.Build) !void {
\\ );
\\}
, &[_][]const u8{
\\:2:5: error:
\\:2:5: error:
\\ hello!
\\ I'm a multiline error message.
\\ I hope to be very useful!
\\
\\
\\ also I will leave this trailing newline here if you don't mind
\\
\\
});
}

Expand Down
14 changes: 7 additions & 7 deletions test/link/macho.zig
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ fn testHelloC(b: *Build, opts: Options) *Step {

const exe = addExecutable(b, opts, .{ .name = "main", .c_source_bytes =
\\#include <stdio.h>
\\int main() {
\\int main() {
\\ printf("Hello world!\n");
\\ return 0;
\\}
Expand Down Expand Up @@ -932,7 +932,7 @@ fn testMergeLiteralsX64(b: *Build, opts: Options) *Step {
\\ lea L._q1(%rip), %rax
\\ mov (%rax), %xmm0
\\ ret
\\
\\
\\.section __TEXT,__cstring,cstring_literals
\\l._s1:
\\ .asciz "hello"
Expand All @@ -958,7 +958,7 @@ fn testMergeLiteralsX64(b: *Build, opts: Options) *Step {
\\ lea L._q2(%rip), %rax
\\ mov (%rax), %xmm0
\\ ret
\\
\\
\\.section __TEXT,__cstring,cstring_literals
\\l._s2:
\\ .asciz "hello"
Expand Down Expand Up @@ -1048,7 +1048,7 @@ fn testMergeLiteralsArm64(b: *Build, opts: Options) *Step {
\\ adrp x8, L._q1@PAGE
\\ ldr d0, [x8, L._q1@PAGEOFF]
\\ ret
\\
\\
\\.section __TEXT,__cstring,cstring_literals
\\l._s1:
\\ .asciz "hello"
Expand All @@ -1074,7 +1074,7 @@ fn testMergeLiteralsArm64(b: *Build, opts: Options) *Step {
\\ adrp x8, L._q2@PAGE
\\ ldr d0, [x8, L._q2@PAGEOFF]
\\ ret
\\
\\
\\.section __TEXT,__cstring,cstring_literals
\\l._s2:
\\ .asciz "hello"
Expand Down Expand Up @@ -1168,7 +1168,7 @@ fn testMergeLiteralsArm642(b: *Build, opts: Options) *Step {
\\ adrp x0, L._q1@PAGE
\\ ldr x0, [x0, L._q1@PAGEOFF]
\\ ret
\\
\\
\\.section __TEXT,__cstring,cstring_literals
\\_s1:
\\ .asciz "hello"
Expand All @@ -1189,7 +1189,7 @@ fn testMergeLiteralsArm642(b: *Build, opts: Options) *Step {
\\ adrp x0, L._q2@PAGE
\\ ldr x0, [x0, L._q2@PAGEOFF]
\\ ret
\\
\\
\\.section __TEXT,__cstring,cstring_literals
\\_s2:
\\ .asciz "hello"
Expand Down
4 changes: 2 additions & 2 deletions tools/doctest.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1468,10 +1468,10 @@ test "printShell" {
try testing.expectEqualSlices(u8, expected, buffer.items);
}
{
// intentional space after "--build-option1 \"
const shell_out =
\\$ zig build test.zig \
\\ --build-option1 \
\\ --build-option1 \
++ " \n" ++
\\ --build-option2
\\$ ./test
;
Expand Down