| author | |
| committer | |
| log | 23837094312763ffe6e598df80fdc2ef63f73ab5 |
| tree | e7a96a114864fd2ecdba938b23579a88129227b0 |
| parent | 43d5bea7af8933723a457da45714b144d95e2c70 |
3 files changed, 22 insertions(+), 3 deletions(-)
src/Sema.zig+7-3| ... | @@ -15649,11 +15649,15 @@ fn zirAsm( | ... | @@ -15649,11 +15649,15 @@ fn zirAsm( |
| 15649 | inputs[arg_i] = .{ .c = constraint, .n = name }; | 15649 | inputs[arg_i] = .{ .c = constraint, .n = name }; |
| 15650 | } | 15650 | } |
| 15651 | 15651 | ||
| 15652 | const clobbers_src = block.src(.{ .asm_clobbers = src.offset.node_offset.x }); | ||
| 15653 | const clobbers_ty = try sema.getBuiltinType(src, .@"assembly.Clobbers"); | ||
| 15652 | const clobbers = if (extra.data.clobbers == .none) empty: { | 15654 | const clobbers = if (extra.data.clobbers == .none) empty: { |
| 15653 | const clobbers_ty = try sema.getBuiltinType(src, .@"assembly.Clobbers"); | ||
| 15654 | break :empty try sema.structInitEmpty(block, clobbers_ty, src, src); | 15655 | break :empty try sema.structInitEmpty(block, clobbers_ty, src, src); |
| 15655 | } else sema.resolveInst(extra.data.clobbers); // Already coerced by AstGen. | 15656 | } else clobbers: { |
| 15656 | const clobbers_val = try sema.resolveConstDefinedValue(block, src, clobbers, .{ .simple = .clobber }); | 15657 | const uncoerced = sema.resolveInst(extra.data.clobbers); |
| 15658 | break :clobbers try sema.coerce(block, clobbers_ty, uncoerced, clobbers_src); | ||
| 15659 | }; | ||
| 15660 | const clobbers_val = try sema.resolveConstDefinedValue(block, clobbers_src, clobbers, .{ .simple = .clobber }); | ||
| 15657 | needed_capacity += asm_source.len / 4 + 1; | 15661 | needed_capacity += asm_source.len / 4 + 1; |
| 15658 | 15662 | ||
| 15659 | try sema.air_extra.ensureUnusedCapacity(gpa, needed_capacity); | 15663 | try sema.air_extra.ensureUnusedCapacity(gpa, needed_capacity); |
src/Zcu.zig+8| ... | @@ -1602,6 +1602,12 @@ pub const SrcLoc = struct { | ... | @@ -1602,6 +1602,12 @@ pub const SrcLoc = struct { |
| 1602 | // token points to the ')' | 1602 | // token points to the ')' |
| 1603 | tree.tokenToSpan(data[1] - 1); | 1603 | tree.tokenToSpan(data[1] - 1); |
| 1604 | }, | 1604 | }, |
| 1605 | .asm_clobbers => |offset| { | ||
| 1606 | const tree = try src_loc.file_scope.getTree(zcu); | ||
| 1607 | const node = offset.toAbsolute(src_loc.base_node); | ||
| 1608 | const full = tree.fullAsm(node).?; | ||
| 1609 | return tree.nodeToSpan(full.ast.clobbers.unwrap().?); // this should only be reachable if the clobbers are written in the source | ||
| 1610 | }, | ||
| 1605 | .for_input => |for_input| { | 1611 | .for_input => |for_input| { |
| 1606 | const tree = try src_loc.file_scope.getTree(zcu); | 1612 | const tree = try src_loc.file_scope.getTree(zcu); |
| 1607 | const node = for_input.for_node_offset.toAbsolute(src_loc.base_node); | 1613 | const node = for_input.for_node_offset.toAbsolute(src_loc.base_node); |
| ... | @@ -2552,6 +2558,8 @@ pub const LazySrcLoc = struct { | ... | @@ -2552,6 +2558,8 @@ pub const LazySrcLoc = struct { |
| 2552 | offset: Ast.Node.Offset, | 2558 | offset: Ast.Node.Offset, |
| 2553 | output_index: u32, | 2559 | output_index: u32, |
| 2554 | }, | 2560 | }, |
| 2561 | /// Points to the assembly node | ||
| 2562 | asm_clobbers: Ast.Node.Offset, | ||
| 2555 | /// The source location points to a for loop input. | 2563 | /// The source location points to a for loop input. |
| 2556 | for_input: struct { | 2564 | for_input: struct { |
| 2557 | /// Points to the for loop AST node. | 2565 | /// Points to the for loop AST node. |
test/cases/compile_errors/undefined_assembly_clobbers.zig created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | export fn foo() void { | ||
| 2 | asm volatile("" ::: undefined); | ||
| 3 | } | ||
| 4 | |||
| 5 | // error | ||
| 6 | // | ||
| 7 | // :2:25: error: use of undefined value here causes illegal behavior | ||