diff options
| author | Sahnvour <Sahnvour@users.noreply.github.com> | 2018-11-19 22:22:21 +0100 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2018-11-19 16:22:21 -0500 |
| commit | 703c6684d103f14193411b589eaa0e0b1e1189f0 (patch) | |
| tree | 3c19fddb4174bb5ed104e6dbac573533821956cd /src/ir.cpp | |
| parent | 89e82281be73701f5a634770366e9dca5a0e89a9 (diff) | |
| download | zig-703c6684d103f14193411b589eaa0e0b1e1189f0.tar.gz zig-703c6684d103f14193411b589eaa0e0b1e1189f0.zip | |
Crash fixes and small improvements to inline asm. (#1756)
* codegen: LLVMConstInlineAsm is deprecated.
* codegen: replace commas in asm constraint strings by pipes as required by LLVM.
* ir: enforce usage of '=' constraint modifier for inline assembly outputs.
Others are not currently supported and this was just asserted alter in `ir_render_asm`.
* asm: forbid comptime_int/floats as inputs in favor of explicitely sized constants.
Fixes a crash due to comptime_int/floats having no type_ref.
* asm: handle inputs with integers of <8 or non power of 2 bitsize.
We widen them to the next highest power of two.
Diffstat (limited to 'src/ir.cpp')
| -rw-r--r-- | src/ir.cpp | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 03389a2320..a62da827bc 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -5537,6 +5537,15 @@ static IrInstruction *ir_gen_asm_expr(IrBuilder *irb, Scope *scope, AstNode *nod return irb->codegen->invalid_instruction; } } + + const char modifier = *buf_ptr(asm_output->constraint); + if (modifier != '=') { + add_node_error(irb->codegen, node, + buf_sprintf("invalid modifier starting output constraint for '%s': '%c', only '=' is supported." + " Compiler TODO: see https://github.com/ziglang/zig/issues/215", + buf_ptr(asm_output->asm_symbolic_name), modifier)); + return irb->codegen->invalid_instruction; + } } for (size_t i = 0; i < node->data.asm_expr.input_list.length; i += 1) { AsmInput *asm_input = node->data.asm_expr.input_list.at(i); @@ -15386,9 +15395,19 @@ static IrInstruction *ir_analyze_instruction_asm(IrAnalyze *ira, IrInstructionAs } for (size_t i = 0; i < asm_expr->input_list.length; i += 1) { - input_list[i] = asm_instruction->input_list[i]->child; - if (type_is_invalid(input_list[i]->value.type)) + IrInstruction *const input_value = asm_instruction->input_list[i]->child; + if (type_is_invalid(input_value->value.type)) return ira->codegen->invalid_instruction; + + if (instr_is_comptime(input_value) && + (input_value->value.type->id == ZigTypeIdComptimeInt || + input_value->value.type->id == ZigTypeIdComptimeFloat)) { + ir_add_error_node(ira, input_value->source_node, + buf_sprintf("expected sized integer or sized float, found %s", buf_ptr(&input_value->value.type->name))); + return ira->codegen->invalid_instruction; + } + + input_list[i] = input_value; } IrInstruction *result = ir_build_asm(&ira->new_irb, |
