commit 23837094312763ffe6e598df80fdc2ef63f73ab5 (tree)
parent 43d5bea7af8933723a457da45714b144d95e2c70
Author: pentuppup <pentuppup@noreply.codeberg.org>
Date: Tue, 17 Feb 2026 13:38:00 -0500
coerce assembly clobbers in sema
Diffstat:
3 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/src/Sema.zig b/src/Sema.zig
@@ -15649,11 +15649,15 @@ fn zirAsm(
inputs[arg_i] = .{ .c = constraint, .n = name };
}
+ const clobbers_src = block.src(.{ .asm_clobbers = src.offset.node_offset.x });
+ const clobbers_ty = try sema.getBuiltinType(src, .@"assembly.Clobbers");
const clobbers = if (extra.data.clobbers == .none) empty: {
- const clobbers_ty = try sema.getBuiltinType(src, .@"assembly.Clobbers");
break :empty try sema.structInitEmpty(block, clobbers_ty, src, src);
- } else sema.resolveInst(extra.data.clobbers); // Already coerced by AstGen.
- const clobbers_val = try sema.resolveConstDefinedValue(block, src, clobbers, .{ .simple = .clobber });
+ } else clobbers: {
+ const uncoerced = sema.resolveInst(extra.data.clobbers);
+ break :clobbers try sema.coerce(block, clobbers_ty, uncoerced, clobbers_src);
+ };
+ const clobbers_val = try sema.resolveConstDefinedValue(block, clobbers_src, clobbers, .{ .simple = .clobber });
needed_capacity += asm_source.len / 4 + 1;
try sema.air_extra.ensureUnusedCapacity(gpa, needed_capacity);
diff --git a/src/Zcu.zig b/src/Zcu.zig
@@ -1602,6 +1602,12 @@ pub const SrcLoc = struct {
// token points to the ')'
tree.tokenToSpan(data[1] - 1);
},
+ .asm_clobbers => |offset| {
+ const tree = try src_loc.file_scope.getTree(zcu);
+ const node = offset.toAbsolute(src_loc.base_node);
+ const full = tree.fullAsm(node).?;
+ return tree.nodeToSpan(full.ast.clobbers.unwrap().?); // this should only be reachable if the clobbers are written in the source
+ },
.for_input => |for_input| {
const tree = try src_loc.file_scope.getTree(zcu);
const node = for_input.for_node_offset.toAbsolute(src_loc.base_node);
@@ -2552,6 +2558,8 @@ pub const LazySrcLoc = struct {
offset: Ast.Node.Offset,
output_index: u32,
},
+ /// Points to the assembly node
+ asm_clobbers: Ast.Node.Offset,
/// The source location points to a for loop input.
for_input: struct {
/// Points to the for loop AST node.
diff --git a/test/cases/compile_errors/undefined_assembly_clobbers.zig b/test/cases/compile_errors/undefined_assembly_clobbers.zig
@@ -0,0 +1,7 @@
+export fn foo() void {
+ asm volatile("" ::: undefined);
+}
+
+// error
+//
+// :2:25: error: use of undefined value here causes illegal behavior