authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-15 21:17:39+01:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-02-16 19:53:53+01:00
log096f79260b025ab53d77c4943f237676abb5b7d8
tree448091adf4f32044febeceeec4f694313fbb8811
parentb15958c557d3b29c8d4cee9951a8bfd30c215482

ir: Prevent crash when indexing undefined ptr to array

Closes #4471

2 files changed, 35 insertions(+), 18 deletions(-)

src/ir.cpp+26-18
......@@ -20638,12 +20638,12 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
2063820638 if (type_is_invalid(array_ptr->value->type))
2063920639 return ira->codegen->invalid_inst_gen;
2064020640
20641 ZigValue *orig_array_ptr_val = array_ptr->value;
20642
2064320641 IrInstGen *elem_index = elem_ptr_instruction->elem_index->child;
2064420642 if (type_is_invalid(elem_index->value->type))
2064520643 return ira->codegen->invalid_inst_gen;
2064620644
20645 ZigValue *orig_array_ptr_val = array_ptr->value;
20646
2064720647 ZigType *ptr_type = orig_array_ptr_val->type;
2064820648 assert(ptr_type->id == ZigTypeIdPointer);
2064920649
......@@ -20653,23 +20653,25 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
2065320653 // We will adjust return_type's alignment before returning it.
2065420654 ZigType *return_type;
2065520655
20656 if (type_is_invalid(array_type)) {
20656 if (type_is_invalid(array_type))
2065720657 return ira->codegen->invalid_inst_gen;
20658 } else if (array_type->id == ZigTypeIdArray ||
20659 (array_type->id == ZigTypeIdPointer &&
20660 array_type->data.pointer.ptr_len == PtrLenSingle &&
20661 array_type->data.pointer.child_type->id == ZigTypeIdArray))
20658
20659 if (array_type->id == ZigTypeIdPointer &&
20660 array_type->data.pointer.ptr_len == PtrLenSingle &&
20661 array_type->data.pointer.child_type->id == ZigTypeIdArray)
2066220662 {
20663 if (array_type->id == ZigTypeIdPointer) {
20664 array_type = array_type->data.pointer.child_type;
20665 ptr_type = ptr_type->data.pointer.child_type;
20666 if (orig_array_ptr_val->special != ConstValSpecialRuntime) {
20667 orig_array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val,
20668 elem_ptr_instruction->base.base.source_node);
20669 if (orig_array_ptr_val == nullptr)
20670 return ira->codegen->invalid_inst_gen;
20671 }
20672 }
20663 IrInstGen *ptr_value = ir_get_deref(ira, &elem_ptr_instruction->base.base,
20664 array_ptr, nullptr);
20665 if (type_is_invalid(ptr_value->value->type))
20666 return ira->codegen->invalid_inst_gen;
20667
20668 array_type = array_type->data.pointer.child_type;
20669 ptr_type = ptr_type->data.pointer.child_type;
20670
20671 orig_array_ptr_val = ptr_value->value;
20672 }
20673
20674 if (array_type->id == ZigTypeIdArray) {
2067320675 if (array_type->data.array.len == 0) {
2067420676 ir_add_error_node(ira, elem_ptr_instruction->base.base.source_node,
2067520677 buf_sprintf("index 0 outside array of size 0"));
......@@ -20807,8 +20809,14 @@ static IrInstGen *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstSrcElemP
2080720809 orig_array_ptr_val->data.x_ptr.special != ConstPtrSpecialHardCodedAddr &&
2080820810 (orig_array_ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar || array_type->id == ZigTypeIdArray))
2080920811 {
20812 if ((err = ir_resolve_const_val(ira->codegen, ira->new_irb.exec,
20813 elem_ptr_instruction->base.base.source_node, orig_array_ptr_val, UndefBad)))
20814 {
20815 return ira->codegen->invalid_inst_gen;
20816 }
20817
2081020818 ZigValue *array_ptr_val = const_ptr_pointee(ira, ira->codegen, orig_array_ptr_val,
20811 elem_ptr_instruction->base.base.source_node);
20819 elem_ptr_instruction->base.base.source_node);
2081220820 if (array_ptr_val == nullptr)
2081320821 return ira->codegen->invalid_inst_gen;
2081420822
test/compile_errors.zig+9
......@@ -3,6 +3,15 @@ const builtin = @import("builtin");
33const Target = @import("std").Target;
44
55pub fn addCases(cases: *tests.CompileErrorContext) void {
6 cases.addTest("access of undefined pointer to array",
7 \\const ram_u32: *[4096]u32 = undefined;
8 \\export fn entry() void {
9 \\ @ptrCast(*u32, &(ram_u32[0])) = &(ram_u32[0]);
10 \\}
11 , &[_][]const u8{
12 "tmp.zig:3:29: error: use of undefined value here causes undefined behavior",
13 });
14
615 cases.addTest("duplicate field in anonymous struct literal",
716 \\export fn entry() void {
817 \\ const anon = .{