Skip to content

Commit d686113

Browse files
committedDec 20, 2017
fix crash when implicitly casting array of len 0 to slice
closes #660
·
0.15.20.2.0
1 parent 1cc450e commit d686113

File tree

3 files changed

+31
-8
lines changed

3 files changed

+31
-8
lines changed
 

‎src/codegen.cpp‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2722,6 +2722,9 @@ static LLVMValueRef ir_render_phi(CodeGen *g, IrExecutable *executable, IrInstru
27222722
}
27232723

27242724
static LLVMValueRef ir_render_ref(CodeGen *g, IrExecutable *executable, IrInstructionRef *instruction) {
2725+
if (!type_has_bits(instruction->base.value.type)) {
2726+
return nullptr;
2727+
}
27252728
LLVMValueRef value = ir_llvm_value(g, instruction->value);
27262729
if (handle_is_ptr(instruction->value->value.type)) {
27272730
return value;
@@ -3013,6 +3016,15 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
30133016
add_bounds_check(g, end_val, LLVMIntEQ, nullptr, LLVMIntULE, array_end);
30143017
}
30153018
}
3019+
if (!type_has_bits(array_type)) {
3020+
LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");
3021+
3022+
// TODO if debug safety is on, store 0xaaaaaaa in ptr field
3023+
LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");
3024+
gen_store_untyped(g, len_value, len_field_ptr, 0, false);
3025+
return tmp_struct_ptr;
3026+
}
3027+
30163028

30173029
LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_ptr_index, "");
30183030
LLVMValueRef indices[] = {

‎src/ir.cpp‎

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7748,8 +7748,9 @@ static TypeTableEntry *ir_resolve_peer_types(IrAnalyze *ira, AstNode *source_nod
77487748
static void ir_add_alloca(IrAnalyze *ira, IrInstruction *instruction, TypeTableEntry *type_entry) {
77497749
if (type_has_bits(type_entry) && handle_is_ptr(type_entry)) {
77507750
FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
7751-
assert(fn_entry);
7752-
fn_entry->alloca_list.append(instruction);
7751+
if (fn_entry != nullptr) {
7752+
fn_entry->alloca_list.append(instruction);
7753+
}
77537754
}
77547755
}
77557756

@@ -7851,9 +7852,7 @@ static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_inst
78517852
IrInstruction *result = ir_build_cast(&ira->new_irb, source_instr->scope, source_instr->source_node, wanted_type, value, cast_op);
78527853
result->value.type = wanted_type;
78537854
if (need_alloca) {
7854-
FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
7855-
if (fn_entry)
7856-
fn_entry->alloca_list.append(result);
7855+
ir_add_alloca(ira, result, wanted_type);
78577856
}
78587857
return result;
78597858
}
@@ -8287,6 +8286,7 @@ static IrInstruction *ir_analyze_cast_ref(IrAnalyze *ira, IrInstruction *source_
82878286
assert(fn_entry);
82888287
fn_entry->alloca_list.append(new_instruction);
82898288
}
8289+
ir_add_alloca(ira, new_instruction, child_type);
82908290
return new_instruction;
82918291
}
82928292
}
@@ -8330,13 +8330,15 @@ static IrInstruction *ir_get_ref(IrAnalyze *ira, IrInstruction *source_instructi
83308330

83318331
TypeTableEntry *ptr_type = get_pointer_to_type_extra(ira->codegen, value->value.type,
83328332
is_const, is_volatile, get_abi_alignment(ira->codegen, value->value.type), 0, 0);
8333-
FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
8334-
assert(fn_entry);
83358333
IrInstruction *new_instruction = ir_build_ref(&ira->new_irb, source_instruction->scope,
83368334
source_instruction->source_node, value, is_const, is_volatile);
83378335
new_instruction->value.type = ptr_type;
83388336
new_instruction->value.data.rh_ptr = RuntimeHintPtrStack;
8339-
fn_entry->alloca_list.append(new_instruction);
8337+
if (type_has_bits(ptr_type)) {
8338+
FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
8339+
assert(fn_entry);
8340+
fn_entry->alloca_list.append(new_instruction);
8341+
}
83408342
return new_instruction;
83418343
}
83428344

‎test/cases/slice.zig‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,12 @@ test "debug safety lets us slice from len..len" {
2525
fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) -> []u8 {
2626
return a_slice[start..end];
2727
}
28+
29+
test "implicitly cast array of size 0 to slice" {
30+
var msg = []u8 {};
31+
assertLenIsZero(msg);
32+
}
33+
34+
fn assertLenIsZero(msg: []const u8) {
35+
assert(msg.len == 0);
36+
}

0 commit comments

Comments
 (0)
Please sign in to comment.