authorgravatar for timonkruiper@gmail.comTimon Kruiper <timonkruiper@gmail.com> 2019-08-17 14:16:51+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-08-20 14:11:03-04:00
log2addec8ea1f35241e9399c5da6855c427481985f
tree2c291ee59f281db3ef3ab4ba67d0b1de53960f14
parent2aa18b909765a48878d3f30f638e79d6eee1b584
signature Commit is signed but in an unrecognized format.

compiler error when variable in asm template cannot be found


2 files changed, 47 insertions(+), 0 deletions(-)

src/ir.cpp+35
...@@ -6743,6 +6743,25 @@ static Error parse_asm_template(IrBuilder *irb, AstNode *source_node, Buf *asm_t...@@ -6743,6 +6743,25 @@ static Error parse_asm_template(IrBuilder *irb, AstNode *source_node, Buf *asm_t
6743 return ErrorNone;6743 return ErrorNone;
6744}6744}
67456745
6746static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_template) {
6747 const char *ptr = buf_ptr(src_template) + tok->start + 2;
6748 size_t len = tok->end - tok->start - 2;
6749 size_t result = 0;
6750 for (size_t i = 0; i < node->data.asm_expr.output_list.length; i += 1, result += 1) {
6751 AsmOutput *asm_output = node->data.asm_expr.output_list.at(i);
6752 if (buf_eql_mem(asm_output->asm_symbolic_name, ptr, len)) {
6753 return result;
6754 }
6755 }
6756 for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1, result += 1) {
6757 AsmInput *asm_input = node->data.asm_expr.input_list.at(i);
6758 if (buf_eql_mem(asm_input->asm_symbolic_name, ptr, len)) {
6759 return result;
6760 }
6761 }
6762 return SIZE_MAX;
6763}
6764
6746static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *node) {6765static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *node) {
6747 Error err;6766 Error err;
6748 assert(node->type == NodeTypeAsmExpr);6767 assert(node->type == NodeTypeAsmExpr);
...@@ -6830,6 +6849,22 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod...@@ -6830,6 +6849,22 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod
6830 input_list[i] = input_value;6849 input_list[i] = input_value;
6831 }6850 }
68326851
6852 for (size_t token_i = 0; token_i < tok_list.length; token_i += 1) {
6853 AsmToken asm_token = tok_list.at(token_i);
6854 if (asm_token.id == AsmTokenIdVar) {
6855 size_t index = find_asm_index(irb->codegen, node, &asm_token, template_buf);
6856 if (index == SIZE_MAX) {
6857 const char *ptr = buf_ptr(template_buf) + asm_token.start + 2;
6858 uint32_t len = asm_token.end - asm_token.start - 2;
6859
6860 add_node_error(irb->codegen, node,
6861 buf_sprintf("could not find '%.*s' in the inputs or outputs.",
6862 len, ptr));
6863 return irb->codegen->invalid_instruction;
6864 }
6865 }
6866 }
6867
6833 return ir_build_asm(irb, scope, node, template_buf, tok_list.items, tok_list.length,6868 return ir_build_asm(irb, scope, node, template_buf, tok_list.items, tok_list.length,
6834 input_list, output_types, output_vars, return_count, is_volatile);6869 input_list, output_types, output_vars, return_count, is_volatile);
6835}6870}
test/compile_errors.zig+12
...@@ -2,6 +2,18 @@ const tests = @import("tests.zig");...@@ -2,6 +2,18 @@ const tests = @import("tests.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {4pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.add(
6 "variable in inline assembly template cannot be found",
7 \\export fn entry() void {
8 \\ var sp = asm volatile (
9 \\ "mov %[foo], sp"
10 \\ : [bar] "=r" (-> usize)
11 \\ );
12 \\}
13 ,
14 "tmp.zig:2:14: error: could not find 'foo' in the inputs or outputs."
15 );
16
5 cases.add(17 cases.add(
6 "indirect recursion of async functions detected",18 "indirect recursion of async functions detected",
7 \\var frame: ?anyframe = null;19 \\var frame: ?anyframe = null;