diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/codegen.cpp | 4 | ||||
| -rw-r--r-- | src/ir.cpp | 39 |
2 files changed, 42 insertions, 1 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 7ed799611f..e486764db8 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -1677,6 +1677,7 @@ static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstru if (handle_is_ptr(instruction->value->type_entry)) { return value; } else { + assert(instruction->tmp_ptr); LLVMBuildStore(g->builder, value, instruction->tmp_ptr); return instruction->tmp_ptr; } @@ -2843,6 +2844,7 @@ static void do_code_gen(CodeGen *g) { for (size_t alloca_i = 0; alloca_i < fn_table_entry->alloca_list.length; alloca_i += 1) { IrInstruction *instruction = fn_table_entry->alloca_list.at(alloca_i); LLVMValueRef *slot; + TypeTableEntry *slot_type = instruction->type_entry; if (instruction->id == IrInstructionIdCast) { IrInstructionCast *cast_instruction = (IrInstructionCast *)instruction; slot = &cast_instruction->tmp_ptr; @@ -2876,7 +2878,7 @@ static void do_code_gen(CodeGen *g) { } else { zig_unreachable(); } - *slot = LLVMBuildAlloca(g->builder, instruction->type_entry->type_ref, ""); + *slot = LLVMBuildAlloca(g->builder, slot_type->type_ref, ""); } ImportTableEntry *import = get_scope_import(&fn_table_entry->fndef_scope->base); diff --git a/src/ir.cpp b/src/ir.cpp index b2f7f960a8..705a6d0c2f 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -4230,6 +4230,13 @@ static ImplicitCastMatchResult ir_types_match_with_implicit_cast(IrAnalyze *ira, return ImplicitCastMatchResultYes; } + // implicitly take a const pointer to something + { + TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true); + if (types_match_const_cast_only(expected_type, const_ptr_actual)) { + return ImplicitCastMatchResultYes; + } + } return ImplicitCastMatchResultNo; } @@ -4721,6 +4728,30 @@ static IrInstruction *ir_analyze_err_wrap_code(IrAnalyze *ira, IrInstruction *so return result; } +static IrInstruction *ir_analyze_cast_ref(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, TypeTableEntry *wanted_type) { + if (instr_is_comptime(value)) { + ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); + if (!val) + return ira->codegen->invalid_instruction; + + IrInstructionConst *const_instruction = ir_create_instruction<IrInstructionConst>(ira->new_irb.exec, + source_instr->scope, source_instr->source_node); + const_instruction->base.type_entry = wanted_type; + const_instruction->base.static_value.special = ConstValSpecialStatic; + const_instruction->base.static_value.depends_on_compile_var = val->depends_on_compile_var; + const_instruction->base.static_value.data.x_ptr.base_ptr = val; + const_instruction->base.static_value.data.x_ptr.index = SIZE_MAX; + return &const_instruction->base; + } + + if (value->id == IrInstructionIdLoadPtr) { + IrInstructionLoadPtr *load_ptr_inst = (IrInstructionLoadPtr *)value; + return load_ptr_inst->ptr; + } else { + zig_panic("TODO more ways to cast to const pointer"); + } +} + static IrInstruction *ir_analyze_null_to_maybe(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, TypeTableEntry *wanted_type) { assert(wanted_type->id == TypeTableEntryIdMaybe); assert(instr_is_comptime(value)); @@ -4974,6 +5005,14 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst return ir_resolve_cast(ira, source_instr, value, wanted_type, CastOpNoop, false); } + // explicit cast from something to const pointer of it + { + TypeTableEntry *const_ptr_actual = get_pointer_to_type(ira->codegen, actual_type, true); + if (types_match_const_cast_only(wanted_type, const_ptr_actual)) { + return ir_analyze_cast_ref(ira, source_instr, value, wanted_type); + } + } + add_node_error(ira->codegen, source_instr->source_node, buf_sprintf("invalid cast from type '%s' to '%s'", buf_ptr(&actual_type->name), |
