diff --git a/src/AstGen.zig b/src/AstGen.zig index a816628f66928a0db259a2dfe9ecce4f3bd9be5b..e2cdffc014b86ac1e5af36ca77e82115ab9792d9 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -6622,7 +6622,17 @@ fn asmExpr( // See https://github.com/ziglang/zig/issues/215 and related issues discussing // possible inline assembly improvements. Until then here is status quo AstGen // for assembly syntax. It's used by std lib crypto aesni.zig. - + const is_container_asm = astgen.fn_block == null; + if (is_container_asm) { + if (full.volatile_token) |t| + return astgen.failTok(t, "volatile is meaningless on global assembly", .{}); + if (full.outputs.len != 0 or full.inputs.len != 0 or full.first_clobber != null) + return astgen.failNode(node, "global assembly cannot have inputs, outputs, or clobbers", .{}); + } else { + if (full.outputs.len == 0 and full.volatile_token == null) { + return astgen.failNode(node, "assembly expression with no output must be marked volatile", .{}); + } + } if (full.outputs.len > 32) { return astgen.failNode(full.outputs[32], "too many asm outputs", .{}); } diff --git a/test/behavior/syntax.zig b/test/behavior/syntax.zig index 6f75810f3804327b17fd820f8c46d0c31ee641be..c5f9fc70b1d439f55ed2f1618a708b41a973ba76 100644 --- a/test/behavior/syntax.zig +++ b/test/behavior/syntax.zig @@ -60,8 +60,7 @@ fn asm_lists() void { :[a] "x" (x),); asm ("not real assembly" :[a] "x" (->i32),:[a] "x" (1),); - asm ("still not real assembly" + asm volatile ("still not real assembly" :::"a","b",); } } - diff --git a/test/cases.zig b/test/cases.zig index cc0b924bb3b8072f3eb5dc866c34653dba2817f3..37683072a2ba67a866a435483409c90558d7e4fa 100644 --- a/test/cases.zig +++ b/test/cases.zig @@ -1506,6 +1506,39 @@ pub fn addCases(ctx: *TestContext) !void { \\ _ = x; \\} , &[_][]const u8{":4:27: error: expected type, found comptime_int"}); + case.addError( + \\const S = struct { + \\ comptime { + \\ asm volatile ( + \\ \\zig_moment: + \\ \\syscall + \\ ); + \\ } + \\}; + \\pub fn main() void { + \\ _ = S; + \\} + , &.{":3:13: error: volatile is meaningless on global assembly"}); + case.addError( + \\pub fn main() void { + \\ var bruh: u32 = 1; + \\ asm ("" + \\ : + \\ : [bruh] "{rax}" (4) + \\ : "memory" + \\ ); + \\} + , &.{":3:5: error: assembly expression with no output must be marked volatile"}); + case.addError( + \\pub fn main() void {} + \\comptime { + \\ asm ("" + \\ : + \\ : [bruh] "{rax}" (4) + \\ : "memory" + \\ ); + \\} + , &.{":3:5: error: global assembly cannot have inputs, outputs, or clobbers"}); } { var case = ctx.exe("comptime var", linux_x64);